diff --git a/include/twn_texture_modes.h b/include/twn_texture_modes.h index 5b2936b..cc07fd2 100644 --- a/include/twn_texture_modes.h +++ b/include/twn_texture_modes.h @@ -9,6 +9,7 @@ typedef enum TextureMode { TEXTURE_MODE_OPAQUE, /* all pixels are solid */ TEXTURE_MODE_SEETHROUGH, /* some pixels are alpha zero */ TEXTURE_MODE_GHOSTLY, /* arbitrary alpha values */ + TEXTURE_MODE_UNKNOWN = -1, /* a sentinel */ } TextureMode; #endif diff --git a/src/rendering/twn_draw_c.h b/src/rendering/twn_draw_c.h index 3bc3add..6ac464f 100644 --- a/src/rendering/twn_draw_c.h +++ b/src/rendering/twn_draw_c.h @@ -137,6 +137,7 @@ void create_circle_geometry(Vec2 position, struct QuadBatch { size_t size; /* how many primitives are in current batch */ + TextureKey texture_key; TextureMode mode; /* how color should be applied */ bool constant_colored; /* whether colored batch is uniformly colored */ bool repeat; /* whether repeat is needed */ diff --git a/src/rendering/twn_gl_15_rendering.c b/src/rendering/twn_gl_15_rendering.c index 187e971..d854b12 100644 --- a/src/rendering/twn_gl_15_rendering.c +++ b/src/rendering/twn_gl_15_rendering.c @@ -31,6 +31,7 @@ typedef struct ElementIndexedQuad { Color c3; } ElementIndexedQuad; + typedef struct ElementIndexedQuadWithoutColor { /* upper-left */ Vec2 v0; @@ -111,6 +112,11 @@ typedef struct { } DeferredCommandDraw; +typedef struct { + char *paths; +} DeferredCommandDrawSkybox; + + typedef struct { Color color; bool clear_color; @@ -144,6 +150,7 @@ typedef struct { typedef struct { enum DeferredCommandType { DEFERRED_COMMAND_TYPE_DRAW, + DEFERRED_COMMAND_TYPE_DRAW_SKYBOX, DEFERRED_COMMAND_TYPE_CLEAR, DEFERRED_COMMAND_TYPE_USE_PIPIELINE, DEFERRED_COMMAND_TYPE_USE_TEXTURE_MODE, @@ -152,6 +159,7 @@ typedef struct { union { DeferredCommandDraw draw; + DeferredCommandDrawSkybox draw_skybox; DeferredCommandClear clear; DeferredCommandUsePipeline use_pipeline; DeferredCommandUseTextureMode use_texture_mode; @@ -160,7 +168,7 @@ typedef struct { } DeferredCommand; -static TextureMode texture_mode_last_used = -1; +static TextureMode texture_mode_last_used = TEXTURE_MODE_UNKNOWN; static Pipeline pipeline_last_used = PIPELINE_NO; @@ -199,6 +207,7 @@ GLuint get_scratch_vertex_array(void) { static void finally_use_2d_pipeline(void); static void finally_use_space_pipeline(void); static void finally_use_texture_mode(TextureMode mode); +static void deferred_render_skybox(char *paths); static DeferredCommand *deferred_commands; @@ -311,6 +320,11 @@ static void issue_deferred_draw_commands(void) { break; } + case DEFERRED_COMMAND_TYPE_DRAW_SKYBOX: { + deferred_render_skybox(deferred_commands[i].draw_skybox.paths); + break; + } + case DEFERRED_COMMAND_TYPE_USE_PIPIELINE: { switch (deferred_commands[i].use_pipeline.pipeline) { case PIPELINE_2D: @@ -457,7 +471,7 @@ static void finally_use_2d_pipeline(void) { /* removes near/far plane comparison and discard */ if (GLAD_GL_ARB_depth_clamp) - glDisable(GL_DEPTH_CLAMP); + glEnable(GL_DEPTH_CLAMP); glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); @@ -629,9 +643,8 @@ void finally_render_quads(const Primitive2D primitives[], } if (batch.textured) { - /* TODO: bad, don't */ command.textured = true; - command.texture_key = primitives->sprite.texture_key; + command.texture_key = batch.texture_key; command.texture_repeat = batch.repeat; } @@ -913,6 +926,18 @@ void render_circle(const CirclePrimitive *circle) { void finally_render_skybox(char *paths) { + DeferredCommand command = { + .type = DEFERRED_COMMAND_TYPE_DRAW_SKYBOX, + .draw_skybox = (DeferredCommandDrawSkybox){ + .paths = paths + } + }; + + arrpush(deferred_commands, command); +} + + +static void deferred_render_skybox(char *paths) { static GLuint cubemap = 0; static char *paths_cache = NULL; @@ -945,27 +970,27 @@ void finally_render_skybox(char *paths) { if (loading_needed) { /* load all the sides */ char *expanded = expand_asterisk(paths, "up"); - load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_POSITIVE_Y); + load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_POSITIVE_Y); SDL_free(expanded); expanded = expand_asterisk(paths, "down"); - load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y); + load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y); SDL_free(expanded); expanded = expand_asterisk(paths, "east"); - load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_POSITIVE_X); + load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_POSITIVE_X); SDL_free(expanded); expanded = expand_asterisk(paths, "north"); - load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_POSITIVE_Z); + load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_POSITIVE_Z); SDL_free(expanded); expanded = expand_asterisk(paths, "west"); - load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_NEGATIVE_X); + load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_NEGATIVE_X); SDL_free(expanded); expanded = expand_asterisk(paths, "south"); - load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); + load_cubemap_side(expanded, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); SDL_free(expanded); } @@ -981,6 +1006,10 @@ void finally_render_skybox(char *paths) { glDisable(GL_ALPHA_TEST); glDepthMask(GL_FALSE); + /* removes near/far plane comparison and discard */ + if (GLAD_GL_ARB_depth_clamp) + glEnable(GL_DEPTH_CLAMP); + glBegin(GL_QUADS); { /* up */ glTexCoord3f(50.f, 50.f, 50.f); @@ -1043,6 +1072,9 @@ void finally_render_skybox(char *paths) { glVertex3f(-50.f, 50.f, -50.f); } glEnd(); + if (GLAD_GL_ARB_depth_clamp) + glDisable(GL_DEPTH_CLAMP); + glDepthMask(GL_TRUE); glDisable(GL_TEXTURE_CUBE_MAP); diff --git a/src/rendering/twn_sprites.c b/src/rendering/twn_sprites.c index 0f5bc26..49354ea 100644 --- a/src/rendering/twn_sprites.c +++ b/src/rendering/twn_sprites.c @@ -69,6 +69,7 @@ struct QuadBatch collect_sprite_batch(const Primitive2D primitives[], size_t len struct QuadBatch batch = { .mode = textures_get_mode(&ctx.texture_cache, primitives[0].sprite.texture_key), + .texture_key = primitives[0].sprite.texture_key, .constant_colored = true, .repeat = primitives[0].sprite.repeat, .textured = true,