Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embed GLSL files during build #238

Merged
merged 7 commits into from
Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions cmake/EmbedResource.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# EmbedResource.cmake

####################################################################################################
# original function by amir-saniyan https://gist.github.com/amir-saniyan/de99cee82fa9d8d615bb69f3f53b6004
function(embed_resource resource_file_name source_file_name variable_name)

if(EXISTS "${source_file_name}")
if("${source_file_name}" IS_NEWER_THAN "${resource_file_name}")
return()
endif()
endif()

file(READ "${resource_file_name}" hex_content HEX)

string(REPEAT "[0-9a-f]" 32 pattern)
string(REGEX REPLACE "(${pattern})" "\\1\n" content "${hex_content}")
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " content "${content}")
string(REGEX REPLACE ", $" "" content "${content}")
set(array_definition "static const char ${variable_name}[] =\n{\n${content}\n};")
set(source "// Auto generated file.\n${array_definition}\n")
file(WRITE "${source_file_name}" "${source}")

endfunction()
####################################################################################################


if(NOT DEFINED SOURCE_DIR)
message(FATAL_ERROR "SOURCE_DIR is not set")
endif(NOT DEFINED SOURCE_DIR)

if(NOT DEFINED FILE)
message(FATAL_ERROR "FILE is not set")
endif(NOT DEFINED FILE)

string(REPLACE "." "_" generated_name "${FILE}")
string(REPLACE "/" "_" generated_name "${generated_name}")
string(TOUPPER "${generated_name}" generated_name)
embed_resource("${SOURCE_DIR}/${FILE}" "${FILE}.h" "${generated_name}")
24 changes: 18 additions & 6 deletions src/harness/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ if (NOT DEFINED IO_PLATFORM)
set(IO_PLATFORM "SDL_OpenGL")
endif()

target_include_directories(harness
target_include_directories(harness
PRIVATE
.
${CMAKE_SOURCE_DIR}
Expand Down Expand Up @@ -61,14 +61,26 @@ target_sources(harness PRIVATE
)

if (IO_PLATFORM STREQUAL "SDL_OpenGL")
# generate embedded glsl resources
foreach(elem resources/framebuffer_vert.glsl resources/framebuffer_frag.glsl resources/3d_vert.glsl resources/3d_frag.glsl)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${elem}.h"
COMMAND "${CMAKE_COMMAND}" "-DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}" "-DFILE=${elem}" -P "${dethrace_SOURCE_DIR}/cmake/EmbedResource.cmake"
DEPENDS "${elem}"
)
endforeach()

target_sources(harness PRIVATE
io_platforms/sdl_gl.c
renderers/gl/gl_renderer.c
renderers/gl/gl_renderer.h
renderers/gl/shaders.c
renderers/gl/shaders.h
renderers/gl/stored_context.c
renderers/gl/stored_context.h

resources/framebuffer_vert.glsl.h
resources/framebuffer_frag.glsl.h
resources/3d_vert.glsl.h
resources/3d_frag.glsl.h
)
target_link_libraries(harness PRIVATE SDL2::SDL2 glad)
endif()
Expand All @@ -78,9 +90,9 @@ if(WIN32)
os/windows.c
)
elseif(APPLE)
target_sources(harness PRIVATE
os/macos.c
)
target_sources(harness PRIVATE
os/macos.c
)
else()
target_sources(harness PRIVATE
os/linux.c
Expand Down
14 changes: 7 additions & 7 deletions src/harness/harness.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,19 @@ void Harness_DetectGameMode() {
harness_game_info.defines.INTRO_SMK_FILE = "SPLINTRO.SMK";
harness_game_info.defines.GERMAN_LOADSCRN = "LOADSCRN.PIX";
harness_game_info.mode = eGame_splatpack;
LOG_INFO("\"%s\"", "Splat Pack");
printf("Game mode: Splat Pack\n");
} else if (access("DATA/RACES/TINSEL.TXT", F_OK) != -1) {
// Only the the splat x-mas demo has the tinsel track
harness_game_info.defines.INTRO_SMK_FILE = "";
harness_game_info.defines.GERMAN_LOADSCRN = "";
harness_game_info.mode = eGame_splatpack_demo;
LOG_INFO("\"%s\"", "Splat Pack X-mas demo");
printf("Game mode: Splat Pack X-mas demo\n");
} else {
// Assume we're using the splatpack demo
harness_game_info.defines.INTRO_SMK_FILE = "";
harness_game_info.defines.GERMAN_LOADSCRN = "";
harness_game_info.mode = eGame_splatpack_demo;
LOG_INFO("\"%s\"", "Splat Pack demo");
printf("Game mode: Splat Pack demo\n");
}
} else if (access("DATA/RACES/CITYB3.TXT", F_OK) != -1) {
// All non-splatpack edition have the cityb3 track
Expand All @@ -111,7 +111,7 @@ void Harness_DetectGameMode() {
harness_game_info.defines.INTRO_SMK_FILE = "";
harness_game_info.defines.GERMAN_LOADSCRN = "COWLESS.PIX";
harness_game_info.mode = eGame_carmageddon_demo;
LOG_INFO("\"%s\"", "Carmageddon demo");
printf("Game mode: Carmageddon demo\n");
} else {
goto carmageddon;
}
Expand All @@ -124,7 +124,7 @@ void Harness_DetectGameMode() {
}
harness_game_info.defines.GERMAN_LOADSCRN = "LOADSCRN.PIX";
harness_game_info.mode = eGame_carmageddon;
LOG_INFO("\"%s\"", "Carmageddon");
printf("Game mode: Carmageddon\n");
}

