From 52fe471ff2839b80fe16d33f7a9a396c9ac795b8 Mon Sep 17 00:00:00 2001 From: Dethrace Labs <78985374+dethrace-labs@users.noreply.github.com> Date: Thu, 14 Dec 2023 16:14:43 +1300 Subject: [PATCH] wip --- src/harness/CMakeLists.txt | 36 ++++--- src/harness/platforms/sdl_opengl.c | 29 +++--- src/harness/renderers/gl/gl_renderer.c | 100 +++++++++++++------- src/harness/renderers/gl/gl_renderer.h | 7 +- src/harness/resources/3d_frag.glsl | 12 +-- src/harness/resources/3d_vert.glsl | 5 - src/harness/resources/framebuffer_frag.glsl | 7 -- src/harness/resources/framebuffer_vert.glsl | 7 -- src/harness/resources/glcore_header.glsl | 2 + src/harness/resources/gles_header.glsl | 5 + 10 files changed, 126 insertions(+), 84 deletions(-) create mode 100644 src/harness/resources/glcore_header.glsl create mode 100644 src/harness/resources/gles_header.glsl diff --git a/src/harness/CMakeLists.txt b/src/harness/CMakeLists.txt index 13f08467..c002111a 100644 --- a/src/harness/CMakeLists.txt +++ b/src/harness/CMakeLists.txt @@ -72,13 +72,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() + + file(GLOB glsl_resource_files "resources/*.glsl") + message(${glsl_resource_files}) + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embedded_resources.h" + COMMAND "${CMAKE_COMMAND}" "-DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}" "-DRESOURCES_GLOB=resources/*.glsl" -P "${CMAKE_SOURCE_DIR}/cmake/EmbedResources.cmake" + DEPENDS ${glsl_resource_files} + ) + # cd /Users/j.harris/code/dethrace/build/src/harness && + # /opt/homebrew/Cellar/cmake/3.26.3/bin/cmake -DSOURCE_DIR=/Users/j.harris/code/dethrace -DRESOURCES_GLOB=resources/*.glsl -P /Users/j.harris/code/dethrace/src/harness/cmake/EmbedResources.cmake + + # 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() + # cd /Users/j.harris/code/dethrace/build/src/harness && + # /opt/homebrew/Cellar/cmake/3.26.3/bin/cmake -DSOURCE_DIR=/Users/j.harris/code/dethrace/src/harness -DFILE=resources/3d_frag.glsl -P /Users/j.harris/code/dethrace/cmake/EmbedResource.cmake target_sources(harness PRIVATE platforms/sdl_opengl.c @@ -88,10 +101,11 @@ if (IO_PLATFORM STREQUAL "SDL_OpenGL") 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 + # resources/framebuffer_vert.glsl.h + # resources/framebuffer_frag.glsl.h + # resources/3d_vert.glsl.h + # resources/3d_frag.glsl.h + embedded_resources.h ) target_include_directories(harness PRIVATE "${dethrace_SOURCE_DIR}/src/DETHRACE/common") target_link_libraries(harness PRIVATE SDL2::SDL2 glad) diff --git a/src/harness/platforms/sdl_opengl.c b/src/harness/platforms/sdl_opengl.c index b3d1f600..569b2439 100644 --- a/src/harness/platforms/sdl_opengl.c +++ b/src/harness/platforms/sdl_opengl.c @@ -49,25 +49,30 @@ static void* create_window_and_renderer(char* title, int x, int y, int width, in window_height = height; render_width = width; render_height = height; + tOpenGL_profile opengl_profile; if (SDL_Init(SDL_INIT_VIDEO) != 0) { LOG_PANIC("SDL_INIT_VIDEO error: %s", SDL_GetError()); } - if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES) != 0) { - LOG_PANIC("Failed to set SDL_GL_CONTEXT_PROFILE_MASK attribute. %s", SDL_GetError()); - }; - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - SDL_GL_SetSwapInterval(1); - window = SDL_CreateWindow(title, - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - width, height, - SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + // prefer OpenGL core profile + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + opengl_profile = eOpenGL_profile_core; + window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + if (window == NULL) { + LOG_WARN("Failed to create OpenGL core profile: %s. Trying OpenGLES...", SDL_GetError()); + // fallback to OpenGL ES 3 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + opengl_profile = eOpenGL_profile_es; + window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + } if (window == NULL) { LOG_PANIC("Failed to create window. %s", SDL_GetError()); } @@ -90,7 +95,7 @@ static void* create_window_and_renderer(char* title, int x, int y, int width, in exit(1); } - GLRenderer_Init(render_width, render_height); + GLRenderer_Init(opengl_profile, render_width, render_height); update_viewport(); return window; diff --git a/src/harness/renderers/gl/gl_renderer.c b/src/harness/renderers/gl/gl_renderer.c index 822b5df5..7d8a40fc 100644 --- a/src/harness/renderers/gl/gl_renderer.c +++ b/src/harness/renderers/gl/gl_renderer.c @@ -1,17 +1,15 @@ #include "gl_renderer.h" #include "brender/brender.h" +#include "embedded_resources.h" #include "harness.h" #include "harness/trace.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 #include #include +static tOpenGL_profile opengl_profile; static GLuint screen_buffer_vao, screen_buffer_ebo; static GLuint fullscreen_quad_texture, palette_texture, depth_texture; @@ -80,10 +78,22 @@ static GLuint CreateShaderProgram(char* name, const char* vertex_shader, const i GLuint program; GLuint v_shader, f_shader; + embedded_resource_t* header; + + if (opengl_profile == eOpenGL_profile_es) { + header = get_embedded_resource_by_name("resources/gles_header.glsl"); + } else { + header = get_embedded_resource_by_name("resources/glcore_header.glsl"); + } + if (header == NULL) { + LOG_PANIC("Failed to get glsl header resource"); + } + program = glCreateProgram(); v_shader = glCreateShader(GL_VERTEX_SHADER); - const GLchar* vertex_sources[] = { vertex_shader }; - glShaderSource(v_shader, 1, vertex_sources, &vertex_shader_len); + const GLchar* vertex_sources[] = { header->content, vertex_shader }; + const GLint vertex_source_lengths[] = { header->len, vertex_shader_len }; + glShaderSource(v_shader, 2, vertex_sources, vertex_source_lengths); glCompileShader(v_shader); glGetShaderiv(v_shader, GL_COMPILE_STATUS, &success); if (!success) { @@ -92,8 +102,9 @@ static GLuint CreateShaderProgram(char* name, const char* vertex_shader, const i } f_shader = glCreateShader(GL_FRAGMENT_SHADER); - const GLchar* fragment_sources[] = { fragment_shader }; - glShaderSource(f_shader, 1, fragment_sources, &fragment_shader_len); + const GLchar* fragment_sources[] = { header->content, fragment_shader }; + const GLint fragment_source_lengths[] = { header->len, fragment_shader_len }; + glShaderSource(f_shader, 2, fragment_sources, fragment_source_lengths); glCompileShader(f_shader); glGetShaderiv(f_shader, GL_COMPILE_STATUS, &success); if (!success) { @@ -127,7 +138,15 @@ static GLint GetValidatedUniformLocation(GLuint program, char* uniform_name) { } static void LoadShaders(void) { - shader_program_2d = CreateShaderProgram("framebuffer", RESOURCES_FRAMEBUFFER_VERT_GLSL, sizeof(RESOURCES_FRAMEBUFFER_VERT_GLSL), RESOURCES_FRAMEBUFFER_FRAG_GLSL, sizeof(RESOURCES_FRAMEBUFFER_FRAG_GLSL)); + embedded_resource_t* frag = get_embedded_resource_by_name("resources/framebuffer_frag.glsl"); + if (frag == NULL) { + LOG_PANIC("Failed to get embedded resource"); + } + embedded_resource_t* vert = get_embedded_resource_by_name("resources/framebuffer_vert.glsl"); + if (vert == NULL) { + LOG_PANIC("Failed to get embedded resource"); + } + shader_program_2d = CreateShaderProgram("framebuffer", vert->content, vert->len, frag->content, frag->len); glUseProgram(shader_program_2d); uniforms_2d.pixels = GetValidatedUniformLocation(shader_program_2d, "u_pixels"); uniforms_2d.palette = GetValidatedUniformLocation(shader_program_2d, "u_palette"); @@ -136,7 +155,16 @@ static void LoadShaders(void) { glUniform1i(uniforms_2d.pixels, 0); glUniform1i(uniforms_2d.palette, 1); - shader_program_3d = CreateShaderProgram("3d", RESOURCES_3D_VERT_GLSL, sizeof(RESOURCES_3D_VERT_GLSL), RESOURCES_3D_FRAG_GLSL, sizeof(RESOURCES_3D_FRAG_GLSL)); + frag = get_embedded_resource_by_name("resources/3d_frag.glsl"); + if (frag == NULL) { + LOG_PANIC("Failed to get embedded resource"); + } + vert = get_embedded_resource_by_name("resources/3d_vert.glsl"); + if (vert == NULL) { + LOG_PANIC("Failed to get embedded resource"); + } + + shader_program_3d = CreateShaderProgram("3d", vert->content, vert->len, frag->content, frag->len); glUseProgram(shader_program_3d); uniforms_3d.clip_plane_count = GetValidatedUniformLocation(shader_program_3d, "u_clip_plane_count"); for (int i = 0; i < 6; i++) { @@ -211,7 +239,8 @@ static void SetupFullScreenRectGeometry(void) { glBindVertexArray(0); } -void GLRenderer_Init(int pRender_width, int pRender_height) { +void GLRenderer_Init(tOpenGL_profile profile, int pRender_width, int pRender_height) { + opengl_profile = profile; render_width = pRender_width; render_height = pRender_height; @@ -394,17 +423,16 @@ void GLRenderer_EndScene(void) { void GLRenderer_FullScreenQuad(uint8_t* screen_buffer) { - glViewport(vp_x, vp_y, vp_width, vp_height); - + glBindFramebuffer(GL_FRAMEBUFFER, 0); - + glDisable(GL_DEPTH_TEST); - - // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -//CHECK_GL_ERROR("GLRenderer_RenderFullScreenQuad2"); + + // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + // CHECK_GL_ERROR("GLRenderer_RenderFullScreenQuad2"); glBindTexture(GL_TEXTURE_2D, fullscreen_quad_texture); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, render_width, render_height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, screen_buffer); glBindVertexArray(screen_buffer_vao); @@ -627,10 +655,10 @@ void GLRenderer_Model(br_actor* actor, br_model* model, br_material* material, b switch (render_type) { case BRT_TRIANGLE: - //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; case BRT_LINE: - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glUniform1ui(uniforms_3d.material_index_base, 255); glUniform1ui(uniforms_3d.material_flags, 0); break; @@ -699,22 +727,26 @@ void GLRenderer_BufferTexture(br_pixelmap* pm) { void GLRenderer_FlushBuffer(tRenderer_flush_type flush_type) { uint8_t* pm_pixels = last_colour_buffer->pixels; - + uint16_t* depth_pixels = last_depth_buffer->pixels; + if (!dirty_buffers) { return; } - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id); - glReadPixels(0, 0, render_width, render_height, GL_RED_INTEGER, GL_UNSIGNED_BYTE, screen_buffer_flip_pixels); - // pull framebuffer into cpu memory to emulate BRender behavior - //glBindTexture(GL_TEXTURE_2D, framebuffer_texture); - //glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, screen_buffer_flip_pixels); + if (opengl_profile == eOpenGL_profile_es) { + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id); + glReadPixels(0, 0, render_width, render_height, GL_RED_INTEGER, GL_UNSIGNED_BYTE, screen_buffer_flip_pixels); + } else { + glBindTexture(GL_TEXTURE_2D, framebuffer_texture); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, screen_buffer_flip_pixels); + } + CHECK_GL_ERROR("GLRenderer_FlushBuffer3"); - + // flip texture to match the expected orientation int dest_y = render_height; - + uint8_t new_pixel; for (int y = 0; y < render_height; y++) { dest_y--; @@ -731,14 +763,16 @@ void GLRenderer_FlushBuffer(tRenderer_flush_type flush_type) { if (flush_type == eFlush_all) { // pull depthbuffer into cpu memory to emulate BRender behavior - //glBindTexture(GL_TEXTURE_2D, depth_texture); - //glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depth_buffer_flip_pixels); - - glReadPixels(0, 0, render_width, render_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depth_buffer_flip_pixels); + if (opengl_profile == eOpenGL_profile_es) { + glReadPixels(0, 0, render_width, render_height, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depth_buffer_flip_pixels); + } else { + glBindTexture(GL_TEXTURE_2D, depth_texture); + glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, depth_buffer_flip_pixels); + } dest_y = last_colour_buffer->height; int src_y = render_height - last_colour_buffer->base_y - last_colour_buffer->height; - uint16_t* depth_pixels = last_depth_buffer->pixels; + for (int y = 0; y < last_colour_buffer->height; y++) { dest_y--; for (int x = 0; x < last_colour_buffer->width; x++) { diff --git a/src/harness/renderers/gl/gl_renderer.h b/src/harness/renderers/gl/gl_renderer.h index 9a7fabc9..1b5aec4c 100644 --- a/src/harness/renderers/gl/gl_renderer.h +++ b/src/harness/renderers/gl/gl_renderer.h @@ -4,6 +4,11 @@ #include "harness.h" #include "harness/hooks.h" +typedef enum tOpenGL_profile { + eOpenGL_profile_core, + eOpenGL_profile_es, +} tOpenGL_profile; + #define CHECK_GL_ERROR(msg) \ { \ GLenum e = glGetError(); \ @@ -36,7 +41,7 @@ } \ } -void GLRenderer_Init(int render_width, int render_height); +void GLRenderer_Init(tOpenGL_profile profile, int render_width, int render_height); void GLRenderer_SetPalette(uint8_t* rgba_colors); void GLRenderer_BeginScene(br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer); void GLRenderer_EndScene(void); diff --git a/src/harness/resources/3d_frag.glsl b/src/harness/resources/3d_frag.glsl index 4394a456..be72504c 100644 --- a/src/harness/resources/3d_frag.glsl +++ b/src/harness/resources/3d_frag.glsl @@ -1,9 +1,3 @@ -#version 300 es - -precision mediump float; -precision mediump int; -precision lowp usampler2D; - // Input, output variables // ======================= @@ -80,7 +74,7 @@ void main(void) { if (texel == 0u) { discard; } - + if ((u_material_flags & BR_MATF_LIGHT) != 0u) { if ((u_material_flags & BR_MATF_PRELIT) != 0u) { // BR_MATF_PRELIT means the light value comes from the vertex color attribute @@ -101,8 +95,10 @@ void main(void) { // u_colour_buffer is upside down from opengl perspective. We need to sample it upside down. int i = int(gl_FragCoord.x); int i2 = int(u_viewport_height) - int(gl_FragCoord.y); - ivec2 coords = ivec2(gl_FragCoord.x, i2); + ivec2 coords = ivec2(int(gl_FragCoord.x), i2); uint current_framebuffer_color = texelFetch(u_colour_buffer, coords, 0).r; + + // uint current_framebuffer_color = texelFetch(u_colour_buffer, ivec2(gl_FragCoord.x, int(u_viewport_height - gl_FragCoord.y)), 0).r; out_palette_index = texelFetch(u_material_blend_table, ivec2(out_palette_index, current_framebuffer_color), 0).r; } diff --git a/src/harness/resources/3d_vert.glsl b/src/harness/resources/3d_vert.glsl index cc97c6f4..42eb1b99 100644 --- a/src/harness/resources/3d_vert.glsl +++ b/src/harness/resources/3d_vert.glsl @@ -1,8 +1,3 @@ -#version 300 es - -precision mediump float; -precision mediump int; - layout (location = 0) in vec3 a_pos; layout (location = 1) in vec3 a_normal; layout (location = 2) in vec2 a_uv; diff --git a/src/harness/resources/framebuffer_frag.glsl b/src/harness/resources/framebuffer_frag.glsl index 70760ae2..e4dc3c5e 100644 --- a/src/harness/resources/framebuffer_frag.glsl +++ b/src/harness/resources/framebuffer_frag.glsl @@ -1,10 +1,3 @@ -#version 300 es - -precision mediump float; -precision mediump int; -precision lowp usampler2D; - - in vec2 v_tex_coord; uniform usampler2D u_pixels; diff --git a/src/harness/resources/framebuffer_vert.glsl b/src/harness/resources/framebuffer_vert.glsl index 67d294fa..219fde32 100644 --- a/src/harness/resources/framebuffer_vert.glsl +++ b/src/harness/resources/framebuffer_vert.glsl @@ -1,14 +1,7 @@ -#version 300 es - -precision highp float; -precision highp int; - layout (location = 0) in vec3 a_pos; layout (location = 1) in vec3 a_color; layout (location = 2) in vec2 a_uv; - - out vec2 v_tex_coord; void main(void) { diff --git a/src/harness/resources/glcore_header.glsl b/src/harness/resources/glcore_header.glsl new file mode 100644 index 00000000..e5715fa9 --- /dev/null +++ b/src/harness/resources/glcore_header.glsl @@ -0,0 +1,2 @@ +#version 140 +#extension GL_ARB_explicit_attrib_location : require diff --git a/src/harness/resources/gles_header.glsl b/src/harness/resources/gles_header.glsl new file mode 100644 index 00000000..a852d8cc --- /dev/null +++ b/src/harness/resources/gles_header.glsl @@ -0,0 +1,5 @@ +#version 300 es + +precision mediump float; +precision mediump int; +precision lowp usampler2D;