harness_game_info.localization = eGameLocalization_none;
Expand Down Expand Up @@ -176,7 +176,7 @@ void Harness_DetectGameMode() {
void Harness_Init(int* argc, char* argv[]) {
int result;

LOG_INFO("version: " DETHRACE_VERSION);
printf("Dethrace version: %s\n", DETHRACE_VERSION);

// disable the original CD check code
harness_game_config.enable_cd_check = 0;
Expand Down Expand Up @@ -206,7 +206,7 @@ void Harness_Init(int* argc, char* argv[]) {
if (root_dir == NULL) {
LOG_INFO("DETHRACE_ROOT_DIR is not set, assuming '.'");
} else {
printf("DETHRACE_ROOT_DIR: %s\n", root_dir);
printf("Data directory: %s\n", root_dir);
result = chdir(root_dir);
if (result != 0) {
LOG_PANIC("Failed to chdir. Error is %s", strerror(errno));
Expand Down
114 changes: 52 additions & 62 deletions src/harness/renderers/gl/gl_renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#include "brender/brender.h"
#include "harness.h"
#include "harness/trace.h"
#include "shaders.h"
#include "resources/3d_frag.glsl.h"
#include "resources/3d_vert.glsl.h"
#include "resources/framebuffer_frag.glsl.h"
#include "resources/framebuffer_vert.glsl.h"
#include "stored_context.h"

#include <glad/glad.h>
Expand All @@ -29,7 +32,7 @@ static br_pixelmap* last_shade_table = NULL;
static int dirty_buffers = 0;

struct {
GLuint pixels, pixels_transform;
GLuint pixels, uv_transform;
GLuint shade_table;
GLuint model, view, projection;
GLuint palette_index_override;
Expand All @@ -46,92 +49,84 @@ struct {
GLuint pixels, palette;
} uniforms_2dpp;

GLuint CreateShaderFromFile(const char* filename, const char* fallback, GLenum type) {
GLuint CreateShaderProgram(char* name, const char* vertex_shader, const int vertex_shader_len, const char* fragment_shader, const int fragment_shader_len) {
int success;
char log_buffer[1024];
GLuint program;
GLuint v_shader, f_shader;

GLuint res = glCreateShader(type);

FILE* f = fopen(filename, "r");
if (f) {
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
char* file_bytes = malloc(fsize + 1);
fsize = fread(file_bytes, fsize, 1, f);
fclose(f);
file_bytes[fsize] = 0;
const GLchar* sources[] = { file_bytes };
glShaderSource(res, 1, sources, NULL);
} else {
const GLchar* sources[] = { fallback };
glShaderSource(res, 1, sources, NULL);
program = glCreateProgram();
v_shader = glCreateShader(GL_VERTEX_SHADER);
const GLchar* vertex_sources[] = { vertex_shader };
glShaderSource(v_shader, 1, vertex_sources, &vertex_shader_len);
glCompileShader(v_shader);
glGetShaderiv(v_shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(v_shader, 1024, NULL, log_buffer);
LOG_PANIC("shader %s failed to compile: %s", name, log_buffer);
}

glCompileShader(res);
glGetShaderiv(res, GL_COMPILE_STATUS, &success);
f_shader = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* fragment_sources[] = { fragment_shader };
glShaderSource(f_shader, 1, fragment_sources, &fragment_shader_len);
glCompileShader(f_shader);
glGetShaderiv(f_shader, GL_COMPILE_STATUS, &success);
if (!success) {
char log_buffer[1024];
glGetShaderInfoLog(res, 1024, NULL, log_buffer);
LOG_PANIC("shader %s failed to compile: %s", filename, log_buffer);
glGetShaderInfoLog(f_shader, 1024, NULL, log_buffer);
LOG_PANIC("shader %s failed to compile: %s", name, log_buffer);
}
return res;
}

GLuint CreateShaderProgram(const char* vertex_file, const char* fragment_file, const char* vertex_fallback, const char* fragment_fallback) {
GLuint program = glCreateProgram();
GLuint v_shader, f_shader;

v_shader = CreateShaderFromFile(vertex_file, vertex_fallback, GL_VERTEX_SHADER);
if (!v_shader)
return 0;
glAttachShader(program, v_shader);

f_shader = CreateShaderFromFile(fragment_file, fragment_fallback, GL_FRAGMENT_SHADER);
if (!f_shader)
return 0;
glAttachShader(program, f_shader);

glLinkProgram(program);

glDeleteShader(v_shader);
glDeleteShader(f_shader);

GLint link_ok = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if (!link_ok) {
char log_buffer[1024];
glGetShaderInfoLog(program, 1024, NULL, log_buffer);
LOG_PANIC("shader program %s:%s failed to link: %s", vertex_file, fragment_file, log_buffer);
LOG_PANIC("shader program %s failed to link: %s", name, log_buffer);
}
return program;
}

GLint GetValidatedUniformLocation(GLuint program, char* uniform_name) {
GLint location;
location = glGetUniformLocation(program, uniform_name);
if (location == -1) {
LOG_PANIC("glGetUniformLocation(%d, %s) failed. Check the shader uniform names.", program, uniform_name);
}
return location;
}

void LoadShaders() {
shader_program_2d = CreateShaderProgram("vertex_shader_2d.glsl", "fragment_shader_2d.glsl", vs_2d, fs_2d);
shader_program_2d = CreateShaderProgram("framebuffer", RESOURCES_FRAMEBUFFER_VERT_GLSL, sizeof(RESOURCES_FRAMEBUFFER_VERT_GLSL), RESOURCES_FRAMEBUFFER_FRAG_GLSL, sizeof(RESOURCES_FRAMEBUFFER_FRAG_GLSL));
glUseProgram(shader_program_2d);
uniforms_2d.pixels = glGetUniformLocation(shader_program_2d, "pixels");
uniforms_2d.palette = glGetUniformLocation(shader_program_2d, "palette");
uniforms_2d.pixels = GetValidatedUniformLocation(shader_program_2d, "u_pixels");
uniforms_2d.palette = GetValidatedUniformLocation(shader_program_2d, "u_palette");

// bind the uniform samplers to texture units:
glUniform1i(uniforms_2d.pixels, 0);
glUniform1i(uniforms_2d.palette, 1);

shader_program_3d = CreateShaderProgram("vertex_shader_3d.glsl", "fragment_shader_3d.glsl", vs_3d, fs_3d);
shader_program_3d = CreateShaderProgram("3d", RESOURCES_3D_VERT_GLSL, sizeof(RESOURCES_3D_VERT_GLSL), RESOURCES_3D_FRAG_GLSL, sizeof(RESOURCES_3D_FRAG_GLSL));
glUseProgram(shader_program_3d);
uniforms_3d.clip_plane_count = glGetUniformLocation(shader_program_3d, "clip_plane_count");
uniforms_3d.clip_plane_count = GetValidatedUniformLocation(shader_program_3d, "u_clip_plane_count");
for (int i = 0; i < 6; i++) {
char name[32];
sprintf(name, "clip_planes[%d]", i);
uniforms_3d.clip_planes[i] = glGetUniformLocation(shader_program_3d, name);
sprintf(name, "u_clip_planes[%d]", i);
uniforms_3d.clip_planes[i] = GetValidatedUniformLocation(shader_program_3d, name);
}
uniforms_3d.model = glGetUniformLocation(shader_program_3d, "model");
uniforms_3d.pixels = glGetUniformLocation(shader_program_3d, "pixels");
uniforms_3d.pixels_transform = glGetUniformLocation(shader_program_3d, "pixels_transform");
uniforms_3d.shade_table = glGetUniformLocation(shader_program_3d, "shade_table");
uniforms_3d.projection = glGetUniformLocation(shader_program_3d, "projection");
uniforms_3d.palette_index_override = glGetUniformLocation(shader_program_3d, "palette_index_override");
uniforms_3d.view = glGetUniformLocation(shader_program_3d, "view");
uniforms_3d.light_value = glGetUniformLocation(shader_program_3d, "light_value");
uniforms_3d.model = GetValidatedUniformLocation(shader_program_3d, "u_model");
uniforms_3d.pixels = GetValidatedUniformLocation(shader_program_3d, "u_pixels");
uniforms_3d.uv_transform = GetValidatedUniformLocation(shader_program_3d, "u_texture_coords_transform");
uniforms_3d.shade_table = GetValidatedUniformLocation(shader_program_3d, "u_shade_table");
uniforms_3d.projection = GetValidatedUniformLocation(shader_program_3d, "u_projection");
uniforms_3d.palette_index_override = GetValidatedUniformLocation(shader_program_3d, "u_palette_index_override");
uniforms_3d.view = GetValidatedUniformLocation(shader_program_3d, "u_view");
uniforms_3d.light_value = GetValidatedUniformLocation(shader_program_3d, "u_light_value");

// bind the uniform samplers to texture units. palette=1, shadetable=2
glUniform1i(uniforms_3d.pixels, 0);
Expand Down Expand Up @@ -492,7 +487,7 @@ void setActiveMaterial(tStored_material* material) {
return;
}

glUniform3fv(uniforms_3d.pixels_transform, 2, material->map_transform->v);
glUniformMatrix2x3fv(uniforms_3d.uv_transform, 1, GL_TRUE, &material->map_transform.m[0][0]);
glUniform1i(uniforms_3d.palette_index_override, material->index_base);
if (material->shade_table) {
GLRenderer_SetShadeTable(material->shade_table);
Expand Down Expand Up @@ -578,12 +573,7 @@ void GLRenderer_BufferMaterial(br_material* mat) {
strcpy(stored->identifier, mat->identifier);
}
}
stored->map_transform[0].v[0] = mat->map_transform.m[0][0];
stored->map_transform[0].v[1] = mat->map_transform.m[0][1];
stored->map_transform[0].v[2] = mat->map_transform.m[2][0];
stored->map_transform[1].v[0] = mat->map_transform.m[1][0];
stored->map_transform[1].v[1] = mat->map_transform.m[1][1];
stored->map_transform[1].v[2] = mat->map_transform.m[2][1];
BrMatrix23Copy(&stored->map_transform, &mat->map_transform);
stored->pixelmap = mat->colour_map;
stored->flags = mat->flags;
stored->shade_table = mat->index_shade;
Expand Down
Loading