From cc98c63d00de0a5319d91f4985f880ba26cfc533 Mon Sep 17 00:00:00 2001 From: dashodanger <> Date: Sun, 10 Nov 2024 15:08:12 -0700 Subject: [PATCH 1/2] Consolidate GL state changes and render calls --- source_files/edge/con_con.cc | 228 +++++++------ source_files/edge/e_main.cc | 120 +++++-- source_files/edge/f_finale.cc | 8 +- source_files/edge/hu_draw.cc | 515 ++++++++++++++-------------- source_files/edge/hu_draw.h | 3 +- source_files/edge/hu_font.cc | 36 +- source_files/edge/hu_stuff.cc | 2 - source_files/edge/i_movie.cc | 159 +++++---- source_files/edge/i_video.cc | 5 +- source_files/edge/m_menu.cc | 4 +- source_files/edge/p_maputl.cc | 2 - source_files/edge/r_colormap.cc | 4 +- source_files/edge/r_draw.cc | 62 +--- source_files/edge/r_draw.h | 4 - source_files/edge/r_effects.cc | 69 ++-- source_files/edge/r_image.cc | 4 +- source_files/edge/r_main.cc | 36 +- source_files/edge/r_md2.cc | 148 ++++---- source_files/edge/r_mdl.cc | 148 ++++---- source_files/edge/r_misc.cc | 50 ++- source_files/edge/r_render.cc | 140 +++----- source_files/edge/r_sky.cc | 585 ++++++++++++++++++-------------- source_files/edge/r_state.cc | 7 +- source_files/edge/r_state.h | 310 +++++++++++------ source_files/edge/r_texgl.cc | 27 +- source_files/edge/r_things.cc | 55 ++- source_files/edge/r_units.cc | 311 ++++++++--------- source_files/edge/r_units.h | 15 + source_files/edge/r_wipe.cc | 182 +++++----- 29 files changed, 1661 insertions(+), 1578 deletions(-) diff --git a/source_files/edge/con_con.cc b/source_files/edge/con_con.cc index 98137780d..bf2931cbe 100644 --- a/source_files/edge/con_con.cc +++ b/source_files/edge/con_con.cc @@ -50,6 +50,7 @@ #include "r_draw.h" #include "r_image.h" #include "r_modes.h" +#include "r_units.h" #include "r_wipe.h" #include "stb_sprintf.h" #include "w_files.h" @@ -572,25 +573,24 @@ static void CalcSizes() (FNSZ / console_font->image_character_height_)); } -static void SolidBox(int x, int y, int w, int h, RGBAColor col, float alpha) +static void SolidBox(float x, float y, float w, float h, RGBAColor col, float alpha) { - if (alpha < 0.99f) - glEnable(GL_BLEND); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, + 0, alpha < 0.99f ? kBlendingAlpha : kBlendingNone); sg_color sgcol = sg_make_color_1i(col); - - glColor4f(sgcol.r, sgcol.g, sgcol.b, alpha); - - glBegin(GL_QUADS); - - glVertex2i(x, y); - glVertex2i(x, y + h); - glVertex2i(x + w, y + h); - glVertex2i(x + w, y); - - glEnd(); - - glDisable(GL_BLEND); + sgcol.a = alpha; + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x, y, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x, y + h, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x + w, y + h, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x + w, y, 0}}; + + EndRenderUnit(4); } static void HorizontalLine(int y, RGBAColor col) @@ -600,15 +600,11 @@ static void HorizontalLine(int y, RGBAColor col) SolidBox(0, y, current_screen_width - 1, 1, col, alpha); } -static void DrawChar(int x, int y, char ch, RGBAColor col) +static void DrawChar(float x, float y, char ch, RendererVertex *glvert, sg_color *col) { if (x + FNSZ < 0) return; - sg_color sgcol = sg_make_color_1i(col); - - glColor4f(sgcol.r, sgcol.g, sgcol.b, 1.0f); - if (console_font->definition_->type_ == kFontTypeTrueType) { float chwidth = console_font->CharWidth(ch); @@ -618,16 +614,18 @@ static void DrawChar(int x, int y, char ch, RGBAColor col) float y_adjust = console_font->truetype_glyph_map_.at((uint8_t)ch).y_shift[current_font_size] * FNSZ_ratio; float height = console_font->truetype_glyph_map_.at((uint8_t)ch).height[current_font_size] * FNSZ_ratio; stbtt_aligned_quad *q = console_font->truetype_glyph_map_.at((uint8_t)ch).character_quad[current_font_size]; - glBegin(GL_POLYGON); - glTexCoord2f(q->s0, q->t0); - glVertex2f(x + x_adjust, y - y_adjust); - glTexCoord2f(q->s1, q->t0); - glVertex2f(x + x_adjust + width, y - y_adjust); - glTexCoord2f(q->s1, q->t1); - glVertex2f(x + x_adjust + width, y - y_adjust - height); - glTexCoord2f(q->s0, q->t1); - glVertex2f(x + x_adjust, y - y_adjust - height); - glEnd(); + memcpy(&glvert->rgba_color, col, 4 * sizeof(float)); + glvert->position = {{x + x_adjust, y - y_adjust, 0}}; + glvert++->texture_coordinates[0] = {{q->s0, q->t0}}; + memcpy(&glvert->rgba_color, col, 4 * sizeof(float)); + glvert->position = {{x + x_adjust + width, y - y_adjust, 0}}; + glvert++->texture_coordinates[0] = {{q->s1, q->t0}}; + memcpy(&glvert->rgba_color, col, 4 * sizeof(float)); + glvert->position = {{x + x_adjust + width, y - y_adjust - height, 0}}; + glvert++->texture_coordinates[0] = {{q->s1, q->t1}}; + memcpy(&glvert->rgba_color, col, 4 * sizeof(float)); + glvert->position = {{x + x_adjust, y - y_adjust - height, 0}}; + glvert->texture_coordinates[0] = {{q->s0, q->t1}}; return; } @@ -639,51 +637,45 @@ static void DrawChar(int x, int y, char ch, RGBAColor col) float ty1 = (py)*console_font->font_image_->height_ratio_; float ty2 = (py + 1) * console_font->font_image_->height_ratio_; - glBegin(GL_POLYGON); - - glTexCoord2f(tx1, ty1); - glVertex2i(x, y); - - glTexCoord2f(tx1, ty2); - glVertex2i(x, y + FNSZ); - - glTexCoord2f(tx2, ty2); - glVertex2i(x + FNSZ, y + FNSZ); - - glTexCoord2f(tx2, ty1); - glVertex2i(x + FNSZ, y); - - glEnd(); + memcpy(&glvert->rgba_color, col, 4 * sizeof(float)); + glvert->position = {{x, y, 0}}; + glvert++->texture_coordinates[0] = {{tx1, ty1}}; + memcpy(&glvert->rgba_color, col, 4 * sizeof(float)); + glvert->position = {{x, y + FNSZ, 0}}; + glvert++->texture_coordinates[0] = {{tx1, ty2}}; + memcpy(&glvert->rgba_color, col, 4 * sizeof(float)); + glvert->position = {{x + FNSZ, y + FNSZ, 0}}; + glvert++->texture_coordinates[0] = {{tx2, ty2}}; + memcpy(&glvert->rgba_color, col, 4 * sizeof(float)); + glvert->position = {{x + FNSZ, y, 0}}; + glvert->texture_coordinates[0] = {{tx2, ty1}}; } -static void DrawEndoomChar(float x, float y, char ch, RGBAColor col, RGBAColor col2, bool blink, int enwidth) +static void DrawEndoomChar(float x, float y, char ch, RGBAColor col, RGBAColor col2, bool blink, int enwidth, GLuint tex_id) { if (x + FNSZ < 0) return; sg_color sgcol = sg_make_color_1i(col2); + sgcol.a = 1.0f; - glDisable(GL_TEXTURE_2D); - - glColor4f(sgcol.r, sgcol.g, sgcol.b, 1.0f); - - glBegin(GL_QUADS); - - glVertex2i(x - (enwidth / 2), y); - - glVertex2i(x - (enwidth / 2), y + FNSZ); - - glVertex2i(x + (enwidth / 2), y + FNSZ); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, + 0, kBlendingNone); - glVertex2i(x + (enwidth / 2), y); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x - (enwidth / 2), y}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x - (enwidth / 2), y + FNSZ}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x + (enwidth / 2), y + FNSZ}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x + (enwidth / 2), y}}; - glEnd(); - glEnable(GL_TEXTURE_2D); + EndRenderUnit(4); sgcol = sg_make_color_1i(col); - - glColor4f(sgcol.r, sgcol.g, sgcol.b, 1.0f); + sgcol.a = 1.0f; if (blink && console_cursor >= 16) ch = 0x20; @@ -697,49 +689,47 @@ static void DrawEndoomChar(float x, float y, char ch, RGBAColor col, RGBAColor c float ty1 = (py)*endoom_font->font_image_->height_ratio_; float ty2 = (py + 1) * endoom_font->font_image_->height_ratio_; - glBegin(GL_POLYGON); - - glTexCoord2f(tx1, ty1); - glVertex2i(x - enwidth, y); - - glTexCoord2f(tx1, ty2); - glVertex2i(x - enwidth, y + FNSZ); - - glTexCoord2f(tx2, ty2); - glVertex2i(x + enwidth, y + FNSZ); - - glTexCoord2f(tx2, ty1); - glVertex2i(x + enwidth, y); - - glEnd(); + glvert = BeginRenderUnit(GL_POLYGON, 4, GL_MODULATE, tex_id, (GLuint)kTextureEnvironmentDisable, 0, + 0, kBlendingMasked); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty1}}; + glvert++->position = {{x - enwidth, y}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty2}}; + glvert++->position = {{x - enwidth, y + FNSZ}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty2}}; + glvert++->position = {{x + enwidth, y + FNSZ}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty1}}; + glvert->position = {{x + enwidth, y}}; + + EndRenderUnit(4); } // writes the text on coords (x,y) of the console -static void DrawText(int x, int y, const char *s, RGBAColor col) +static void DrawText(float x, float y, const char *s, RGBAColor col) { + GLuint tex_id = 0; + BlendingMode blend = kBlendingNone; + if (console_font->definition_->type_ == kFontTypeImage) { // Always whiten the font when used with console output - GLuint tex_id = ImageCache(console_font->font_image_, true, (const Colormap *)0, true); - - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, tex_id); - - glEnable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0); + tex_id = ImageCache(console_font->font_image_, true, (const Colormap *)0, true); + blend = kBlendingMasked; } else if (console_font->definition_->type_ == kFontTypeTrueType) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_TEXTURE_2D); if ((image_smoothing && console_font->definition_->truetype_smoothing_ == FontDefinition::kTrueTypeSmoothOnDemand) || console_font->definition_->truetype_smoothing_ == FontDefinition::kTrueTypeSmoothAlways) - glBindTexture(GL_TEXTURE_2D, console_font->truetype_smoothed_texture_id_[current_font_size]); + tex_id = console_font->truetype_smoothed_texture_id_[current_font_size]; else - glBindTexture(GL_TEXTURE_2D, console_font->truetype_texture_id_[current_font_size]); + tex_id = console_font->truetype_texture_id_[current_font_size]; + + blend = kBlendingAlpha; } bool draw_cursor = false; @@ -750,10 +740,18 @@ static void DrawText(int x, int y, const char *s, RGBAColor col) draw_cursor = true; } + sg_color sgcol = sg_make_color_1i(col); + RendererVertex *glvert = nullptr; + int pos = 0; for (; *s; s++, pos++) { - DrawChar(x, y, *s, col); + glvert = BeginRenderUnit(GL_POLYGON, 4, GL_MODULATE, tex_id, (GLuint)kTextureEnvironmentDisable, 0, + 0, blend); + + DrawChar(x, y, *s, glvert, &sgcol); + + EndRenderUnit(4); if (console_font->definition_->type_ == kFontTypeTrueType) { @@ -767,7 +765,13 @@ static void DrawText(int x, int y, const char *s, RGBAColor col) if (pos == input_position && draw_cursor) { - DrawChar(x, y, 95, col); + glvert = BeginRenderUnit(GL_POLYGON, 4, GL_MODULATE, tex_id, (GLuint)kTextureEnvironmentDisable, 0, + 0, blend); + + DrawChar(x, y, 95, glvert, &sgcol); + + EndRenderUnit(4); + draw_cursor = false; } @@ -778,11 +782,14 @@ static void DrawText(int x, int y, const char *s, RGBAColor col) } if (draw_cursor) - DrawChar(x, y, 95, col); + { + glvert = BeginRenderUnit(GL_POLYGON, 4, GL_MODULATE, tex_id, (GLuint)kTextureEnvironmentDisable, 0, + 0, blend); - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); + DrawChar(x, y, 95, glvert, &sgcol); + + EndRenderUnit(4); + } } static void EndoomDrawText(int x, int y, ConsoleLine *endoom_line) @@ -793,29 +800,18 @@ static void EndoomDrawText(int x, int y, ConsoleLine *endoom_line) int enwidth = RoundToInteger((float)endoom_font->image_monospace_width_ * ((float)FNSZ / endoom_font->image_monospace_width_) / 2); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, tex_id); - - glEnable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0); - for (int i = 0; i < 80; i++) { uint8_t info = endoom_line->endoom_bytes_.at(i); DrawEndoomChar(x, y, endoom_line->line_.at(i), endoom_colors[info & 15], endoom_colors[(info >> 4) & 7], - info & 128, enwidth); + info & 128, enwidth, tex_id); x += enwidth; if (x >= current_screen_width) break; } - - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); } void ConsoleSetupFont(void) @@ -860,6 +856,8 @@ void ConsoleDrawer(void) // -- background -- + StartUnitBatch(false); + int CON_GFX_HT = (current_screen_height * 3 / 5); int y = current_screen_height; @@ -939,6 +937,8 @@ void ConsoleDrawer(void) if (y >= current_screen_height) break; } + + FinishUnitBatch(); } static void GotoEndOfLine(void) @@ -1624,6 +1624,8 @@ void ConsoleShowFPS(void) if (debug_fps.d_ == 0) return; + StartUnitBatch(false); + ConsoleSetupFont(); // -AJA- 2022: reworked for better accuracy, ability to show WORST time @@ -1723,6 +1725,8 @@ void ConsoleShowFPS(void) stbsp_sprintf(textbuf, "%i texture", ec_frame_stats.draw_texture_change); DrawText(x, y, textbuf, SG_WEB_GRAY_RGBA32); } + + FinishUnitBatch(); } void ConsoleShowPosition(void) @@ -1730,6 +1734,8 @@ void ConsoleShowPosition(void) if (debug_position.d_ <= 0) return; + StartUnitBatch(false); + ConsoleSetupFont(); Player *p = players[display_player]; @@ -1779,6 +1785,8 @@ void ConsoleShowPosition(void) y -= FNSZ; stbsp_sprintf(textbuf, " sub: %d", (int)(p->map_object_->subsector_ - level_subsectors)); DrawText(x, y, textbuf, SG_WEB_GRAY_RGBA32); + + FinishUnitBatch(); } void ConsolePrintEndoom() diff --git a/source_files/edge/e_main.cc b/source_files/edge/e_main.cc index 47b407908..4a2c82d74 100644 --- a/source_files/edge/e_main.cc +++ b/source_files/edge/e_main.cc @@ -269,20 +269,60 @@ class StartupProgress if (gamma_correction.f_ < 0) { int col = (1.0f + gamma_correction.f_) * 255; - glEnable(GL_BLEND); - glBlendFunc(GL_ZERO, GL_SRC_COLOR); - HUDSolidBox(hud_x_left, 0, hud_x_right, 200, epi::MakeRGBA(col, col, col)); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_BLEND); + sg_color sgcol = sg_make_color_4b(col, col, col, 255); + sgcol.a = HUDGetAlpha(); + + StartUnitBatch(false); + + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNegativeGamma); + + float x1 = 0; + float x2 = current_screen_width; + + float y1 = current_screen_height; + float y2 = 0; + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x1, y2, 0}}; + + EndRenderUnit(4); + + FinishUnitBatch(); } else if (gamma_correction.f_ > 0) { int col = gamma_correction.f_ * 255; - glEnable(GL_BLEND); - glBlendFunc(GL_DST_COLOR, GL_ONE); - HUDSolidBox(hud_x_left, 0, hud_x_right, 200, epi::MakeRGBA(col, col, col)); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_BLEND); + sg_color sgcol = sg_make_color_4b(col, col, col, 255); + sgcol.a = HUDGetAlpha(); + + StartUnitBatch(false); + + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingPositiveGamma); + + float x1 = 0; + float x2 = current_screen_width; + + float y1 = current_screen_height; + float y2 = 0; + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x1, y2, 0}}; + + EndRenderUnit(4); + + FinishUnitBatch(); } FinishFrame(); @@ -688,20 +728,60 @@ void EdgeDisplay(void) if (gamma_correction.f_ < 0) { int col = (1.0f + gamma_correction.f_) * 255; - glEnable(GL_BLEND); - glBlendFunc(GL_ZERO, GL_SRC_COLOR); - HUDSolidBox(hud_x_left, 0, hud_x_right, 200, epi::MakeRGBA(col, col, col)); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_BLEND); + sg_color sgcol = sg_make_color_4b(col, col, col, 255); + sgcol.a = HUDGetAlpha(); + + StartUnitBatch(false); + + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNegativeGamma); + + float x1 = 0; + float x2 = current_screen_width; + + float y1 = current_screen_height; + float y2 = 0; + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x1, y2, 0}}; + + EndRenderUnit(4); + + FinishUnitBatch(); } else if (gamma_correction.f_ > 0) { int col = gamma_correction.f_ * 255; - glEnable(GL_BLEND); - glBlendFunc(GL_DST_COLOR, GL_ONE); - HUDSolidBox(hud_x_left, 0, hud_x_right, 200, epi::MakeRGBA(col, col, col)); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_BLEND); + sg_color sgcol = sg_make_color_4b(col, col, col, 255); + sgcol.a = HUDGetAlpha(); + + StartUnitBatch(false); + + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingPositiveGamma); + + float x1 = 0; + float x2 = current_screen_width; + + float y1 = current_screen_height; + float y2 = 0; + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x1, y2, 0}}; + + EndRenderUnit(4); + + FinishUnitBatch(); } if (m_screenshot_required) diff --git a/source_files/edge/f_finale.cc b/source_files/edge/f_finale.cc index f90b4a4ce..dbef44f6f 100644 --- a/source_files/edge/f_finale.cc +++ b/source_files/edge/f_finale.cc @@ -803,14 +803,14 @@ static void CastDrawer(void) skin_img = ImageForDummySkin(); glClear(GL_DEPTH_BUFFER_BIT); - glEnable(GL_DEPTH_TEST); + global_render_state->Enable(GL_DEPTH_TEST); if (md->md2_model_) MD2RenderModel2D(md->md2_model_, skin_img, cast_state->frame, pos_x, pos_y, scale_x, scale_y, cast_order); else if (md->mdl_model_) MDLRenderModel2D(md->mdl_model_, skin_img, cast_state->frame, pos_x, pos_y, scale_x, scale_y, cast_order); - glDisable(GL_DEPTH_TEST); + global_render_state->Disable(GL_DEPTH_TEST); return; } @@ -838,8 +838,8 @@ static void CastDrawer(void) width *= scale_x; height *= scale_y; - RenderImage(pos_x - offset_x, pos_y + offset_y, width, height, image, flip ? image->Right() : 0, 0, - flip ? 0 : image->Right(), image->Top(), nullptr, 1.0f, cast_order->palremap_); + HUDRawImage(pos_x - offset_x, pos_y + offset_y, pos_x - offset_x + width, pos_y + offset_y + height, image, flip ? image->Right() : 0, 0, + flip ? 0 : image->Right(), image->Top(), 1.0f, kRGBANoValue, cast_order->palremap_); } // diff --git a/source_files/edge/hu_draw.cc b/source_files/edge/hu_draw.cc index 565205d98..8fd4f5aa9 100644 --- a/source_files/edge/hu_draw.cc +++ b/source_files/edge/hu_draw.cc @@ -225,7 +225,7 @@ void HUDPushScissor(float x1, float y1, float x2, float y2, bool expand) if (scissor_stack_top == 0) { - glEnable(GL_SCISSOR_TEST); + global_render_state->Enable(GL_SCISSOR_TEST); sx1 = HMM_MAX(sx1, 0); sy1 = HMM_MAX(sy1, 0); @@ -269,7 +269,7 @@ void HUDPopScissor() if (scissor_stack_top == 0) { - glDisable(GL_SCISSOR_TEST); + global_render_state->Disable(GL_SCISSOR_TEST); } else { @@ -363,25 +363,23 @@ void HUDCalcTurbulentTexCoords(float *tx, float *ty, float x, float y) void HUDRawImage(float hx1, float hy1, float hx2, float hy2, const Image *image, float tx1, float ty1, float tx2, float ty2, float alpha, RGBAColor text_col, const Colormap *palremap, float sx, float sy, char ch) { - int x1 = RoundToInteger(hx1); - int y1 = RoundToInteger(hy1); - int x2 = RoundToInteger(hx2 + 0.25f); - int y2 = RoundToInteger(hy2 + 0.25f); - - if (x1 >= x2 || y1 >= y2) + if (hx1 >= hx2 || hy1 >= hy2) return; - if (x2 < 0 || x1 > current_screen_width || y2 < 0 || y1 > current_screen_height) + if (hx2 < 0 || hx1 > current_screen_width || hy2 < 0 || hy1 > current_screen_height) return; sg_color sgcol = sg_white; + sgcol.a = alpha; + BlendingMode blend; + GLuint tex_id = 0; bool do_whiten = false; if (text_col != kRGBANoValue) { sgcol = sg_make_color_1i(text_col); - sgcol.a = 1.0f; + sgcol.a = alpha; do_whiten = true; } @@ -389,95 +387,87 @@ void HUDRawImage(float hx1, float hy1, float hx2, float hy2, const Image *image, { if (current_font->definition_->type_ == kFontTypeTrueType) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_TEXTURE_2D); + blend = kBlendingAlpha; if ((image_smoothing && current_font->definition_->truetype_smoothing_ == FontDefinition::kTrueTypeSmoothOnDemand) || current_font->definition_->truetype_smoothing_ == FontDefinition::kTrueTypeSmoothAlways) - glBindTexture(GL_TEXTURE_2D, current_font->truetype_smoothed_texture_id_[current_font_size]); + tex_id = current_font->truetype_smoothed_texture_id_[current_font_size]; else - glBindTexture(GL_TEXTURE_2D, current_font->truetype_texture_id_[current_font_size]); + tex_id = current_font->truetype_texture_id_[current_font_size]; } else // patch font { - glEnable(GL_ALPHA_TEST); if (!(alpha < 0.11f || image->opacity_ == kOpacityComplex)) - glAlphaFunc(GL_GREATER, alpha * 0.66f); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); + blend = kBlendingLess; + else + blend = kBlendingMasked; + blend = (BlendingMode)(blend|kBlendingAlpha); if ((image_smoothing && current_font->definition_->truetype_smoothing_ == FontDefinition::kTrueTypeSmoothOnDemand) || current_font->definition_->truetype_smoothing_ == FontDefinition::kTrueTypeSmoothAlways) { if (do_whiten) - glBindTexture(GL_TEXTURE_2D, current_font->patch_font_cache_.atlas_whitened_smoothed_texture_id); + tex_id = current_font->patch_font_cache_.atlas_whitened_smoothed_texture_id; else - glBindTexture(GL_TEXTURE_2D, current_font->patch_font_cache_.atlas_smoothed_texture_id); + tex_id = current_font->patch_font_cache_.atlas_smoothed_texture_id; } else { if (do_whiten) - glBindTexture(GL_TEXTURE_2D, current_font->patch_font_cache_.atlas_whitened_texture_id); + tex_id = current_font->patch_font_cache_.atlas_whitened_texture_id; else - glBindTexture(GL_TEXTURE_2D, current_font->patch_font_cache_.atlas_texture_id); + tex_id = current_font->patch_font_cache_.atlas_texture_id; } } - glColor4f(sgcol.r, sgcol.g, sgcol.b, alpha); - glBegin(GL_QUADS); - glTexCoord2f(tx1, ty2); - glVertex2f(hx1, hy1); - glTexCoord2f(tx2, ty2); - glVertex2f(hx2, hy1); - glTexCoord2f(tx2, ty1); - glVertex2f(hx2, hy2); - glTexCoord2f(tx1, ty1); - glVertex2f(hx1, hy2); - glEnd(); - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); - glAlphaFunc(GL_GREATER, 0); + + StartUnitBatch(false); + + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, tex_id, (GLuint)kTextureEnvironmentDisable, 0, 0, blend); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty2}}; + glvert++->position = {{hx1, hy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty2}}; + glvert++->position = {{hx2, hy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty1}}; + glvert++->position = {{hx2, hy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty1}}; + glvert->position = {{hx1, hy2, 0}}; + + EndRenderUnit(4); + + FinishUnitBatch(); return; } - // GLuint tex_id = ImageCache(image, true, palremap, do_whiten); - GLuint tex_id = ImageCache(image, true, nullptr, do_whiten); - - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, tex_id); + tex_id = ImageCache(image, true, nullptr, do_whiten); if (alpha >= 0.99f && image->opacity_ == kOpacitySolid) - glDisable(GL_ALPHA_TEST); + blend = kBlendingNone; else { - glEnable(GL_ALPHA_TEST); - if (!(alpha < 0.11f || image->opacity_ == kOpacityComplex)) - glAlphaFunc(GL_GREATER, alpha * 0.66f); + blend = kBlendingLess; + else + blend = kBlendingMasked; } if (image->opacity_ == kOpacityComplex || alpha < 0.99f) - glEnable(GL_BLEND); - - GLint old_s_clamp = kDummyClamp; - GLint old_t_clamp = kDummyClamp; + blend = (BlendingMode)(blend|kBlendingAlpha); if (sx != 0.0 || sy != 0.0) { - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, &old_s_clamp); - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, &old_t_clamp); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + blend = (BlendingMode)(blend|kBlendingRepeatX|kBlendingRepeatY); HUDCalcScrollTexCoords(sx, sy, &tx1, &ty1, &tx2, &ty2); } if (epi::StringCaseCompareASCII(image->name_, hud_overlays.at(video_overlay.d_)) == 0) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + blend = (BlendingMode)(blend|kBlendingRepeatX|kBlendingRepeatY); } bool hud_swirl = false; @@ -491,29 +481,30 @@ void HUDRawImage(float hx1, float hy1, float hx2, float hy2, const Image *image, if (image->liquid_type_ == kLiquidImageThick) hud_thick_liquid = true; - glColor4f(sgcol.r, sgcol.g, sgcol.b, alpha); + StartUnitBatch(false); - glBegin(GL_QUADS); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, tex_id, (GLuint)kTextureEnvironmentDisable, 0, 0, blend); if (hud_swirl) { - HUDCalcTurbulentTexCoords(&tx1, &ty1, x1, y1); - HUDCalcTurbulentTexCoords(&tx2, &ty2, x2, y2); + HUDCalcTurbulentTexCoords(&tx1, &ty1, hx1, hy1); + HUDCalcTurbulentTexCoords(&tx2, &ty2, hx2, hy2); } - glTexCoord2f(tx1, ty1); - glVertex2i(x1, y1); - - glTexCoord2f(tx2, ty1); - glVertex2i(x2, y1); - - glTexCoord2f(tx2, ty2); - glVertex2i(x2, y2); - - glTexCoord2f(tx1, ty2); - glVertex2i(x1, y2); - - glEnd(); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty1}}; + glvert++->position = {{hx1, hy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty1}}; + glvert++->position = {{hx2, hy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty2}}; + glvert++->position = {{hx2, hy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty2}}; + glvert->position = {{hx1, hy2, 0}}; + + EndRenderUnit(4); if (hud_swirl && swirling_flats == kLiquidSwirlParallax) { @@ -522,98 +513,81 @@ void HUDRawImage(float hx1, float hy1, float hx2, float hy2, const Image *image, tx2 += 0.2; ty1 += 0.2; ty2 += 0.2; - HUDCalcTurbulentTexCoords(&tx1, &ty1, x1, y1); - HUDCalcTurbulentTexCoords(&tx2, &ty2, x2, y2); + HUDCalcTurbulentTexCoords(&tx1, &ty1, hx1, hy1); + HUDCalcTurbulentTexCoords(&tx2, &ty2, hx2, hy2); alpha /= 2; - glEnable(GL_ALPHA_TEST); - - glColor4f(sgcol.r, sgcol.g, sgcol.b, alpha); - - glEnable(GL_BLEND); - glBegin(GL_QUADS); - glTexCoord2f(tx1, ty1); - glVertex2i(x1, y1); - - glTexCoord2f(tx2, ty1); - glVertex2i(x2, y1); - - glTexCoord2f(tx2, ty2); - glVertex2i(x2, y2); - - glTexCoord2f(tx1, ty2); - glVertex2i(x1, y2); - glEnd(); + blend = (BlendingMode)(blend|kBlendingMasked|kBlendingAlpha); + + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, tex_id, (GLuint)kTextureEnvironmentDisable, 0, 0, blend); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty1}}; + glvert++->position = {{hx1, hy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty1}}; + glvert++->position = {{hx2, hy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty2}}; + glvert++->position = {{hx2, hy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty2}}; + glvert->position = {{hx1, hy2, 0}}; + + EndRenderUnit(4); } + FinishUnitBatch(); + hud_swirl_pass = 0; hud_thick_liquid = false; - - if (old_s_clamp != kDummyClamp) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, old_s_clamp); - - if (old_t_clamp != kDummyClamp) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, old_t_clamp); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); - - glAlphaFunc(GL_GREATER, 0); } void HUDRawFromTexID(float hx1, float hy1, float hx2, float hy2, unsigned int tex_id, ImageOpacity opacity, float tx1, float ty1, float tx2, float ty2, float alpha) { - int x1 = RoundToInteger(hx1); - int y1 = RoundToInteger(hy1); - int x2 = RoundToInteger(hx2 + 0.25f); - int y2 = RoundToInteger(hy2 + 0.25f); + sg_color sgcol = sg_white; + sgcol.a = alpha; + BlendingMode blend = kBlendingNone; - if (x1 >= x2 || y1 >= y2) + if (hx1 >= hx2 || hy1 >= hy2) return; - if (x2 < 0 || x1 > current_screen_width || y2 < 0 || y1 > current_screen_height) + if (hx2 < 0 || hx1 > current_screen_width || hy2 < 0 || hy1 > current_screen_height) return; - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, tex_id); - if (alpha >= 0.99f && opacity == kOpacitySolid) - glDisable(GL_ALPHA_TEST); + blend = kBlendingNone; else { - glEnable(GL_ALPHA_TEST); - if (!(alpha < 0.11f || opacity == kOpacityComplex)) - glAlphaFunc(GL_GREATER, alpha * 0.66f); + blend = kBlendingLess; + else + blend = kBlendingMasked; } if (opacity == kOpacityComplex || alpha < 0.99f) - glEnable(GL_BLEND); - - glColor4f(1.0f, 1.0f, 1.0f, alpha); + blend = (BlendingMode(blend|kBlendingAlpha)); - glBegin(GL_QUADS); + StartUnitBatch(false); - glTexCoord2f(tx1, ty1); - glVertex2i(x1, y1); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, tex_id, (GLuint)kTextureEnvironmentDisable, 0, 0, blend); - glTexCoord2f(tx2, ty1); - glVertex2i(x2, y1); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty1}}; + glvert++->position = {{hx1, hy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty1}}; + glvert++->position = {{hx2, hy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty2}}; + glvert++->position = {{hx2, hy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty2}}; + glvert->position = {{hx1, hy2, 0}}; - glTexCoord2f(tx2, ty2); - glVertex2i(x2, y2); + EndRenderUnit(4); - glTexCoord2f(tx1, ty2); - glVertex2i(x1, y2); - - glEnd(); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); - - glAlphaFunc(GL_GREATER, 0); + FinishUnitBatch(); } void HUDStretchFromImageData(float x, float y, float w, float h, const ImageData *img, unsigned int tex_id, @@ -798,23 +772,26 @@ void HUDSolidBox(float x1, float y1, float x2, float y2, RGBAColor col) y2 = HUDToRealCoordinatesY(y2); } - if (current_alpha < 0.99f) - glEnable(GL_BLEND); - - sg_color sgcol = sg_make_color_1i(col); + StartUnitBatch(false); - glColor4f(sgcol.r, sgcol.g, sgcol.b, current_alpha); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, + 0, current_alpha < 0.99f ? kBlendingAlpha : kBlendingNone); - glBegin(GL_QUADS); + sg_color sgcol = sg_make_color_1i(col); + sgcol.a = current_alpha; - glVertex2f(x1, y1); - glVertex2f(x1, y2); - glVertex2f(x2, y2); - glVertex2f(x2, y1); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y1, 0}}; - glEnd(); + EndRenderUnit(4); - glDisable(GL_BLEND); + FinishUnitBatch(); } void HUDSolidLine(float x1, float y1, float x2, float y2, RGBAColor col, float thickness, bool smooth, float dx, @@ -828,31 +805,35 @@ void HUDSolidLine(float x1, float y1, float x2, float y2, RGBAColor col, float t dx = HUDToRealCoordinatesX(dx) - HUDToRealCoordinatesX(0); dy = HUDToRealCoordinatesY(0) - HUDToRealCoordinatesY(dy); - glLineWidth(thickness); + global_render_state->LineWidth(thickness); if (smooth) - glEnable(GL_LINE_SMOOTH); + global_render_state->Enable(GL_LINE_SMOOTH); - if (smooth || current_alpha < 0.99f) - glEnable(GL_BLEND); + StartUnitBatch(false); sg_color sgcol = sg_make_color_1i(col); + sgcol.a = current_alpha; + BlendingMode blend = kBlendingNone; - glColor4f(sgcol.r, sgcol.g, sgcol.b, current_alpha); + if (smooth || current_alpha < 0.99f) + blend= kBlendingAlpha; - glBegin(GL_LINES); + RendererVertex *glvert = BeginRenderUnit(GL_LINES, 2, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, blend); - glVertex2i((int)x1 + (int)dx, (int)y1 + (int)dy); - glVertex2i((int)x2 + (int)dx, (int)y2 + (int)dy); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1+dx, y1+dy, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x2+dx, y2+dy, 0}}; - glEnd(); + EndRenderUnit(2); - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); - glLineWidth(1.0f); + FinishUnitBatch(); + global_render_state->Disable(GL_LINE_SMOOTH); + global_render_state->LineWidth(1.0f); } -void HUDThinBox(float x1, float y1, float x2, float y2, RGBAColor col, float thickness) +void HUDThinBox(float x1, float y1, float x2, float y2, RGBAColor col, float thickness, BlendingMode special_blend) { std::swap(y1, y2); @@ -861,42 +842,70 @@ void HUDThinBox(float x1, float y1, float x2, float y2, RGBAColor col, float thi x2 = HUDToRealCoordinatesX(x2); y2 = HUDToRealCoordinatesY(y2); - if (current_alpha < 0.99f) - glEnable(GL_BLEND); - + StartUnitBatch(false); sg_color sgcol = sg_make_color_1i(col); + sgcol.a = current_alpha; + BlendingMode blend = kBlendingNone; - glColor4f(sgcol.r, sgcol.g, sgcol.b, current_alpha); - - glBegin(GL_QUADS); - glVertex2f(x1, y1); - glVertex2f(x1, y2); - glVertex2f(x1 + 2 + thickness, y2); - glVertex2f(x1 + 2 + thickness, y1); - glEnd(); - - glBegin(GL_QUADS); - glVertex2f(x2 - 2 - thickness, y1); - glVertex2f(x2 - 2 - thickness, y2); - glVertex2f(x2, y2); - glVertex2f(x2, y1); - glEnd(); - - glBegin(GL_QUADS); - glVertex2f(x1 + 2 + thickness, y1); - glVertex2f(x1 + 2 + thickness, y1 + 2 + thickness); - glVertex2f(x2 - 2 - thickness, y1 + 2 + thickness); - glVertex2f(x2 - 2 - thickness, y1); - glEnd(); - - glBegin(GL_QUADS); - glVertex2f(x1 + 2 + thickness, y2 - 2 - thickness); - glVertex2f(x1 + 2 + thickness, y2); - glVertex2f(x2 - 2 - thickness, y2); - glVertex2f(x2 - 2 - thickness, y2 - 2 - thickness); - glEnd(); - - glDisable(GL_BLEND); + if (current_alpha < 0.99f) + blend = kBlendingAlpha; + + if (special_blend != kBlendingNone) + blend = special_blend; + + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, blend); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1 + 2 + thickness, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x1 + 2 + thickness, y1, 0}}; + + EndRenderUnit(4); + + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, blend); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2 - 2 - thickness, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2 - 2 - thickness, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x2, y1, 0}}; + + EndRenderUnit(4); + + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, blend); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1 + 2 + thickness, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1 + 2 + thickness, y1 + 2 + thickness, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2 - 2 - thickness, y1 + 2 + thickness, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x2 - 2 - thickness, y1, 0}}; + + EndRenderUnit(4); + + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, blend); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1 + 2 + thickness, y2 - 2 - thickness, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1 + 2 + thickness, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2 - 2 - thickness, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x2 - 2 - thickness, y2 - 2 - thickness, 0}}; + + EndRenderUnit(4); + + FinishUnitBatch(); } void HUDGradientBox(float x1, float y1, float x2, float y2, RGBAColor *cols) @@ -908,30 +917,38 @@ void HUDGradientBox(float x1, float y1, float x2, float y2, RGBAColor *cols) x2 = HUDToRealCoordinatesX(x2); y2 = HUDToRealCoordinatesY(y2); - if (current_alpha < 0.99f) - glEnable(GL_BLEND); + StartUnitBatch(false); + BlendingMode blend = kBlendingNone; - glBegin(GL_QUADS); + if (current_alpha < 0.99f) + blend = kBlendingAlpha; sg_color sgcol = sg_make_color_1i(cols[1]); - glColor4f(sgcol.r, sgcol.g, sgcol.b, current_alpha); - glVertex2f(x1, y1); + sgcol.a = current_alpha; + + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, blend); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y1, 0}}; sgcol = sg_make_color_1i(cols[0]); - glColor4f(sgcol.r, sgcol.g, sgcol.b, current_alpha); - glVertex2f(x1, y2); + sgcol.a = current_alpha; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y2, 0}}; sgcol = sg_make_color_1i(cols[2]); - glColor4f(sgcol.r, sgcol.g, sgcol.b, current_alpha); - glVertex2f(x2, y2); + sgcol.a = current_alpha; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y2, 0}}; sgcol = sg_make_color_1i(cols[3]); - glColor4f(sgcol.r, sgcol.g, sgcol.b, current_alpha); - glVertex2f(x2, y1); + sgcol.a = current_alpha; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y1, 0}}; - glEnd(); + EndRenderUnit(4); - glDisable(GL_BLEND); + FinishUnitBatch(); } float HUDFontWidth(void) @@ -1130,64 +1147,54 @@ void HUDDrawEndoomChar(float left_x, float top_y, float FNX, const Image *img, c sg_color sgcol = sg_make_color_1i(color2); - glDisable(GL_TEXTURE_2D); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNone); - glColor4f(sgcol.r, sgcol.g, sgcol.b, current_alpha); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{left_x, top_y, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{left_x, top_y + h, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{left_x + w, top_y + h, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{left_x + w, top_y, 0}}; - glBegin(GL_QUADS); - - glVertex2f(left_x, top_y); - - glVertex2f(left_x, top_y + h); - - glVertex2f(left_x + w, top_y + h); - - glVertex2f(left_x + w, top_y); - - glEnd(); + EndRenderUnit(4); sgcol = sg_make_color_1i(color1); - glEnable(GL_TEXTURE_2D); - GLuint tex_id = ImageCache(img, true, (const Colormap *)0, true); - glBindTexture(GL_TEXTURE_2D, tex_id); + BlendingMode blend = kBlendingNone; if (img->opacity_ == kOpacitySolid) - glDisable(GL_ALPHA_TEST); + blend = kBlendingNone; else { - glEnable(GL_ALPHA_TEST); - if (img->opacity_ != kOpacityComplex) - glAlphaFunc(GL_GREATER, 0.66f); + blend = kBlendingLess; + else + blend = kBlendingAlpha; } - glColor4f(sgcol.r, sgcol.g, sgcol.b, current_alpha); - - glBegin(GL_QUADS); + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, tex_id, (GLuint)kTextureEnvironmentDisable, 0, 0, blend); float width_adjust = FNX / 2 + .5; - glTexCoord2f(tx1, ty1); - glVertex2f(left_x - width_adjust, top_y); - - glTexCoord2f(tx2, ty1); - glVertex2f(left_x + w + width_adjust, top_y); - - glTexCoord2f(tx2, ty2); - glVertex2f(left_x + w + width_adjust, top_y + h); - - glTexCoord2f(tx1, ty2); - glVertex2f(left_x - width_adjust, top_y + h); - - glEnd(); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); - - glAlphaFunc(GL_GREATER, 0); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty1}}; + glvert++->position = {{left_x - width_adjust, top_y, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty1}}; + glvert++->position = {{left_x + w + width_adjust, top_y, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty2}}; + glvert++->position = {{left_x + w + width_adjust, top_y + h, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty2}}; + glvert->position = {{left_x - width_adjust, top_y + h, 0}}; + + EndRenderUnit(4); + + FinishUnitBatch(); } // diff --git a/source_files/edge/hu_draw.h b/source_files/edge/hu_draw.h index d374c1b41..3789dc2d6 100644 --- a/source_files/edge/hu_draw.h +++ b/source_files/edge/hu_draw.h @@ -26,6 +26,7 @@ #pragma once #include "hu_font.h" +#include "r_units.h" // X coordinates of left and right edges of screen. // updated by calls to HUDSetCoordinateSystem() or HUDReset(). @@ -75,7 +76,7 @@ void HUDSolidLine(float x1, float y1, float x2, float y2, RGBAColor col, float t float dx = 0, float dy = 0); // Draw a thin outline of a box. -void HUDThinBox(float x1, float y1, float x2, float y2, RGBAColor col, float thickness = 0.0f); +void HUDThinBox(float x1, float y1, float x2, float y2, RGBAColor col, float thickness = 0.0f, BlendingMode special_blend = kBlendingNone); // Like HUDSolidBox but the colors of each corner (TL, BL, TR, BR) can // be specified individually. diff --git a/source_files/edge/hu_font.cc b/source_files/edge/hu_font.cc index 07b539629..39113dc76 100644 --- a/source_files/edge/hu_font.cc +++ b/source_files/edge/hu_font.cc @@ -211,30 +211,30 @@ void Font::LoadPatches() SavePNG(atlas_png, atlas->data);*/ patch_font_cache_.atlas_rectangles = atlas->rectangles_; glGenTextures(1, &patch_font_cache_.atlas_texture_id); - glBindTexture(GL_TEXTURE_2D, patch_font_cache_.atlas_texture_id); + global_render_state->BindTexture(patch_font_cache_.atlas_texture_id); + global_render_state->TextureMinFilter(GL_NEAREST); + global_render_state->TextureMagFilter(GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, atlas->data_->width_, atlas->data_->height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, atlas->data_->pixels_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glGenTextures(1, &patch_font_cache_.atlas_smoothed_texture_id); - glBindTexture(GL_TEXTURE_2D, patch_font_cache_.atlas_smoothed_texture_id); + global_render_state->BindTexture(patch_font_cache_.atlas_smoothed_texture_id); + global_render_state->TextureMinFilter(GL_LINEAR); + global_render_state->TextureMagFilter(GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, atlas->data_->width_, atlas->data_->height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, atlas->data_->pixels_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); atlas->data_->Whiten(); glGenTextures(1, &patch_font_cache_.atlas_whitened_texture_id); - glBindTexture(GL_TEXTURE_2D, patch_font_cache_.atlas_whitened_texture_id); + global_render_state->BindTexture(patch_font_cache_.atlas_whitened_texture_id); + global_render_state->TextureMinFilter(GL_NEAREST); + global_render_state->TextureMagFilter(GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, atlas->data_->width_, atlas->data_->height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, atlas->data_->pixels_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glGenTextures(1, &patch_font_cache_.atlas_whitened_smoothed_texture_id); - glBindTexture(GL_TEXTURE_2D, patch_font_cache_.atlas_whitened_smoothed_texture_id); + global_render_state->BindTexture(patch_font_cache_.atlas_whitened_smoothed_texture_id); + global_render_state->TextureMinFilter(GL_LINEAR); + global_render_state->TextureMagFilter(GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, atlas->data_->width_, atlas->data_->height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, atlas->data_->pixels_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); delete atlas; } else @@ -422,17 +422,17 @@ void Font::LoadFontTTF() stbtt_PackFontRanges(spc, truetype_buffer_, 0, truetype_atlas_[i], 1); stbtt_PackEnd(spc); glGenTextures(1, &truetype_texture_id_[i]); - glBindTexture(GL_TEXTURE_2D, truetype_texture_id_[i]); + global_render_state->BindTexture(truetype_texture_id_[i]); + global_render_state->TextureMinFilter(GL_NEAREST); + global_render_state->TextureMagFilter(GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, truetype_scaling_bitmap_sizes[i], truetype_scaling_bitmap_sizes[i], 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glGenTextures(1, &truetype_smoothed_texture_id_[i]); - glBindTexture(GL_TEXTURE_2D, truetype_smoothed_texture_id_[i]); + global_render_state->BindTexture(truetype_smoothed_texture_id_[i]); + global_render_state->TextureMinFilter(GL_LINEAR); + global_render_state->TextureMagFilter(GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, truetype_scaling_bitmap_sizes[i], truetype_scaling_bitmap_sizes[i], 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); delete[] temp_bitmap; float x = 0.0f; float y = 0.0f; diff --git a/source_files/edge/hu_stuff.cc b/source_files/edge/hu_stuff.cc index 6b69592db..9e69936a2 100644 --- a/source_files/edge/hu_stuff.cc +++ b/source_files/edge/hu_stuff.cc @@ -224,8 +224,6 @@ void HUDDrawer(void) HUDSetAlignment(); HUDSetAlpha(); } - - // TODO: chat messages } // Starts displaying the message. diff --git a/source_files/edge/i_movie.cc b/source_files/edge/i_movie.cc index f1a0901c4..6fb2cf9de 100644 --- a/source_files/edge/i_movie.cc +++ b/source_files/edge/i_movie.cc @@ -26,6 +26,7 @@ #include "r_gldefs.h" #include "r_modes.h" #include "r_state.h" +#include "r_units.h" #include "r_wipe.h" #include "s_blit.h" #include "s_music.h" @@ -47,10 +48,10 @@ static uint8_t *movie_bytes = nullptr; static double fadein = 0; static double fadeout = 0; static double elapsed_time = 0; -static int vx1 = 0; -static int vx2 = 0; -static int vy1 = 0; -static int vy2 = 0; +static float vx1 = 0.0f; +static float vx2 = 0.0f; +static float vy1 = 0.0f; +static float vy2 = 0.0f; static float tx1 = 0.0f; static float tx2 = 1.0f; static float ty1 = 0.0f; @@ -88,7 +89,7 @@ void MovieVideoCallback(plm_t *mpeg, plm_frame_t *frame, void *user) (void)user; plm_frame_to_rgb(frame, rgb_data, frame->width * 3); - glBindTexture(GL_TEXTURE_2D, canvas); + global_render_state->BindTexture(canvas); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, frame->width, frame->height, 0, GL_RGB, GL_UNSIGNED_BYTE, rgb_data); } @@ -157,9 +158,12 @@ void PlayMovie(const std::string &name) } if (canvas) - glDeleteTextures(1, &canvas); + global_render_state->DeleteTexture(&canvas); glGenTextures(1, &canvas); + global_render_state->BindTexture(canvas); + global_render_state->TextureMagFilter(GL_LINEAR); + global_render_state->TextureMinFilter(GL_LINEAR); if (rgb_data) { @@ -247,7 +251,7 @@ static void EndMovie() } if (canvas) { - glDeleteTextures(1, &canvas); + global_render_state->DeleteTexture(&canvas); canvas = 0; } ResumeMusic(); @@ -257,55 +261,52 @@ void MovieDrawer() { if (!playing_movie) return; + if (!plm_has_ended(decoder)) { - SetupMatrices2D(); - - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, canvas); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glDisable(GL_ALPHA_TEST); - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - - glBegin(GL_QUADS); - - glTexCoord2f(tx1, ty2); - glVertex2i(vx1, vy2); - - glTexCoord2f(tx2, ty2); - glVertex2i(vx2, vy2); + StartUnitBatch (false); - glTexCoord2f(tx2, ty1); - glVertex2i(vx2, vy1); + sg_color sgcol = sg_white; - glTexCoord2f(tx1, ty1); - glVertex2i(vx1, vy1); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, canvas, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNone); - glEnd(); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty2}}; + glvert++->position = {{vx1, vy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty2}}; + glvert++->position = {{vx2, vy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty1}}; + glvert++->position = {{vx2, vy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty1}}; + glvert->position = {{vx1, vy1, 0}}; - glDisable(GL_TEXTURE_2D); + EndRenderUnit(4); // Fade-in fadein = plm_get_time(decoder); if (fadein <= 0.25f) { - glColor4f(0, 0, 0, (0.25f - fadein) / 0.25f); - glEnable(GL_BLEND); - - glBegin(GL_QUADS); - - glVertex2i(vx1, vy2); - glVertex2i(vx2, vy2); - glVertex2i(vx2, vy1); - glVertex2i(vx1, vy1); - - glEnd(); - - glDisable(GL_BLEND); + sgcol = { 0, 0, 0, (0.25f - (float)fadein) / 0.25f }; + + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingAlpha); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{vx1, vy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{vx2, vy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{vx2, vy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{vx1, vy1, 0}}; + + EndRenderUnit(4); } + FinishUnitBatch(); + if (skip_bar_active) { // Draw black box at bottom of screen @@ -314,58 +315,50 @@ void MovieDrawer() // Draw progress HUDSolidBox(hud_x_left, 197, hud_x_right * (skip_time / 0.9f), 199, SG_WHITE_RGBA32); } - - GetRenderState()->SetDefaultStateFull(); } else { - SetupMatrices2D(); - double current_time = (double)SDL_GetTicks() / 1000.0; fadeout = current_time - last_time; - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, canvas); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glDisable(GL_ALPHA_TEST); - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - - glBegin(GL_QUADS); - - glTexCoord2f(tx1, ty2); - glVertex2i(vx1, vy2); - - glTexCoord2f(tx2, ty2); - glVertex2i(vx2, vy2); + StartUnitBatch(false); - glTexCoord2f(tx2, ty1); - glVertex2i(vx2, vy1); + sg_color sgcol = sg_white; - glTexCoord2f(tx1, ty1); - glVertex2i(vx1, vy1); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, canvas, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNone); - glEnd(); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty2}}; + glvert++->position = {{vx1, vy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty2}}; + glvert++->position = {{vx2, vy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx2, ty1}}; + glvert++->position = {{vx2, vy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx1, ty1}}; + glvert->position = {{vx1, vy1, 0}}; - glDisable(GL_TEXTURE_2D); + EndRenderUnit(4); // Fade-out - glColor4f(0, 0, 0, HMM_MAX(0.0f, 1.0f - ((0.25f - fadeout) / 0.25f))); - glEnable(GL_BLEND); - - glBegin(GL_QUADS); - - glVertex2i(vx1, vy2); - glVertex2i(vx2, vy2); - glVertex2i(vx2, vy1); - glVertex2i(vx1, vy1); - - glEnd(); - - glDisable(GL_BLEND); - - GetRenderState()->SetDefaultStateFull(); + sgcol = { 0, 0, 0, HMM_MAX(0.0f, 1.0f - ((0.25f - (float)fadeout) / 0.25f)) }; + + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingAlpha); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{vx1, vy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{vx2, vy2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{vx2, vy1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{vx1, vy1, 0}}; + + EndRenderUnit(4); + + FinishUnitBatch(); } } diff --git a/source_files/edge/i_video.cc b/source_files/edge/i_video.cc index edd594a2b..016b8cfa1 100644 --- a/source_files/edge/i_video.cc +++ b/source_files/edge/i_video.cc @@ -29,6 +29,7 @@ #include "m_misc.h" #include "n_network.h" #include "r_modes.h" +#include "r_state.h" #include "version.h" SDL_Window *program_window; @@ -385,7 +386,7 @@ bool SetScreenSize(DisplayMode *mode) signal(SIGSEGV, SIG_DFL); #endif - glClearColor(0, 0, 0, 1.0f); + global_render_state->ClearColor(0, 0, 0, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_GL_SwapWindow(program_window); @@ -396,7 +397,7 @@ bool SetScreenSize(DisplayMode *mode) void StartFrame(void) { ec_frame_stats.Clear(); - glClearColor(0, 0, 0, 1.0f); + global_render_state->ClearColor(0, 0, 0, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (draw_culling.d_) renderer_far_clip.f_ = draw_culling_distance.f_; diff --git a/source_files/edge/m_menu.cc b/source_files/edge/m_menu.cc index 6ac7e4e37..68c9a4cea 100644 --- a/source_files/edge/m_menu.cc +++ b/source_files/edge/m_menu.cc @@ -532,7 +532,7 @@ void MenuReadSaveStrings(void) delete save_extended_information_slots[i].save_image_data; save_extended_information_slots[i].save_image_data = nullptr; if (save_extended_information_slots[i].save_texture_id) - glDeleteTextures(1, &save_extended_information_slots[i].save_texture_id); + global_render_state->DeleteTexture(&save_extended_information_slots[i].save_texture_id); save_extended_information_slots[i].save_texture_id = 0; save_extended_information_slots[i].save_image_page = save_page; epi::FileDelete(fn); @@ -546,7 +546,7 @@ void MenuReadSaveStrings(void) { delete save_extended_information_slots[i].save_image_data; if (save_extended_information_slots[i].save_texture_id) - glDeleteTextures(1, &save_extended_information_slots[i].save_texture_id); + global_render_state->DeleteTexture(&save_extended_information_slots[i].save_texture_id); epi::File *svimg_file = epi::FileOpen(fn, epi::kFileAccessRead | epi::kFileAccessBinary); if (svimg_file) { diff --git a/source_files/edge/p_maputl.cc b/source_files/edge/p_maputl.cc index d212857bb..56272c5c4 100644 --- a/source_files/edge/p_maputl.cc +++ b/source_files/edge/p_maputl.cc @@ -31,8 +31,6 @@ // Gap/extrafloor utility functions. // Touch Node code. // -// TODO HERE: -// + make gap routines FatalError if overflow limit. // #include diff --git a/source_files/edge/r_colormap.cc b/source_files/edge/r_colormap.cc index d7fe76ed9..00dbf36e1 100644 --- a/source_files/edge/r_colormap.cc +++ b/source_files/edge/r_colormap.cc @@ -767,7 +767,7 @@ class ColormapShader : public AbstractShader { if (fade_texture_ != 0) { - glDeleteTextures(1, &fade_texture_); + global_render_state->DeleteTexture(&fade_texture_); } if (force_flat_lighting.d_) @@ -783,7 +783,7 @@ class ColormapShader : public AbstractShader { if (fade_texture_ != 0) { - glDeleteTextures(1, &fade_texture_); + global_render_state->DeleteTexture(&fade_texture_); fade_texture_ = 0; } } diff --git a/source_files/edge/r_draw.cc b/source_files/edge/r_draw.cc index 79e0cd744..eb86d482c 100644 --- a/source_files/edge/r_draw.cc +++ b/source_files/edge/r_draw.cc @@ -37,70 +37,10 @@ void NewScreenSize(int width, int height, int bits) SetupMatrices2D(); // prevent a visible border with certain cards/drivers - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + global_render_state->ClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); } -void RenderImage(float x, float y, float w, float h, const Image *image, float tx1, float ty1, float tx2, float ty2, - const Colormap *textmap, float alpha, const Colormap *palremap) -{ - int x1 = RoundToInteger(x); - int y1 = RoundToInteger(y); - int x2 = RoundToInteger(x + w + 0.25f); - int y2 = RoundToInteger(y + h + 0.25f); - - if (x1 == x2 || y1 == y2) - return; - - sg_color sgcol = sg_white; - - GLuint tex_id = ImageCache(image, true, (textmap && (textmap->special_ & kColorSpecialWhiten)) ? nullptr : palremap, - (textmap && (textmap->special_ & kColorSpecialWhiten)) ? true : false); - - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, tex_id); - - if (alpha >= 0.99f && image->opacity_ == kOpacitySolid) - glDisable(GL_ALPHA_TEST); - else - { - glEnable(GL_ALPHA_TEST); - - if (!(alpha < 0.11f || image->opacity_ == kOpacityComplex)) - glAlphaFunc(GL_GREATER, alpha * 0.66f); - } - - if (image->opacity_ == kOpacityComplex || alpha < 0.99f) - glEnable(GL_BLEND); - - if (textmap) - sgcol = sg_make_color_1i(GetFontColor(textmap)); - - glColor4f(sgcol.r, sgcol.g, sgcol.b, alpha); - - glBegin(GL_QUADS); - - glTexCoord2f(tx1, ty1); - glVertex2i(x1, y1); - - glTexCoord2f(tx2, ty1); - glVertex2i(x2, y1); - - glTexCoord2f(tx2, ty2); - glVertex2i(x2, y2); - - glTexCoord2f(tx1, ty2); - glVertex2i(x1, y2); - - glEnd(); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); - - glAlphaFunc(GL_GREATER, 0); -} - void ReadScreen(int x, int y, int w, int h, uint8_t *rgb_buffer) { glFlush(); diff --git a/source_files/edge/r_draw.h b/source_files/edge/r_draw.h index db0a906ce..9e8dfb064 100644 --- a/source_files/edge/r_draw.h +++ b/source_files/edge/r_draw.h @@ -27,10 +27,6 @@ #include "r_image.h" -// Move to somewhere appropriate later -ACB- 2004/08/19 -void RenderImage(float x, float y, float w, float h, const Image *image, float tx1, float ty1, float tx2, float ty2, - const Colormap *textmap = nullptr, float alpha = 1.0f, const Colormap *palremap = nullptr); - void ReadScreen(int x, int y, int w, int h, uint8_t *rgb_buffer); // This routine should inform the lower level system(s) that the diff --git a/source_files/edge/r_effects.cc b/source_files/edge/r_effects.cc index 9e3a1c412..dc7cbdec1 100644 --- a/source_files/edge/r_effects.cc +++ b/source_files/edge/r_effects.cc @@ -28,13 +28,14 @@ #include "r_misc.h" #include "r_modes.h" #include "r_texgl.h" +#include "r_units.h" #include "w_wad.h" int render_view_extra_light; -float render_view_red_multiplier; -float render_view_green_multiplier; -float render_view_blue_multiplier; +float render_view_red_multiplier = 1.0f; +float render_view_green_multiplier = 1.0f; +float render_view_blue_multiplier = 1.0f; const Colormap *render_view_effect_colormap; @@ -82,9 +83,6 @@ void RendererRainbowEffect(Player *player) else { render_view_red_multiplier = 0.90f; - ///??? render_view_red_multiplier += (1.0f - - /// render_view_red_multiplier) * (1.0f - s); - render_view_green_multiplier = render_view_red_multiplier; render_view_blue_multiplier = render_view_red_multiplier; } @@ -153,8 +151,8 @@ void RendererRainbowEffect(Player *player) // void RendererColourmapEffect(Player *player) { - int x1, y1; - int x2, y2; + float x1, y1; + float x2, y2; float s = EffectStrength(player); @@ -164,15 +162,13 @@ void RendererColourmapEffect(Player *player) if (invulnerability_effect == kInvulnerabilityTextured && !reduce_flash) return; - glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); - if (!reduce_flash) { - glColor4f(1.0f, 1.0f, 1.0f, 0.0f); + StartUnitBatch(false); - glEnable(GL_BLEND); + sg_color sgcol = sg_white; - glBegin(GL_QUADS); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingInvert); x1 = view_window_x; x2 = view_window_x + view_window_width; @@ -180,14 +176,18 @@ void RendererColourmapEffect(Player *player) y1 = view_window_y + view_window_height; y2 = view_window_y; - glVertex2i(x1, y1); - glVertex2i(x2, y1); - glVertex2i(x2, y2); - glVertex2i(x1, y2); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y1, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y2, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x1, y2, 0}}; - glEnd(); + EndRenderUnit(4); - glDisable(GL_BLEND); + FinishUnitBatch(); } else { @@ -195,10 +195,9 @@ void RendererColourmapEffect(Player *player) HUDSetAlpha(0.0f); s = HMM_MAX(0.5f, s); HUDThinBox(hud_x_left, hud_visible_top, hud_x_right, hud_visible_bottom, - epi::MakeRGBA(RoundToInteger(s * 255), RoundToInteger(s * 255), RoundToInteger(s * 255)), 25.0f); + epi::MakeRGBA(RoundToInteger(s * 255), RoundToInteger(s * 255), RoundToInteger(s * 255)), 25.0f, kBlendingInvert); HUDSetAlpha(old_alpha); } - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } } @@ -215,6 +214,8 @@ void RendererPaletteEffect(Player *player) float old_alpha = HUDGetAlpha(); + sg_color sgcol = sg_white; + if (s > 0 && player->powers_[kPowerTypeInvulnerable] > 0 && player->effect_colourmap_ && (player->effect_left_ & 8 || reduce_flash)) { @@ -225,7 +226,7 @@ void RendererPaletteEffect(Player *player) float r, g, b; GetColormapRGB(player->effect_colourmap_, &r, &g, &b); if (!reduce_flash) - glColor4f(r, g, b, 0.20f * s); + sgcol = { r, g, b, 0.20f * s }; else { HUDSetAlpha(0.20f * s); @@ -245,8 +246,8 @@ void RendererPaletteEffect(Player *player) rgb_max = HMM_MIN(200, rgb_max); if (!reduce_flash) - glColor4f((float)rgb_data[0] / (float)rgb_max, (float)rgb_data[1] / (float)rgb_max, - (float)rgb_data[2] / (float)rgb_max, (float)rgb_max / 255.0f); + sgcol = { (float)rgb_data[0] / (float)rgb_max, (float)rgb_data[1] / (float)rgb_max, + (float)rgb_data[2] / (float)rgb_max, (float)rgb_max / 255.0f }; else { HUDSetAlpha((float)rgb_max / 255.0f); @@ -262,18 +263,22 @@ void RendererPaletteEffect(Player *player) if (!reduce_flash) { - glEnable(GL_BLEND); + StartUnitBatch(false); - glBegin(GL_QUADS); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingAlpha); - glVertex2i(0, current_screen_height); - glVertex2i(current_screen_width, current_screen_height); - glVertex2i(current_screen_width, 0); - glVertex2i(0, 0); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{0, (float)current_screen_height, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{(float)current_screen_width, (float)current_screen_height, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{(float)current_screen_width, 0, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{0, 0, 0}}; - glEnd(); + EndRenderUnit(4); - glDisable(GL_BLEND); + FinishUnitBatch(); } } diff --git a/source_files/edge/r_image.cc b/source_files/edge/r_image.cc index b00ffe673..d167993a0 100644 --- a/source_files/edge/r_image.cc +++ b/source_files/edge/r_image.cc @@ -1769,7 +1769,7 @@ static CachedImage *ImageCacheOGL(Image *rim, const Colormap *trans, bool do_whi { if (rc->texture_id != 0) { - glDeleteTextures(1, &rc->texture_id); + global_render_state->DeleteTexture(&rc->texture_id); rc->texture_id = 0; } } @@ -1904,7 +1904,7 @@ void DeleteAllImages(void) if (rc->texture_id != 0) { - glDeleteTextures(1, &rc->texture_id); + global_render_state->DeleteTexture(&rc->texture_id); rc->texture_id = 0; } } diff --git a/source_files/edge/r_main.cc b/source_files/edge/r_main.cc index a66cb4c71..c2a417941 100644 --- a/source_files/edge/r_main.cc +++ b/source_files/edge/r_main.cc @@ -56,8 +56,6 @@ void SetupMatrices2D(void) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // @@ -81,8 +79,6 @@ void SetupWorldMatrices2D(void) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } // @@ -148,32 +144,32 @@ void RendererCheckExtensions(void) // void RendererSoftInit(void) { - glDisable(GL_BLEND); - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_STENCIL_TEST); + global_render_state->Disable(GL_BLEND); + global_render_state->Disable(GL_LIGHTING); + global_render_state->Disable(GL_COLOR_MATERIAL); + global_render_state->Disable(GL_CULL_FACE); + global_render_state->Disable(GL_DEPTH_TEST); + global_render_state->Disable(GL_SCISSOR_TEST); + global_render_state->Disable(GL_STENCIL_TEST); - glDisable(GL_LINE_SMOOTH); + global_render_state->Disable(GL_LINE_SMOOTH); #ifndef EDGE_GL_ES2 - glDisable(GL_POLYGON_SMOOTH); + global_render_state->Disable(GL_POLYGON_SMOOTH); #endif - glEnable(GL_NORMALIZE); + global_render_state->Enable(GL_NORMALIZE); glShadeModel(GL_SMOOTH); - glDepthFunc(GL_LEQUAL); - glAlphaFunc(GL_GREATER, 0); + global_render_state->DepthFunction(GL_LEQUAL); + global_render_state->AlphaFunction(GL_GREATER, 0); glFrontFace(GL_CW); - glCullFace(GL_BACK); - glDisable(GL_CULL_FACE); + global_render_state->CullFace(GL_BACK); + global_render_state->Disable(GL_CULL_FACE); - glHint(GL_FOG_HINT, GL_NICEST); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + global_render_state->Hint(GL_FOG_HINT, GL_NICEST); + global_render_state->Hint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); } // diff --git a/source_files/edge/r_md2.cc b/source_files/edge/r_md2.cc index b22b42f7e..2c403d910 100644 --- a/source_files/edge/r_md2.cc +++ b/source_files/edge/r_md2.cc @@ -27,6 +27,7 @@ #include +#include #include #include "ddf_types.h" @@ -50,6 +51,10 @@ #include "r_state.h" #include "r_units.h" +// clamp cache used by runits to avoid an extremely expensive gl tex param +// lookup +extern std::unordered_map texture_clamp_t; + extern float ApproximateDistance(float dx, float dy, float dz); extern ConsoleVariable draw_culling; @@ -981,20 +986,16 @@ static inline void ModelCoordFunc(MD2CoordinateData *data, int v_idx, HMM_Vec3 * if (!data->is_additive_) { - rgb[0] = col->modulate_red_ / 255.0; - rgb[1] = col->modulate_green_ / 255.0; - rgb[2] = col->modulate_blue_ / 255.0; + rgb[0] = col->modulate_red_ / 255.0 * render_view_red_multiplier; + rgb[1] = col->modulate_green_ / 255.0 * render_view_green_multiplier; + rgb[2] = col->modulate_blue_ / 255.0 * render_view_blue_multiplier; } else { - rgb[0] = col->add_red_ / 255.0; - rgb[1] = col->add_green_ / 255.0; - rgb[2] = col->add_blue_ / 255.0; + rgb[0] = col->add_red_ / 255.0 * render_view_red_multiplier; + rgb[1] = col->add_green_ / 255.0 * render_view_green_multiplier; + rgb[2] = col->add_blue_ / 255.0 * render_view_blue_multiplier; } - - rgb[0] *= render_view_red_multiplier; - rgb[1] *= render_view_green_multiplier; - rgb[2] *= render_view_blue_multiplier; } void MD2RenderModel(MD2Model *md, const Image *skin_img, bool is_weapon, int frame1, int frame2, float lerp, float x, @@ -1179,11 +1180,11 @@ void MD2RenderModel(MD2Model *md, const Image *skin_img, bool is_weapon, int fra fc[1] = (float)epi::GetRGBAGreen(fc_to_use) / 255.0f; fc[2] = (float)epi::GetRGBABlue(fc_to_use) / 255.0f; fc[3] = 1.0f; - glClearColor(fc[0], fc[1], fc[2], 1.0f); - glFogi(GL_FOG_MODE, GL_EXP); - glFogfv(GL_FOG_COLOR, fc); - glFogf(GL_FOG_DENSITY, std::log1p(fd_to_use)); - glEnable(GL_FOG); + global_render_state->ClearColor(fc[0], fc[1], fc[2], 1.0f); + global_render_state->FogColor(fc[0], fc[1], fc[2], fc[3]); + global_render_state->FogMode(GL_EXP); + global_render_state->FogDensity(std::log1p(fd_to_use)); + global_render_state->Enable(GL_FOG); } else if (draw_culling.d_) { @@ -1214,15 +1215,15 @@ void MD2RenderModel(MD2Model *md, const Image *skin_img, bool is_weapon, int fra { fogColor = sg_black; } - glClearColor(fogColor.r, fogColor.g, fogColor.b, 1.0f); - glFogi(GL_FOG_MODE, GL_LINEAR); - glFogfv(GL_FOG_COLOR, &fogColor.r); - glFogf(GL_FOG_START, renderer_far_clip.f_ - 750.0f); - glFogf(GL_FOG_END, renderer_far_clip.f_ - 250.0f); - glEnable(GL_FOG); + global_render_state->ClearColor(fogColor.r, fogColor.g, fogColor.b, 1.0f); + global_render_state->FogMode(GL_LINEAR); + global_render_state->FogColor(fogColor.r, fogColor.g, fogColor.b, fogColor.a); + global_render_state->FogStart(renderer_far_clip.f_ - 750.0f); + global_render_state->FogEnd(renderer_far_clip.f_ - 250.0f); + global_render_state->Enable(GL_FOG); } else - glDisable(GL_FOG); + global_render_state->Disable(GL_FOG); for (int pass = 0; pass < num_pass; pass++) { @@ -1230,7 +1231,7 @@ void MD2RenderModel(MD2Model *md, const Image *skin_img, bool is_weapon, int fra { blending &= ~kBlendingAlpha; blending |= kBlendingAdd; - glDisable(GL_FOG); + global_render_state->Disable(GL_FOG); } data.is_additive_ = (pass > 0 && pass == num_pass - 1); @@ -1247,87 +1248,91 @@ void MD2RenderModel(MD2Model *md, const Image *skin_img, bool is_weapon, int fra continue; } - glPolygonOffset(0, -pass); + global_render_state->PolygonOffset(0, -pass); if (blending & (kBlendingMasked | kBlendingLess)) { if (blending & kBlendingLess) { - glEnable(GL_ALPHA_TEST); + global_render_state->Enable(GL_ALPHA_TEST); } else if (blending & kBlendingMasked) { - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0); + global_render_state->Enable(GL_ALPHA_TEST); + global_render_state->AlphaFunction(GL_GREATER, 0); } - else - glDisable(GL_ALPHA_TEST); } + else + global_render_state->Disable(GL_ALPHA_TEST); if (blending & (kBlendingAlpha | kBlendingAdd)) { if (blending & kBlendingAdd) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + global_render_state->Enable(GL_BLEND); + global_render_state->BlendFunction(GL_SRC_ALPHA, GL_ONE); } else if (blending & kBlendingAlpha) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + global_render_state->Enable(GL_BLEND); + global_render_state->BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - else - glDisable(GL_BLEND); } + else + global_render_state->Disable(GL_BLEND); if (blending & (kBlendingCullBack | kBlendingCullFront)) { if (blending & (kBlendingCullBack | kBlendingCullFront)) { - glEnable(GL_CULL_FACE); - glCullFace((blending & kBlendingCullFront) ? GL_FRONT : GL_BACK); + global_render_state->Enable(GL_CULL_FACE); + global_render_state->CullFace((blending & kBlendingCullFront) ? GL_FRONT : GL_BACK); } - else - glDisable(GL_CULL_FACE); } + else + global_render_state->Disable(GL_CULL_FACE); if (blending & kBlendingNoZBuffer) { - glDepthMask((blending & kBlendingNoZBuffer) ? GL_FALSE : GL_TRUE); + global_render_state->DepthMask((blending & kBlendingNoZBuffer) ? GL_FALSE : GL_TRUE); } if (blending & kBlendingLess) { // NOTE: assumes alpha is constant over whole model - glAlphaFunc(GL_GREATER, trans * 0.66f); + global_render_state->AlphaFunction(GL_GREATER, trans * 0.66f); } - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, skin_tex); + global_render_state->ActiveTexture(GL_TEXTURE1); + global_render_state->Disable(GL_TEXTURE_2D); + global_render_state->ActiveTexture(GL_TEXTURE0); + global_render_state->Enable(GL_TEXTURE_2D); + global_render_state->BindTexture(skin_tex); if (data.is_additive_) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); + global_render_state->TextureEnvironmentMode(GL_COMBINE); + global_render_state->TextureEnvironmentCombineRGB(GL_REPLACE); + global_render_state->TextureEnvironmentSource0RGB(GL_PREVIOUS); } else { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); + global_render_state->TextureEnvironmentMode(GL_MODULATE); + global_render_state->TextureEnvironmentCombineRGB(GL_MODULATE); + global_render_state->TextureEnvironmentSource0RGB(GL_TEXTURE); } - GLint old_clamp = 789; + GLint old_clamp = kDummyClamp; if (blending & kBlendingClampY) { - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, &old_clamp); + auto existing = texture_clamp_t.find(skin_tex); + if (existing != texture_clamp_t.end()) + { + old_clamp = existing->second; + } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, renderer_dumb_clamp.d_ ? GL_CLAMP : GL_CLAMP_TO_EDGE); + global_render_state->TextureWrapT(renderer_dumb_clamp.d_ ? GL_CLAMP : GL_CLAMP_TO_EDGE); } RendererVertex *start = md->gl_vertices_; @@ -1365,12 +1370,11 @@ void MD2RenderModel(MD2Model *md, const Image *skin_img, bool is_weapon, int fra glDrawArrays(GL_TRIANGLES, 0, md->total_triangles_ * 3); // restore the clamping mode - if (old_clamp != 789) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, old_clamp); + if (old_clamp != kDummyClamp) + { + global_render_state->TextureWrapT(old_clamp); + } } - - RenderState *state = GetRenderState(); - state->SetDefaultStateFull(); } void MD2RenderModel2D(MD2Model *md, const Image *skin_img, int frame, float x, float y, float xscale, float yscale, @@ -1388,16 +1392,16 @@ void MD2RenderModel2D(MD2Model *md, const Image *skin_img, int frame, float x, f xscale = yscale * info->model_scale_ * info->model_aspect_; yscale = yscale * info->model_scale_; - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, skin_tex); + global_render_state->Enable(GL_TEXTURE_2D); + global_render_state->BindTexture(skin_tex); - glEnable(GL_BLEND); - glEnable(GL_CULL_FACE); + global_render_state->Enable(GL_BLEND); + global_render_state->Enable(GL_CULL_FACE); if (info->flags_ & kMapObjectFlagFuzzy) - glColor4f(0, 0, 0, 0.5f); + global_render_state->GLColor(0, 0, 0, 0.5f); else - glColor4f(1, 1, 1, 1.0f); + global_render_state->GLColor(1, 1, 1, 1.0f); for (int i = 0; i < md->total_triangles_; i++) { @@ -1419,11 +1423,7 @@ void MD2RenderModel2D(MD2Model *md, const Image *skin_img, int frame, float x, f short n = vert->normal_idx; - float norm_x = md_normals[n].X; - float norm_y = md_normals[n].Y; - float norm_z = md_normals[n].Z; - - glNormal3f(norm_y, norm_z, norm_x); + global_render_state->SetNormal(md_normals[n]); float dx = vert->x * xscale; float dy = vert->y * xscale; @@ -1435,9 +1435,9 @@ void MD2RenderModel2D(MD2Model *md, const Image *skin_img, int frame, float x, f glEnd(); } - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glDisable(GL_CULL_FACE); + global_render_state->Disable(GL_BLEND); + global_render_state->Disable(GL_TEXTURE_2D); + global_render_state->Disable(GL_CULL_FACE); } //--- editor settings --- diff --git a/source_files/edge/r_mdl.cc b/source_files/edge/r_mdl.cc index 11999b574..2b8c4d270 100644 --- a/source_files/edge/r_mdl.cc +++ b/source_files/edge/r_mdl.cc @@ -27,6 +27,7 @@ #include +#include #include #include "ddf_types.h" @@ -52,6 +53,10 @@ #include "r_texgl.h" #include "r_units.h" +// clamp cache used by runits to avoid an extremely expensive gl tex param +// lookup +extern std::unordered_map texture_clamp_t; + extern float ApproximateDistance(float dx, float dy, float dz); extern ConsoleVariable draw_culling; @@ -677,20 +682,16 @@ static inline void ModelCoordFunc(MDLCoordinateData *data, int v_idx, HMM_Vec3 * if (!data->is_additive_) { - rgb[0] = col->modulate_red_ / 255.0; - rgb[1] = col->modulate_green_ / 255.0; - rgb[2] = col->modulate_blue_ / 255.0; + rgb[0] = col->modulate_red_ / 255.0 * render_view_red_multiplier; + rgb[1] = col->modulate_green_ / 255.0 * render_view_green_multiplier; + rgb[2] = col->modulate_blue_ / 255.0 * render_view_blue_multiplier; } else { - rgb[0] = col->add_red_ / 255.0; - rgb[1] = col->add_green_ / 255.0; - rgb[2] = col->add_blue_ / 255.0; + rgb[0] = col->add_red_ / 255.0 * render_view_red_multiplier; + rgb[1] = col->add_green_ / 255.0 * render_view_green_multiplier; + rgb[2] = col->add_blue_ / 255.0 * render_view_blue_multiplier; } - - rgb[0] *= render_view_red_multiplier; - rgb[1] *= render_view_green_multiplier; - rgb[2] *= render_view_blue_multiplier; } void MDLRenderModel(MDLModel *md, const Image *skin_img, bool is_weapon, int frame1, int frame2, float lerp, float x, @@ -876,11 +877,11 @@ void MDLRenderModel(MDLModel *md, const Image *skin_img, bool is_weapon, int fra fc[1] = (float)epi::GetRGBAGreen(fc_to_use) / 255.0f; fc[2] = (float)epi::GetRGBABlue(fc_to_use) / 255.0f; fc[3] = 1.0f; - glClearColor(fc[0], fc[1], fc[2], 1.0f); - glFogi(GL_FOG_MODE, GL_EXP); - glFogfv(GL_FOG_COLOR, fc); - glFogf(GL_FOG_DENSITY, std::log1p(fd_to_use)); - glEnable(GL_FOG); + global_render_state->ClearColor(fc[0], fc[1], fc[2], 1.0f); + global_render_state->FogMode(GL_EXP); + global_render_state->FogColor(fc[0], fc[1], fc[2], 1.0f); + global_render_state->FogDensity(std::log1p(fd_to_use)); + global_render_state->Enable(GL_FOG); } else if (draw_culling.d_) { @@ -911,15 +912,15 @@ void MDLRenderModel(MDLModel *md, const Image *skin_img, bool is_weapon, int fra { fogColor = sg_black; } - glClearColor(fogColor.r, fogColor.g, fogColor.b, 1.0f); - glFogi(GL_FOG_MODE, GL_LINEAR); - glFogfv(GL_FOG_COLOR, &fogColor.r); - glFogf(GL_FOG_START, renderer_far_clip.f_ - 750.0f); - glFogf(GL_FOG_END, renderer_far_clip.f_ - 250.0f); - glEnable(GL_FOG); + global_render_state->ClearColor(fogColor.r, fogColor.g, fogColor.b, 1.0f); + global_render_state->FogMode(GL_LINEAR); + global_render_state->FogColor(fogColor.r, fogColor.g, fogColor.b, fogColor.a); + global_render_state->FogStart(renderer_far_clip.f_ - 750.0f); + global_render_state->FogEnd(renderer_far_clip.f_ - 250.0f); + global_render_state->Enable(GL_FOG); } else - glDisable(GL_FOG); + global_render_state->Disable(GL_FOG); for (int pass = 0; pass < num_pass; pass++) { @@ -927,7 +928,7 @@ void MDLRenderModel(MDLModel *md, const Image *skin_img, bool is_weapon, int fra { blending &= ~kBlendingAlpha; blending |= kBlendingAdd; - glDisable(GL_FOG); + global_render_state->Disable(GL_FOG); } data.is_additive_ = (pass > 0 && pass == num_pass - 1); @@ -944,87 +945,91 @@ void MDLRenderModel(MDLModel *md, const Image *skin_img, bool is_weapon, int fra continue; } - glPolygonOffset(0, -pass); + global_render_state->PolygonOffset(0, -pass); if (blending & (kBlendingMasked | kBlendingLess)) { if (blending & kBlendingLess) { - glEnable(GL_ALPHA_TEST); + global_render_state->Enable(GL_ALPHA_TEST); } else if (blending & kBlendingMasked) { - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0); + global_render_state->Enable(GL_ALPHA_TEST); + global_render_state->AlphaFunction(GL_GREATER, 0); } - else - glDisable(GL_ALPHA_TEST); } + else + global_render_state->Disable(GL_ALPHA_TEST); if (blending & (kBlendingAlpha | kBlendingAdd)) { if (blending & kBlendingAdd) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + global_render_state->Enable(GL_BLEND); + global_render_state->BlendFunction(GL_SRC_ALPHA, GL_ONE); } else if (blending & kBlendingAlpha) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + global_render_state->Enable(GL_BLEND); + global_render_state->BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - else - glDisable(GL_BLEND); } + else + global_render_state->Disable(GL_BLEND); if (blending & (kBlendingCullBack | kBlendingCullFront)) { if (blending & (kBlendingCullBack | kBlendingCullFront)) { - glEnable(GL_CULL_FACE); - glCullFace((blending & kBlendingCullFront) ? GL_FRONT : GL_BACK); + global_render_state->Enable(GL_CULL_FACE); + global_render_state->CullFace((blending & kBlendingCullFront) ? GL_FRONT : GL_BACK); } - else - glDisable(GL_CULL_FACE); } + else + global_render_state->Disable(GL_CULL_FACE); if (blending & kBlendingNoZBuffer) { - glDepthMask((blending & kBlendingNoZBuffer) ? GL_FALSE : GL_TRUE); + global_render_state->DepthMask((blending & kBlendingNoZBuffer) ? GL_FALSE : GL_TRUE); } if (blending & kBlendingLess) { // NOTE: assumes alpha is constant over whole model - glAlphaFunc(GL_GREATER, trans * 0.66f); + global_render_state->AlphaFunction(GL_GREATER, trans * 0.66f); } - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, skin_tex); + global_render_state->ActiveTexture(GL_TEXTURE1); + global_render_state->Disable(GL_TEXTURE_2D); + global_render_state->ActiveTexture(GL_TEXTURE0); + global_render_state->Enable(GL_TEXTURE_2D); + global_render_state->BindTexture(skin_tex); if (data.is_additive_) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); + global_render_state->TextureEnvironmentMode(GL_COMBINE); + global_render_state->TextureEnvironmentCombineRGB(GL_REPLACE); + global_render_state->TextureEnvironmentSource0RGB(GL_PREVIOUS); } else { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); + global_render_state->TextureEnvironmentMode(GL_MODULATE); + global_render_state->TextureEnvironmentCombineRGB(GL_MODULATE); + global_render_state->TextureEnvironmentSource0RGB(GL_TEXTURE); } - GLint old_clamp = 789; + GLint old_clamp = kDummyClamp; if (blending & kBlendingClampY) { - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, &old_clamp); + auto existing = texture_clamp_t.find(skin_tex); + if (existing != texture_clamp_t.end()) + { + old_clamp = existing->second; + } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, renderer_dumb_clamp.d_ ? GL_CLAMP : GL_CLAMP_TO_EDGE); + global_render_state->TextureWrapT(renderer_dumb_clamp.d_ ? GL_CLAMP : GL_CLAMP_TO_EDGE); } RendererVertex *start = md->gl_vertices_; @@ -1062,12 +1067,11 @@ void MDLRenderModel(MDLModel *md, const Image *skin_img, bool is_weapon, int fra glDrawArrays(GL_TRIANGLES, 0, md->total_triangles_ * 3); // restore the clamping mode - if (old_clamp != 789) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, old_clamp); + if (old_clamp != kDummyClamp) + { + global_render_state->TextureWrapT(old_clamp); + } } - - RenderState *state = GetRenderState(); - state->SetDefaultStateFull(); } void MDLRenderModel2D(MDLModel *md, const Image *skin_img, int frame, float x, float y, float xscale, float yscale, @@ -1085,16 +1089,16 @@ void MDLRenderModel2D(MDLModel *md, const Image *skin_img, int frame, float x, f xscale = yscale * info->model_scale_ * info->model_aspect_; yscale = yscale * info->model_scale_; - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, skin_tex); + global_render_state->Enable(GL_TEXTURE_2D); + global_render_state->BindTexture(skin_tex); - glEnable(GL_BLEND); - glEnable(GL_CULL_FACE); + global_render_state->Enable(GL_BLEND); + global_render_state->Enable(GL_CULL_FACE); if (info->flags_ & kMapObjectFlagFuzzy) - glColor4f(0, 0, 0, 0.5f); + global_render_state->GLColor(0, 0, 0, 0.5f); else - glColor4f(1, 1, 1, 1.0f); + global_render_state->GLColor(1, 1, 1, 1.0f); for (int i = 0; i < md->total_triangles_; i++) { @@ -1116,11 +1120,7 @@ void MDLRenderModel2D(MDLModel *md, const Image *skin_img, int frame, float x, f short n = vert->normal_idx; - float norm_x = md_normals[n].X; - float norm_y = md_normals[n].Y; - float norm_z = md_normals[n].Z; - - glNormal3f(norm_y, norm_z, norm_x); + global_render_state->SetNormal(md_normals[n]); float dx = vert->x * xscale; float dy = vert->y * xscale; @@ -1132,9 +1132,9 @@ void MDLRenderModel2D(MDLModel *md, const Image *skin_img, int frame, float x, f glEnd(); } - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glDisable(GL_CULL_FACE); + global_render_state->Disable(GL_BLEND); + global_render_state->Disable(GL_TEXTURE_2D); + global_render_state->Disable(GL_CULL_FACE); } //--- editor settings --- diff --git a/source_files/edge/r_misc.cc b/source_files/edge/r_misc.cc index f1be44f69..509ae0fd6 100644 --- a/source_files/edge/r_misc.cc +++ b/source_files/edge/r_misc.cc @@ -268,11 +268,11 @@ RegionProperties *GetPointProperties(Subsector *sub, float z) //---------------------------------------------------------------------------- // large buffers for cache coherency vs allocating each on heap -static constexpr uint16_t kMaximumDrawThings = 32768; -static constexpr uint16_t kMaximumDrawFloors = 32768; -static constexpr uint32_t kMaximumDrawSegs = 65536; -static constexpr uint32_t kMaximumDrawSubsectors = 65536; -static constexpr uint16_t kMaximumDrawMirrors = 512; +static constexpr uint16_t kDefaultDrawThings = 32768; +static constexpr uint16_t kDefaultDrawFloors = 32768; +static constexpr uint32_t kDefaultDrawSegs = 65536; +static constexpr uint32_t kDefaultDrawSubsectors = 65536; +static constexpr uint16_t kDefaultDrawMirrors = 512; static std::vector draw_things; static std::vector draw_floors; @@ -293,11 +293,11 @@ static int draw_mirror_position; // void AllocateDrawStructs(void) { - draw_things.resize(kMaximumDrawThings); - draw_floors.resize(kMaximumDrawFloors); - draw_segs.resize(kMaximumDrawSegs); - draw_subsectors.resize(kMaximumDrawSubsectors); - draw_mirrors.resize(kMaximumDrawMirrors); + draw_things.resize(kDefaultDrawThings); + draw_floors.resize(kDefaultDrawFloors); + draw_segs.resize(kDefaultDrawSegs); + draw_subsectors.resize(kDefaultDrawSubsectors); + draw_mirrors.resize(kDefaultDrawMirrors); } // bsp clear function @@ -324,50 +324,40 @@ void FreeBSP(void) DrawThing *GetDrawThing() { - if (draw_thing_position >= kMaximumDrawThings) - { - FatalError("Max Draw Things Exceeded"); - } + if (draw_thing_position == draw_things.size()) + draw_things.push_back(DrawThing()); return &draw_things[draw_thing_position++]; } DrawFloor *GetDrawFloor() { - if (draw_floor_position >= kMaximumDrawFloors) - { - FatalError("Max Draw Floors Exceeded"); - } + if (draw_floor_position == draw_floors.size()) + draw_floors.push_back(DrawFloor()); return &draw_floors[draw_floor_position++]; } DrawSeg *GetDrawSeg() { - if (draw_seg_position >= kMaximumDrawSegs) - { - FatalError("Max Draw Segs Exceeded"); - } + if (draw_seg_position == draw_segs.size()) + draw_segs.push_back(DrawSeg()); return &draw_segs[draw_seg_position++]; } DrawSubsector *GetDrawSub() { - if (draw_subsector_position >= kMaximumDrawSubsectors) - { - FatalError("Max Draw Subs Exceeded"); - } + if (draw_subsector_position == draw_subsectors.size()) + draw_subsectors.push_back(DrawSubsector()); return &draw_subsectors[draw_subsector_position++]; } DrawMirror *GetDrawMirror() { - if (draw_mirror_position >= kMaximumDrawMirrors) - { - FatalError("Max Draw Mirrors Exceeded"); - } + if (draw_mirror_position == draw_mirrors.size()) + draw_mirrors.push_back(DrawMirror()); return &draw_mirrors[draw_mirror_position++]; } diff --git a/source_files/edge/r_render.cc b/source_files/edge/r_render.cc index 8fc862a1a..655d800f6 100644 --- a/source_files/edge/r_render.cc +++ b/source_files/edge/r_render.cc @@ -59,8 +59,6 @@ static constexpr float kDoomYSlopeFull = 0.625f; static constexpr float kWavetableIncrement = 0.0009765625f; -static constexpr uint8_t kMaximumPolygonVertices = 64; - EDGE_DEFINE_CONSOLE_VARIABLE(debug_hall_of_mirrors, "0", kConsoleVariableFlagCheat) EDGE_DEFINE_CONSOLE_VARIABLE(force_flat_lighting, "0", kConsoleVariableFlagArchive) @@ -116,8 +114,6 @@ static bool solid_mode; static std::list draw_subsector_list; -static std::unordered_map frame_texture_ids; - // ========= MIRROR STUFF =========== static constexpr uint8_t kMaximumMirrors = 3; @@ -353,12 +349,12 @@ static bool MirrorSegOnPortal(Seg *seg) static void MirrorSetClippers() { - glDisable(GL_CLIP_PLANE0); - glDisable(GL_CLIP_PLANE1); - glDisable(GL_CLIP_PLANE2); - glDisable(GL_CLIP_PLANE3); - glDisable(GL_CLIP_PLANE4); - glDisable(GL_CLIP_PLANE5); + global_render_state->Disable(GL_CLIP_PLANE0); + global_render_state->Disable(GL_CLIP_PLANE1); + global_render_state->Disable(GL_CLIP_PLANE2); + global_render_state->Disable(GL_CLIP_PLANE3); + global_render_state->Disable(GL_CLIP_PLANE4); + global_render_state->Disable(GL_CLIP_PLANE5); if (total_active_mirrors == 0) return; @@ -375,8 +371,8 @@ static void MirrorSetClippers() ClipPlaneEyeAngle(left_p, inner.draw_mirror_->left); ClipPlaneEyeAngle(right_p, inner.draw_mirror_->right + kBAMAngle180); - glEnable(GL_CLIP_PLANE0); - glEnable(GL_CLIP_PLANE1); + global_render_state->Enable(GL_CLIP_PLANE0); + global_render_state->Enable(GL_CLIP_PLANE1); glClipPlane(GL_CLIP_PLANE0, left_p); glClipPlane(GL_CLIP_PLANE1, right_p); @@ -411,7 +407,7 @@ static void MirrorSetClippers() ClipPlaneHorizontalLine(front_p, v2, v1); - glEnable(GL_CLIP_PLANE2 + i); + global_render_state->Enable(GL_CLIP_PLANE2 + i); glClipPlane(GL_CLIP_PLANE2 + i, front_p); } @@ -441,22 +437,6 @@ static void MirrorPop() MirrorSetClippers(); } -static GLuint R_ImageCache(const Image *image, bool anim = true, const Colormap *trans = nullptr) -{ - // (need to load the image to know the opacity) - auto frameid = frame_texture_ids.find(image); - if (frameid == frame_texture_ids.end()) - { - GLuint tex_id = ImageCache(image, true, render_view_effect_colormap); - frame_texture_ids.emplace(image, tex_id); - return tex_id; - } - else - { - return frameid->second; - } -} - float Slope_GetHeight(SlopePlane *slope, float x, float y) { // FIXME: precompute (store in slope_plane_t) @@ -827,7 +807,7 @@ static void DrawWallPart(DrawFloor *dfloor, float x1, float y1, float lz1, float EPI_ASSERT(image); // (need to load the image to know the opacity) - GLuint tex_id = R_ImageCache(image, true, render_view_effect_colormap); + GLuint tex_id = ImageCache(image, true, render_view_effect_colormap); // ignore non-solid walls in solid mode (& vice versa) if ((trans < 0.99f || image->opacity_ >= kOpacityMasked) == solid_mode) @@ -970,7 +950,6 @@ static void DrawWallPart(DrawFloor *dfloor, float x1, float y1, float lz1, float data.tx_mul = tx_mul; data.ty_mul = ty_mul; - // TODO: make a unit vector data.normal = {{(y2 - y1), (x1 - x2), 0}}; data.tex_id = tex_id; @@ -1807,7 +1786,7 @@ static void EmulateFloodPlane(const DrawFloor *dfloor, const Sector *flood_ref, FloodEmulationData data; - data.tex_id = R_ImageCache(surf->image, true, render_view_effect_colormap); + data.tex_id = ImageCache(surf->image, true, render_view_effect_colormap); data.pass = 0; data.R = data.G = data.B = 1.0f; @@ -2447,7 +2426,7 @@ static void RenderPlane(DrawFloor *dfloor, float h, MapSurface *surf, int face_d return; // (need to load the image to know the opacity) - GLuint tex_id = R_ImageCache(surf->image, true, render_view_effect_colormap); + GLuint tex_id = ImageCache(surf->image, true, render_view_effect_colormap); // ignore non-solid planes in solid_mode (& vice versa) if ((trans < 0.99f || surf->image->opacity_ >= kOpacityMasked) == solid_mode) @@ -2893,18 +2872,16 @@ static void RenderSubList(std::list &dsubs, bool for_mirror = f static void DrawMirrorPolygon(DrawMirror *mir) { - glDisable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - float alpha = 0.15 + 0.10 * total_active_mirrors; Line *ld = mir->seg->linedef; EPI_ASSERT(ld); + sg_color sgcol; + if (ld->special) { - sg_color sgcol = sg_make_color_1i(ld->special->fx_color_); + sgcol = sg_make_color_1i(ld->special->fx_color_); // looks better with reduced color in multiple reflections float reduce = 1.0f / (1 + 1.5 * total_active_mirrors); @@ -2913,10 +2890,10 @@ static void DrawMirrorPolygon(DrawMirror *mir) sgcol.g *= reduce; sgcol.b *= reduce; - glColor4f(sgcol.r, sgcol.g, sgcol.b, alpha); + sgcol.a = alpha; } else - glColor4f(1.0, 0.0, 0.0, alpha); + sgcol = {1.0, 0.0, 0.0, alpha}; float x1 = mir->seg->vertex_1->X; float y1 = mir->seg->vertex_1->Y; @@ -2929,16 +2906,19 @@ static void DrawMirrorPolygon(DrawMirror *mir) MirrorCoordinate(x1, y1); MirrorCoordinate(x2, y2); - glBegin(GL_POLYGON); + RendererVertex *glvert = BeginRenderUnit(GL_POLYGON, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, + 0, alpha < 0.99f ? kBlendingAlpha : kBlendingNone); - glVertex3f(x1, y1, z1); - glVertex3f(x1, y1, z2); - glVertex3f(x2, y2, z2); - glVertex3f(x2, y2, z1); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y1, z1}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x1, y1, z2}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{x2, y2, z2}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x2, y2, z1}}; - glEnd(); - - glDisable(GL_BLEND); + EndRenderUnit(4); } static void DrawPortalPolygon(DrawMirror *mir) @@ -2954,22 +2934,14 @@ static void DrawPortalPolygon(DrawMirror *mir) return; } - glDisable(GL_ALPHA_TEST); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - // set texture - GLuint tex_id = R_ImageCache(surf->image); - - glBindTexture(GL_TEXTURE_2D, tex_id); + GLuint tex_id = ImageCache(surf->image); // set colour & alpha float alpha = ld->special->translucency_ * surf->translucency; sg_color sgcol = sg_make_color_1i(ld->special->fx_color_); - - glColor4f(sgcol.r, sgcol.g, sgcol.b, alpha); + sgcol.a = alpha; // get polygon coordinates float x1 = mir->seg->vertex_1->X; @@ -2999,21 +2971,23 @@ static void DrawPortalPolygon(DrawMirror *mir) ty1 = ty1 * surf->y_matrix.Y / total_h; ty2 = ty2 * surf->y_matrix.Y / total_h; - glBegin(GL_POLYGON); - - glTexCoord2f(tx1, ty1); - glVertex3f(x1, y1, z1); - glTexCoord2f(tx1, ty2); - glVertex3f(x1, y1, z2); - glTexCoord2f(tx2, ty2); - glVertex3f(x2, y2, z2); - glTexCoord2f(tx2, ty1); - glVertex3f(x2, y2, z1); - - glEnd(); - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); + RendererVertex *glvert = BeginRenderUnit(GL_POLYGON, 4, GL_MODULATE, tex_id, (GLuint)kTextureEnvironmentDisable, 0, + 0, alpha < 0.99f ? kBlendingAlpha : kBlendingNone); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x1, y1, z1}}; + glvert++->texture_coordinates[0] = {{tx1, ty1}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x1, y1, z2}}; + glvert++->texture_coordinates[0] = {{tx1, ty2}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x2, y2, z2}}; + glvert++->texture_coordinates[0] = {{tx2, ty2}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x2, y2, z1}}; + glvert->texture_coordinates[0] = {{tx2, ty1}}; + + EndRenderUnit(4); } static void RenderMirror(DrawMirror *mir) @@ -3034,11 +3008,15 @@ static void RenderMirror(DrawMirror *mir) } MirrorPop(); + StartUnitBatch(false); + if (mir->is_portal) DrawPortalPolygon(mir); else DrawMirrorPolygon(mir); + FinishUnitBatch(); + #if defined(EDGE_GL_ES2) // GL4ES mirror fix for renderlist gl4es_flush(); @@ -3199,11 +3177,8 @@ static void RenderTrueBsp(void) SetupMatrices3d(); - frame_texture_ids.clear(); - frame_texture_ids.reserve(1024); - glClear(GL_DEPTH_BUFFER_BIT); - glEnable(GL_DEPTH_TEST); + global_render_state->Enable(GL_DEPTH_TEST); // needed for drawing the sky BeginSky(); @@ -3213,13 +3188,8 @@ static void RenderTrueBsp(void) FinishSky(); - RenderState *state = GetRenderState(); - state->SetDefaultStateFull(); - RenderSubList(draw_subsector_list); - state->SetDefaultStateFull(); - // Lobo 2022: // Allow changing the order of weapon model rendering to be // after RenderWeaponSprites() so that FLASH states are @@ -3239,7 +3209,7 @@ static void RenderTrueBsp(void) DoWeaponModel(); } - glDisable(GL_DEPTH_TEST); + global_render_state->Disable(GL_DEPTH_TEST); // now draw 2D stuff like psprites, and add effects SetupWorldMatrices2D(); @@ -3258,9 +3228,9 @@ static void RenderTrueBsp(void) { SetupMatrices3d(); glClear(GL_DEPTH_BUFFER_BIT); - glEnable(GL_DEPTH_TEST); + global_render_state->Enable(GL_DEPTH_TEST); DoWeaponModel(); - glDisable(GL_DEPTH_TEST); + global_render_state->Disable(GL_DEPTH_TEST); SetupMatrices2D(); } diff --git a/source_files/edge/r_sky.cc b/source_files/edge/r_sky.cc index 90e8622dd..b74ea528a 100644 --- a/source_files/edge/r_sky.cc +++ b/source_files/edge/r_sky.cc @@ -50,6 +50,14 @@ extern ConsoleVariable fliplevels; static sg_color sky_cap_color; +static constexpr sg_color sky_white = sg_white; + +static uint32_t total_sky_verts = 0; + +static RendererVertex *sky_glvert = nullptr; + +static bool sky_unit_started = false; + static SkyStretch current_sky_stretch = kSkyStretchUnset; EDGE_DEFINE_CONSOLE_VARIABLE_CLAMPED(sky_stretch_mode, "0", kConsoleVariableFlagArchive, 0, 3); @@ -99,15 +107,6 @@ void ComputeSkyHeights(void) rings[i].group = (i + 1); rings[i].next = rings[i].previous = rings + i; rings[i].maximum_height = sec->ceiling_height; - - // leave some room for tall sprites - static const float SPR_H_MAX = 256.0f; - - if (sec->ceiling_height < 30000.0f && (sec->ceiling_height > sec->floor_height) && - (sec->ceiling_height < sec->floor_height + SPR_H_MAX)) - { - rings[i].maximum_height = sec->floor_height + SPR_H_MAX; - } } // --- make the pass over linedefs --- @@ -211,7 +210,7 @@ static void DeleteSkyTexGroup(int SK) { if (fake_box[SK].texture[i] != 0) { - glDeleteTextures(1, &fake_box[SK].texture[i]); + global_render_state->DeleteTexture(&fake_box[SK].texture[i]); fake_box[SK].texture[i] = 0; } } @@ -292,20 +291,19 @@ static void RendererRevertSkyMatrices(void) glPopMatrix(); } +static void BeginSkyUnit(void) +{ + total_sky_verts = 0; + StartUnitBatch(false); + sky_glvert = BeginRenderUnit(GL_TRIANGLES, kMaximumLocalVertices, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNone); + sky_unit_started = true; +} + void BeginSky(void) { need_to_draw_sky = false; glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glDisable(GL_TEXTURE_2D); - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - - // Draw the entire sky using only one glBegin/glEnd clause. - // glEnd is called in FinishSky and this code assumes that only - // RenderSkyWall and RenderSkyPlane is doing OpenGL calls in - // between. - glBegin(GL_TRIANGLES); } // The following cylindrical sky-drawing routines are adapted from SLADE's 3D @@ -329,7 +327,7 @@ static void BuildSkyCircle() // Renders a cylindrical 'slice' of the sky between [top] and [bottom] on the z // axis // ----------------------------------------------------------------------------- -static void RenderSkySlice(float top, float bottom, float atop, float abottom, float dist, float tx, float ty) +static void RenderSkySlice(float top, float bottom, float atop, float abottom, float dist, float tx, float ty, GLuint sky_tex_id, BlendingMode blend, RGBAColor fc_to_use, float fd_to_use) { float tc_x = 0.0f; float tc_y1 = (top + 1.0f) * (ty * 0.5f); @@ -341,49 +339,56 @@ static void RenderSkySlice(float top, float bottom, float atop, float abottom, f tc_y2 = -tc_y2; } - glBegin(GL_QUADS); + sg_color topcol = {1.0f, 1.0f, 1.0f, atop}; + sg_color bottomcol = {1.0f, 1.0f, 1.0f, abottom}; + + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 128, GL_MODULATE, sky_tex_id, (GLuint)kTextureEnvironmentDisable, 0, 0, blend|kBlendingAlpha, fc_to_use, fd_to_use); // Go through circular points for (unsigned a = 0; a < 31; a++) { // Top - glColor4f(1.0f, 1.0f, 1.0f, atop); - glTexCoord2f(tc_x + tx, tc_y1); - glVertex3f((sky_circle[a + 1].X * dist), -(sky_circle[a + 1].Y * dist), (top * dist)); - glTexCoord2f(tc_x, tc_y1); - glVertex3f((sky_circle[a].X * dist), -(sky_circle[a].Y * dist), (top * dist)); + memcpy(&glvert->rgba_color, &topcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tc_x + tx, tc_y1}}; + glvert++->position = {{(sky_circle[a + 1].X * dist), -(sky_circle[a + 1].Y * dist), (top * dist)}}; + memcpy(&glvert->rgba_color, &topcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tc_x, tc_y1}}; + glvert++->position = {{(sky_circle[a].X * dist), -(sky_circle[a].Y * dist), (top * dist)}}; // Bottom - glColor4f(1.0f, 1.0f, 1.0f, abottom); - glTexCoord2f(tc_x, tc_y2); - glVertex3f((sky_circle[a].X * dist), -(sky_circle[a].Y * dist), (bottom * dist)); - glTexCoord2f(tc_x + tx, tc_y2); - glVertex3f((sky_circle[a + 1].X * dist), -(sky_circle[a + 1].Y * dist), (bottom * dist)); + memcpy(&glvert->rgba_color, &bottomcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tc_x, tc_y2}}; + glvert++->position = {{(sky_circle[a].X * dist), -(sky_circle[a].Y * dist), (bottom * dist)}}; + memcpy(&glvert->rgba_color, &bottomcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tc_x + tx, tc_y2}}; + glvert++->position = {{(sky_circle[a + 1].X * dist), -(sky_circle[a + 1].Y * dist), (bottom * dist)}}; tc_x += tx; } // Link last point -> first // Top - glColor4f(1.0f, 1.0f, 1.0f, atop); - glTexCoord2f(tc_x + tx, tc_y1); - glVertex3f((sky_circle[0].X * dist), -(sky_circle[0].Y * dist), (top * dist)); - glTexCoord2f(tc_x, tc_y1); - glVertex3f((sky_circle[31].X * dist), -(sky_circle[31].Y * dist), (top * dist)); + memcpy(&glvert->rgba_color, &topcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tc_x + tx, tc_y1}}; + glvert++->position = {{(sky_circle[0].X * dist), -(sky_circle[0].Y * dist), (top * dist)}}; + memcpy(&glvert->rgba_color, &topcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tc_x, tc_y1}}; + glvert++->position = {{(sky_circle[31].X * dist), -(sky_circle[31].Y * dist), (top * dist)}}; // Bottom - glColor4f(1.0f, 1.0f, 1.0f, abottom); - glTexCoord2f(tc_x, tc_y2); - glVertex3f((sky_circle[31].X * dist), -(sky_circle[31].Y * dist), (bottom * dist)); - glTexCoord2f(tc_x + tx, tc_y2); - glVertex3f((sky_circle[0].X * dist), -(sky_circle[0].Y * dist), (bottom * dist)); - - glEnd(); + memcpy(&glvert->rgba_color, &bottomcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tc_x, tc_y2}}; + glvert++->position = {{(sky_circle[31].X * dist), -(sky_circle[31].Y * dist), (bottom * dist)}}; + memcpy(&glvert->rgba_color, &bottomcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tc_x + tx, tc_y2}}; + glvert->position = {{(sky_circle[0].X * dist), -(sky_circle[0].Y * dist), (bottom * dist)}}; + + EndRenderUnit(128); } static void RenderSkyCylinder(void) { - GLuint sky = ImageCache(sky_image, false, render_view_effect_colormap); + GLuint sky_tex_id = ImageCache(sky_image, false, render_view_effect_colormap); if (current_map->forced_skystretch_ > kSkyStretchUnset) current_sky_stretch = current_map->forced_skystretch_; @@ -395,8 +400,6 @@ static void RenderSkyCylinder(void) // Center skybox a bit below the camera view SetupSkyMatrices(); - glDisable(GL_TEXTURE_2D); - float dist = renderer_far_clip.f_ * 2.0f; float cap_dist = dist * 2.0f; // Ensure the caps extend beyond the cylindrical // projection Calculate some stuff based on sky height @@ -416,49 +419,55 @@ static void RenderSkyCylinder(void) RGBAColor fc_to_use = current_map->outdoor_fog_color_; float fd_to_use = 0.01f * current_map->outdoor_fog_density_; + BlendingMode blend = kBlendingNoZBuffer; // check for sector fog if (fc_to_use == kRGBANoValue) { fc_to_use = view_properties->fog_color; fd_to_use = view_properties->fog_density; } - - if (!draw_culling.d_ && fc_to_use != kRGBANoValue) + if (draw_culling.d_) { - sg_color fc = sg_make_color_1i(fc_to_use); - glClearColor(fc.r, fc.g, fc.b, fc.a); - glFogi(GL_FOG_MODE, GL_EXP); - glFogfv(GL_FOG_COLOR, &fc.r); - glFogf(GL_FOG_DENSITY, std::log1p(fd_to_use * 0.005f)); - glEnable(GL_FOG); + fc_to_use = kRGBANoValue; + fd_to_use = 0.0f; + blend = (BlendingMode)(blend|kBlendingNoFog); } // Render top cap - glColor4f(sky_cap_color.r, sky_cap_color.g, sky_cap_color.b, 1.0f); - glBegin(GL_QUADS); - glVertex3f(-cap_dist, -cap_dist, cap_z); - glVertex3f(-cap_dist, cap_dist, cap_z); - glVertex3f(cap_dist, cap_dist, cap_z); - glVertex3f(cap_dist, -cap_dist, cap_z); - glEnd(); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, blend, fc_to_use, fd_to_use); + sg_color sgcol = { sky_cap_color.r, sky_cap_color.g, sky_cap_color.b, 1.0f }; + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{-cap_dist, -cap_dist, cap_z}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{-cap_dist, cap_dist, cap_z}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{cap_dist, cap_dist, cap_z}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{cap_dist, -cap_dist, cap_z}}; + + EndRenderUnit(4); // Render bottom cap if (current_sky_stretch > kSkyStretchMirror) - glColor4f(culling_fog_color.r, culling_fog_color.g, culling_fog_color.b, 1.0f); - glBegin(GL_QUADS); + sgcol = { culling_fog_color.r, culling_fog_color.g, culling_fog_color.b, 1.0f }; if (current_sky_stretch == kSkyStretchVanilla) cap_z = 0; - glVertex3f(-cap_dist, -cap_dist, -cap_z); - glVertex3f(-cap_dist, cap_dist, -cap_z); - glVertex3f(cap_dist, cap_dist, -cap_z); - glVertex3f(cap_dist, -cap_dist, -cap_z); - glEnd(); + + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, blend, fc_to_use, fd_to_use); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{-cap_dist, -cap_dist, -cap_z}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{-cap_dist, cap_dist, -cap_z}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert++->position = {{cap_dist, cap_dist, -cap_z}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{cap_dist, -cap_dist, -cap_z}}; + + EndRenderUnit(4); // Render skybox sides - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, sky); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Check for odd sky sizes float tx = 0.125f; @@ -466,30 +475,27 @@ static void RenderSkyCylinder(void) if (sky_image->ScaledWidthActual() > 256) tx = 0.125f / ((float)sky_image->ScaledWidthActual() / 256.0f); - glEnable(GL_ALPHA_TEST); - glEnable(GL_BLEND); - if (current_sky_stretch == kSkyStretchMirror) { if (sky_image->ScaledHeightActual() > 128) { RenderSkySlice(sky_h_ratio, solid_sky_h, 0.0f, 1.0f, dist, tx, - ty); // Top Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Top Fade RenderSkySlice(solid_sky_h, 0.0f, 1.0f, 1.0f, dist, tx, - ty); // Top Solid + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Top Solid RenderSkySlice(0.0f, -solid_sky_h, 1.0f, 1.0f, dist, tx, - ty); // Bottom Solid + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Bottom Solid RenderSkySlice(-solid_sky_h, -sky_h_ratio, 1.0f, 0.0f, dist, tx, - ty); // Bottom Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Bottom Fade } else { - RenderSkySlice(1.0f, 0.75f, 0.0f, 1.0f, dist, tx, ty); // Top Fade - RenderSkySlice(0.75f, 0.0f, 1.0f, 1.0f, dist, tx, ty); // Top Solid + RenderSkySlice(1.0f, 0.75f, 0.0f, 1.0f, dist, tx, ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Top Fade + RenderSkySlice(0.75f, 0.0f, 1.0f, 1.0f, dist, tx, ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Top Solid RenderSkySlice(0.0f, -0.75f, 1.0f, 1.0f, dist, tx, - ty); // Bottom Solid + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Bottom Solid RenderSkySlice(-0.75f, -1.0f, 1.0f, 0.0f, dist, tx, - ty); // Bottom Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Bottom Fade } } else if (current_sky_stretch == kSkyStretchRepeat) @@ -497,19 +503,19 @@ static void RenderSkyCylinder(void) if (sky_image->ScaledHeightActual() > 128) { RenderSkySlice(sky_h_ratio, solid_sky_h, 0.0f, 1.0f, dist, tx, - ty); // Top Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Top Fade RenderSkySlice(solid_sky_h, -solid_sky_h, 1.0f, 1.0f, dist, tx, - ty); // Middle Solid + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Middle Solid RenderSkySlice(-solid_sky_h, -sky_h_ratio, 1.0f, 0.0f, dist, tx, - ty); // Bottom Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Bottom Fade } else { - RenderSkySlice(1.0f, 0.75f, 0.0f, 1.0f, dist, tx, ty); // Top Fade + RenderSkySlice(1.0f, 0.75f, 0.0f, 1.0f, dist, tx, ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Top Fade RenderSkySlice(0.75f, -0.75f, 1.0f, 1.0f, dist, tx, - ty); // Middle Solid + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Middle Solid RenderSkySlice(-0.75f, -1.0f, 1.0f, 0.0f, dist, tx, - ty); // Bottom Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Bottom Fade } } else if (current_sky_stretch == kSkyStretchStretch) @@ -518,20 +524,20 @@ static void RenderSkyCylinder(void) { ty = ((float)sky_image->ScaledHeightActual() / 256.0f); RenderSkySlice(sky_h_ratio, solid_sky_h, 0.0f, 1.0f, dist, tx, - ty); // Top Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Top Fade RenderSkySlice(solid_sky_h, -solid_sky_h, 1.0f, 1.0f, dist, tx, - ty); // Middle Solid + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Middle Solid RenderSkySlice(-solid_sky_h, -sky_h_ratio, 1.0f, 0.0f, dist, tx, - ty); // Bottom Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Bottom Fade } else { ty = 1.0f; - RenderSkySlice(1.0f, 0.75f, 0.0f, 1.0f, dist, tx, ty); // Top Fade + RenderSkySlice(1.0f, 0.75f, 0.0f, 1.0f, dist, tx, ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Top Fade RenderSkySlice(0.75f, -0.75f, 1.0f, 1.0f, dist, tx, - ty); // Middle Solid + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Middle Solid RenderSkySlice(-0.75f, -1.0f, 1.0f, 0.0f, dist, tx, - ty); // Bottom Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Bottom Fade } } else // Vanilla (or sane value if somehow this gets set out of expected @@ -540,28 +546,21 @@ static void RenderSkyCylinder(void) if (sky_image->ScaledHeightActual() > 128) { RenderSkySlice(sky_h_ratio, solid_sky_h, 0.0f, 1.0f, dist / 2, tx, - ty); // Top Fade - RenderSkySlice(solid_sky_h, sky_h_ratio - solid_sky_h, 1.0f, 1.0f, dist / 2, tx, ty); // Middle Solid - RenderSkySlice(sky_h_ratio - solid_sky_h, 0.0f, 1.0f, 0.0f, dist / 2, tx, ty); // Bottom Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Top Fade + RenderSkySlice(solid_sky_h, sky_h_ratio - solid_sky_h, 1.0f, 1.0f, dist / 2, tx, ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Middle Solid + RenderSkySlice(sky_h_ratio - solid_sky_h, 0.0f, 1.0f, 0.0f, dist / 2, tx, ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Bottom Fade } else { ty *= 1.5f; RenderSkySlice(1.0f, 0.98f, 0.0f, 1.0f, dist / 3, tx, - ty); // Top Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Top Fade RenderSkySlice(0.98f, 0.35f, 1.0f, 1.0f, dist / 3, tx, - ty); // Middle Solid + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Middle Solid RenderSkySlice(0.35f, 0.33f, 1.0f, 0.0f, dist / 3, tx, - ty); // Bottom Fade + ty, sky_tex_id, blend, fc_to_use, fd_to_use); // Bottom Fade } } - - glDisable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - if (!draw_culling.d_) - glDisable(GL_FOG); - - RendererRevertSkyMatrices(); } static void RenderSkybox(void) @@ -585,17 +584,6 @@ static void RenderSkybox(void) v1 = 1.0f - v0; } - glEnable(GL_TEXTURE_2D); - - float col[4]; - - col[0] = render_view_red_multiplier; - col[1] = render_view_green_multiplier; - col[2] = render_view_blue_multiplier; - col[3] = 1.0f; - - glColor4fv(col); - RGBAColor fc_to_use = current_map->outdoor_fog_color_; float fd_to_use = 0.01f * current_map->outdoor_fog_density_; // check for sector fog @@ -605,162 +593,200 @@ static void RenderSkybox(void) fd_to_use = view_properties->fog_density; } - if (!draw_culling.d_ && fc_to_use != kRGBANoValue) - { - sg_color fc = sg_make_color_1i(fc_to_use); - glClearColor(fc.r, fc.g, fc.b, fc.a); - glFogi(GL_FOG_MODE, GL_EXP); - glFogfv(GL_FOG_COLOR, &fc.r); - glFogf(GL_FOG_DENSITY, std::log1p(fd_to_use * 0.01f)); - glEnable(GL_FOG); - } - + sg_color sgcol = { render_view_red_multiplier, render_view_green_multiplier, render_view_blue_multiplier, 1.0f }; // top - glBindTexture(GL_TEXTURE_2D, fake_box[SK].texture[kSkyboxTop]); - glNormal3i(0, 0, -1); -#ifdef APPLE_SILICON - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); -#endif - glBegin(GL_QUADS); - glTexCoord2f(v0, v0); - glVertex3f(-dist, dist, +dist); - glTexCoord2f(v0, v1); - glVertex3f(-dist, -dist, +dist); - glTexCoord2f(v1, v1); - glVertex3f(dist, -dist, +dist); - glTexCoord2f(v1, v0); - glVertex3f(dist, dist, +dist); - glEnd(); + HMM_Vec3 norm = {{ 0, 0, -1 }}; + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, fake_box[SK].texture[kSkyboxTop], (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNoZBuffer, fc_to_use, fd_to_use); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v0}}; + glvert++->position = {{-dist, dist, +dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v1}}; + glvert++->position = {{-dist, -dist, +dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v1}}; + glvert++->position = {{dist, -dist, +dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v0}}; + glvert++->position = {{dist, dist, +dist}}; + + EndRenderUnit(4); // bottom - glBindTexture(GL_TEXTURE_2D, fake_box[SK].texture[kSkyboxBottom]); - glNormal3i(0, 0, +1); -#ifdef APPLE_SILICON - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); -#endif - glBegin(GL_QUADS); - glTexCoord2f(v0, v0); - glVertex3f(-dist, -dist, -dist); - glTexCoord2f(v0, v1); - glVertex3f(-dist, dist, -dist); - glTexCoord2f(v1, v1); - glVertex3f(dist, dist, -dist); - glTexCoord2f(v1, v0); - glVertex3f(dist, -dist, -dist); - glEnd(); + norm = {{0, 0, +1}}; + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, fake_box[SK].texture[kSkyboxBottom], (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNoZBuffer, fc_to_use, fd_to_use); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v0}}; + glvert++->position = {{-dist, -dist, -dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v1}}; + glvert++->position = {{-dist, dist, -dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v1}}; + glvert++->position = {{dist, dist, -dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v0}}; + glvert++->position = {{dist, -dist, -dist}}; + + EndRenderUnit(4); // north - glBindTexture(GL_TEXTURE_2D, fake_box[SK].texture[kSkyboxNorth]); - glNormal3i(0, -1, 0); -#ifdef APPLE_SILICON - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); -#endif - glBegin(GL_QUADS); - glTexCoord2f(v0, v0); - glVertex3f(-dist, dist, -dist); - glTexCoord2f(v0, v1); - glVertex3f(-dist, dist, +dist); - glTexCoord2f(v1, v1); - glVertex3f(dist, dist, +dist); - glTexCoord2f(v1, v0); - glVertex3f(dist, dist, -dist); - glEnd(); + norm = {{0, -1, 0}}; + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, fake_box[SK].texture[kSkyboxNorth], (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNoZBuffer, fc_to_use, fd_to_use); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v0}}; + glvert++->position = {{-dist, dist, -dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v1}}; + glvert++->position = {{-dist, dist, +dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v1}}; + glvert++->position = {{dist, dist, +dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v0}}; + glvert++->position = {{dist, dist, -dist}}; + + EndRenderUnit(4); // east - glBindTexture(GL_TEXTURE_2D, fake_box[SK].texture[kSkyboxEast]); - glNormal3i(-1, 0, 0); -#ifdef APPLE_SILICON - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); -#endif - glBegin(GL_QUADS); - glTexCoord2f(v0, v0); - glVertex3f(dist, dist, -dist); - glTexCoord2f(v0, v1); - glVertex3f(dist, dist, +dist); - glTexCoord2f(v1, v1); - glVertex3f(dist, -dist, +dist); - glTexCoord2f(v1, v0); - glVertex3f(dist, -dist, -dist); - glEnd(); + norm = {{-1, 0, 0}}; + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, fake_box[SK].texture[kSkyboxEast], (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNoZBuffer, fc_to_use, fd_to_use); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v0}}; + glvert++->position = {{dist, dist, -dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v1}}; + glvert++->position = {{dist, dist, +dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v1}}; + glvert++->position = {{dist, -dist, +dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v0}}; + glvert++->position = {{dist, -dist, -dist}}; + + EndRenderUnit(4); // south - glBindTexture(GL_TEXTURE_2D, fake_box[SK].texture[kSkyboxSouth]); - glNormal3i(0, +1, 0); -#ifdef APPLE_SILICON - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); -#endif - glBegin(GL_QUADS); - glTexCoord2f(v0, v0); - glVertex3f(dist, -dist, -dist); - glTexCoord2f(v0, v1); - glVertex3f(dist, -dist, +dist); - glTexCoord2f(v1, v1); - glVertex3f(-dist, -dist, +dist); - glTexCoord2f(v1, v0); - glVertex3f(-dist, -dist, -dist); - glEnd(); + norm = {{0, +1, 0}}; + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, fake_box[SK].texture[kSkyboxSouth], (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNoZBuffer, fc_to_use, fd_to_use); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v0}}; + glvert++->position = {{dist, -dist, -dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v1}}; + glvert++->position = {{dist, -dist, +dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v1}}; + glvert++->position = {{-dist, -dist, +dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v0}}; + glvert++->position = {{-dist, -dist, -dist}}; + + EndRenderUnit(4); // west - glBindTexture(GL_TEXTURE_2D, fake_box[SK].texture[kSkyboxWest]); - glNormal3i(+1, 0, 0); -#ifdef APPLE_SILICON - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); -#endif - glBegin(GL_QUADS); - glTexCoord2f(v0, v0); - glVertex3f(-dist, -dist, -dist); - glTexCoord2f(v0, v1); - glVertex3f(-dist, -dist, +dist); - glTexCoord2f(v1, v1); - glVertex3f(-dist, dist, +dist); - glTexCoord2f(v1, v0); - glVertex3f(-dist, dist, -dist); - glEnd(); - - glDisable(GL_TEXTURE_2D); - if (!draw_culling.d_) - glDisable(GL_FOG); + norm = {{+1, 0, 0}}; + glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, fake_box[SK].texture[kSkyboxWest], (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNoZBuffer, fc_to_use, fd_to_use); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v0}}; + glvert++->position = {{-dist, -dist, -dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v0, v1}}; + glvert++->position = {{-dist, -dist, +dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v1}}; + glvert++->position = {{-dist, dist, +dist}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + memcpy(&glvert->normal, &norm, 3 * sizeof(float)); + glvert->texture_coordinates[0] = {{v1, v0}}; + glvert++->position = {{-dist, dist, -dist}}; + + EndRenderUnit(4); +} - RendererRevertSkyMatrices(); +static void FinishSkyUnit(void) +{ + EndRenderUnit(total_sky_verts); + FinishUnitBatch(); + sky_glvert = nullptr; + total_sky_verts = 0; + sky_unit_started = false; } void FinishSky(void) { - glEnd(); // End glBegin(GL_TRIANGLES) from BeginSky + if (sky_unit_started) + FinishSkyUnit(); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); if (!need_to_draw_sky) return; + if (draw_culling.d_) + global_render_state->Disable(GL_DEPTH_TEST); + if (!renderer_dumb_sky.d_) - glDepthFunc(GL_ALWAYS); + global_render_state->DepthFunction(GL_GREATER); else - glDepthMask(GL_FALSE); + global_render_state->DepthMask(false); - if (draw_culling.d_) - glDisable(GL_DEPTH_TEST); + StartUnitBatch(false); + +#ifdef APPLE_SILICON + uint8_t old_dumb_clamp = renderer_dumb_clamp.d_; + renderer_dumb_clamp = 1; +#endif if (custom_skybox) RenderSkybox(); else RenderSkyCylinder(); + FinishUnitBatch(); + + RendererRevertSkyMatrices(); + +#ifdef APPLE_SILICON + renderer_dumb_clamp = old_dumb_clamp; +#endif + if (draw_culling.d_) - glEnable(GL_DEPTH_TEST); + global_render_state->Enable(GL_DEPTH_TEST); if (!renderer_dumb_sky.d_) - glDepthFunc(GL_LEQUAL); + global_render_state->DepthFunction(GL_LEQUAL); else - glDepthMask(GL_TRUE); - - glDisable(GL_TEXTURE_2D); + global_render_state->DepthMask(true); } void RenderSkyPlane(Subsector *sub, float h) @@ -769,11 +795,6 @@ void RenderSkyPlane(Subsector *sub, float h) if (renderer_dumb_sky.d_) return; - - MirrorHeight(h); - - glNormal3f(0, 0, (view_z > h) ? 1.0f : -1.0f); - Seg *seg = sub->segs; if (!seg) return; @@ -792,20 +813,44 @@ void RenderSkyPlane(Subsector *sub, float h) if (!seg) return; + if (!sky_unit_started) + BeginSkyUnit(); + + MirrorHeight(h); + HMM_Vec3 norm = {{0, 0, (view_z > h) ? 1.0f : -1.0f}}; + while (seg) { float x2 = seg->vertex_1->X; float y2 = seg->vertex_1->Y; MirrorCoordinate(x2, y2); - glVertex3f(x0, y0, h); - glVertex3f(x1, y1, h); - glVertex3f(x2, y2, h); + memcpy(&sky_glvert->normal, &norm, 3 * sizeof(float)); + memcpy(&sky_glvert->rgba_color, &sky_white, 4 * sizeof(float)); + sky_glvert++->position = {{x0, y0, h}}; + memcpy(&sky_glvert->normal, &norm, 3 * sizeof(float)); + memcpy(&sky_glvert->rgba_color, &sky_white, 4 * sizeof(float)); + sky_glvert++->position = {{x1, y1, h}}; + memcpy(&sky_glvert->normal, &norm, 3 * sizeof(float)); + memcpy(&sky_glvert->rgba_color, &sky_white, 4 * sizeof(float)); + sky_glvert++->position = {{x2, y2, h}}; + + total_sky_verts += 3; x1 = x2; y1 = y2; seg = seg->subsector_next; } + + // Break up large batches + if (total_sky_verts > kMaximumLocalVertices / 2) + { + EndRenderUnit(total_sky_verts); + FinishUnitBatch(); + StartUnitBatch(false); + sky_glvert = BeginRenderUnit(GL_TRIANGLES, kMaximumLocalVertices, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNone); + total_sky_verts = 0; + } } void RenderSkyWall(Seg *seg, float h1, float h2) @@ -815,6 +860,9 @@ void RenderSkyWall(Seg *seg, float h1, float h2) if (renderer_dumb_sky.d_) return; + if (!sky_unit_started) + BeginSkyUnit(); + float x1 = seg->vertex_1->X; float y1 = seg->vertex_1->Y; float x2 = seg->vertex_2->X; @@ -826,15 +874,38 @@ void RenderSkyWall(Seg *seg, float h1, float h2) MirrorHeight(h1); MirrorHeight(h2); - glNormal3f(y2 - y1, x1 - x2, 0); - - glVertex3f(x1, y1, h1); - glVertex3f(x1, y1, h2); - glVertex3f(x2, y2, h2); - - glVertex3f(x2, y2, h1); - glVertex3f(x2, y2, h2); - glVertex3f(x1, y1, h1); + HMM_Vec3 norm = {{y2 - y1, x1 - x2, 0}}; + + memcpy(&sky_glvert->normal, &norm, 3 * sizeof(float)); + memcpy(&sky_glvert->rgba_color, &sky_white, 4 * sizeof(float)); + sky_glvert++->position = {{x1, y1, h1}}; + memcpy(&sky_glvert->normal, &norm, 3 * sizeof(float)); + memcpy(&sky_glvert->rgba_color, &sky_white, 4 * sizeof(float)); + sky_glvert++->position = {{x1, y1, h2}}; + memcpy(&sky_glvert->normal, &norm, 3 * sizeof(float)); + memcpy(&sky_glvert->rgba_color, &sky_white, 4 * sizeof(float)); + sky_glvert++->position = {{x2, y2, h2}}; + memcpy(&sky_glvert->normal, &norm, 3 * sizeof(float)); + memcpy(&sky_glvert->rgba_color, &sky_white, 4 * sizeof(float)); + sky_glvert++->position = {{x2, y2, h1}}; + memcpy(&sky_glvert->normal, &norm, 3 * sizeof(float)); + memcpy(&sky_glvert->rgba_color, &sky_white, 4 * sizeof(float)); + sky_glvert++->position = {{x2, y2, h2}}; + memcpy(&sky_glvert->normal, &norm, 3 * sizeof(float)); + memcpy(&sky_glvert->rgba_color, &sky_white, 4 * sizeof(float)); + sky_glvert++->position = {{x1, y1, h1}}; + + total_sky_verts += 6; + + // Break up large batches + if (total_sky_verts > kMaximumLocalVertices / 2) + { + EndRenderUnit(total_sky_verts); + FinishUnitBatch(); + StartUnitBatch(false); + sky_glvert = BeginRenderUnit(GL_TRIANGLES, kMaximumLocalVertices, GL_MODULATE, 0, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNone); + total_sky_verts = 0; + } } //---------------------------------------------------------------------------- diff --git a/source_files/edge/r_state.cc b/source_files/edge/r_state.cc index f4221b82d..b2da1fe46 100644 --- a/source_files/edge/r_state.cc +++ b/source_files/edge/r_state.cc @@ -1,9 +1,6 @@ #include "r_state.h" -static RenderState state; +RenderState state; -RenderState *GetRenderState() -{ - return &state; -} +RenderState *global_render_state = &state; diff --git a/source_files/edge/r_state.h b/source_files/edge/r_state.h index 98d6939d8..1b68d1630 100644 --- a/source_files/edge/r_state.h +++ b/source_files/edge/r_state.h @@ -25,6 +25,8 @@ #pragma once +#include + // Need data structure definitions. #include "AlmostEquals.h" @@ -59,6 +61,9 @@ extern Line *level_lines; extern int total_level_sides; extern Side *level_sides; +extern std::unordered_map texture_clamp_s; +extern std::unordered_map texture_clamp_t; + // // POV data. // @@ -122,6 +127,53 @@ class RenderState return; enable_scissor_test_ = enabled; break; + case GL_LIGHTING: + if (enable_lighting_ == enabled) + return; + enable_lighting_ = enabled; + break; + case GL_COLOR_MATERIAL: + if (enable_color_material_ == enabled) + return; + enable_color_material_ = enabled; + break; + case GL_DEPTH_TEST: + if (enable_depth_test_ == enabled) + return; + enable_depth_test_ = enabled; + break; + case GL_STENCIL_TEST: + if (enable_stencil_test_ == enabled) + return; + enable_stencil_test_ = enabled; + break; + case GL_LINE_SMOOTH: + if (enable_line_smooth_ == enabled) + return; + enable_line_smooth_ = enabled; + break; + case GL_NORMALIZE: + if (enable_normalize_ == enabled) + return; + enable_normalize_ = enabled; + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + if (enable_clip_plane_[cap - GL_CLIP_PLANE0] == enabled) + return; + enable_clip_plane_[cap - GL_CLIP_PLANE0] = enabled; + break; +#ifndef EDGE_GL_ES2 + case GL_POLYGON_SMOOTH: + if (enable_polygon_smooth_ == enabled) + return; + enable_polygon_smooth_ = enabled; + break; +#endif default: FatalError("Unknown GL State %i", cap); } @@ -155,6 +207,19 @@ class RenderState ec_frame_stats.draw_state_change++; } + void DepthFunction(GLenum func) + { + if (func == depth_function_) + { + return; + } + + depth_function_ = func; + + glDepthFunc(depth_function_); + ec_frame_stats.draw_state_change++; + } + void CullFace(GLenum mode) { if (cull_face_ == mode) @@ -301,6 +366,49 @@ class RenderState ec_frame_stats.draw_state_change++; } + void SetNormal(const HMM_Vec3 &normal) + { + if (AlmostEquals(normal_vector_.X, normal.X) && AlmostEquals(normal_vector_.Y, normal.Y) + && AlmostEquals(normal_vector_.Z, normal.Z)) + { + return; + } + normal_vector_ = normal; + glNormal3fv((GLfloat *)&normal_vector_); + ec_frame_stats.draw_state_change++; + } + + void GLColor(const GLfloat *color) + { + if (AlmostEquals(color[0], gl_color_[0]) && AlmostEquals(color[1], gl_color_[1]) && + AlmostEquals(color[2], gl_color_[2]) && AlmostEquals(color[3], gl_color_[3])) + { + return; + } + + memcpy(gl_color_, color, 4 * sizeof(float)); + + glColor4fv(gl_color_); + ec_frame_stats.draw_state_change++; + } + + void GLColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) + { + if (AlmostEquals(r, gl_color_[0]) && AlmostEquals(g, gl_color_[1]) && + AlmostEquals(b, gl_color_[2]) && AlmostEquals(a, gl_color_[3])) + { + return; + } + + gl_color_[0] = r; + gl_color_[1] = g; + gl_color_[2] = b; + gl_color_[3] = a; + + glColor4fv(gl_color_); + ec_frame_stats.draw_state_change++; + } + void BlendFunction(GLenum sfactor, GLenum dfactor) { if (blend_source_factor_ == sfactor && blend_destination_factor_ == dfactor) @@ -356,140 +464,90 @@ class RenderState ec_frame_stats.draw_state_change++; } - void TextureWrapT(GLint param) + void TextureMinFilter(GLint param) { GLuint index = active_texture_ - GL_TEXTURE0; - if (texture_wrap_t_[index] == param) - { - return; - } - - texture_wrap_t_[index] = param; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texture_wrap_t_[index]); + texture_min_filter_[index] = param; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture_min_filter_[index]); ec_frame_stats.draw_state_change++; } - void ResetDefaultState() + void TextureMagFilter(GLint param) { - Disable(GL_BLEND); - BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - Disable(GL_ALPHA_TEST); - - DepthMask(true); - - CullFace(GL_BACK); - Disable(GL_CULL_FACE); - - Disable(GL_FOG); - - PolygonOffset(0, 0); + GLuint index = active_texture_ - GL_TEXTURE0; - for (int i = 0; i < 2; i++) - { - bind_texture_2d_[i] = 0; - texture_environment_mode_[i] = 0; - texture_environment_combine_rgb_[i] = 0; - texture_environment_source_0_rgb_[i] = 0; - texture_wrap_t_[i] = 0; - } + texture_mag_filter_[index] = param; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texture_mag_filter_[index]); + ec_frame_stats.draw_state_change++; } - void SetDefaultStateFull() + void TextureWrapS(GLint param) { - enable_blend_ = false; - glDisable(GL_BLEND); - ec_frame_stats.draw_state_change++; - - blend_source_factor_ = GL_SRC_ALPHA; - blend_destination_factor_ = GL_ONE_MINUS_SRC_ALPHA; - glBlendFunc(blend_source_factor_, blend_destination_factor_); - ec_frame_stats.draw_state_change++; - - for (int i = 0; i < 2; i++) - { - enable_texture_2d_[i] = false; - bind_texture_2d_[i] = 0; - glActiveTexture(GL_TEXTURE0 + i); - ec_frame_stats.draw_state_change++; - glBindTexture(GL_TEXTURE_2D, 0); - ec_frame_stats.draw_texture_change++; - ec_frame_stats.draw_state_change++; - glDisable(GL_TEXTURE_2D); - ec_frame_stats.draw_state_change++; - - texture_environment_mode_[i] = 0; - texture_environment_combine_rgb_[i] = 0; - texture_environment_source_0_rgb_[i] = 0; - texture_wrap_t_[i] = 0; - } - - active_texture_ = GL_TEXTURE0; - glActiveTexture(active_texture_); - ec_frame_stats.draw_state_change++; - - enable_alpha_test_ = false; - glDisable(GL_ALPHA_TEST); - ec_frame_stats.draw_state_change++; - - alpha_function_ = GL_GREATER; - alpha_function_reference_ = 0.0f; - - glAlphaFunc(alpha_function_, alpha_function_reference_); - ec_frame_stats.draw_state_change++; - - depth_mask_ = true; - glDepthMask(GL_TRUE); - ec_frame_stats.draw_state_change++; - - cull_face_ = GL_BACK; - glCullFace(cull_face_); - ec_frame_stats.draw_state_change++; - enable_cull_face_ = false; - glDisable(GL_CULL_FACE); - ec_frame_stats.draw_state_change++; + GLuint index = active_texture_ - GL_TEXTURE0; - clear_red_ = 0.0f; - clear_green_ = 0.0f; - clear_blue_ = 0.0f; - clear_alpha_ = 1.0f; - glClearColor(clear_red_, clear_green_, clear_blue_, clear_alpha_); + // We do it regardless of the cached value; functions should check + // texture environments against the appropriate unordered_map and + // know if a change needs to occur + texture_wrap_s_[index] = param; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texture_wrap_s_[index]); ec_frame_stats.draw_state_change++; + } - fog_mode_ = GL_LINEAR; - glFogi(GL_FOG_MODE, fog_mode_); - ec_frame_stats.draw_state_change++; + void TextureWrapT(GLint param) + { + GLuint index = active_texture_ - GL_TEXTURE0; - fog_color_[0] = 0.0f; - fog_color_[1] = 0.0f; - fog_color_[2] = 0.0f; - fog_color_[3] = 1.0f; - glFogfv(GL_FOG_COLOR, fog_color_); + // We do it regardless of the cached value; functions should check + // texture environments against the appropriate unordered_map and + // know if a change needs to occur + texture_wrap_t_[index] = param; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texture_wrap_t_[index]); ec_frame_stats.draw_state_change++; + } - enable_fog_ = false; - glDisable(GL_FOG); - ec_frame_stats.draw_state_change++; - fog_start_ = 0.0f; - fog_end_ = 0.0f; - glFogf(GL_FOG_START, fog_start_); - ec_frame_stats.draw_state_change++; - glFogf(GL_FOG_END, fog_end_); + void MultiTexCoord(GLuint tex, const HMM_Vec2 *coords) + { + if (enable_texture_2d_[tex - GL_TEXTURE0] == false) + return; + if (tex == GL_TEXTURE0 && enable_texture_2d_[1] == false) + glTexCoord2fv((GLfloat *)coords); + else + glMultiTexCoord2fv(tex, (GLfloat *)coords); ec_frame_stats.draw_state_change++; + } - fog_density_ = 0.0f; - glFogf(GL_FOG_DENSITY, fog_density_); + void Hint(GLenum target, GLenum mode) + { + glHint(target, mode); ec_frame_stats.draw_state_change++; + } - polygon_offset_factor_ = 0; - polygon_offset_units_ = 0; - glPolygonOffset(polygon_offset_factor_, polygon_offset_units_); + void LineWidth(float width) + { + if (AlmostEquals(width, line_width_)) + { + return; + } + line_width_ = width; + glLineWidth(line_width_); ec_frame_stats.draw_state_change++; + } - enable_scissor_test_ = false; - glDisable(GL_SCISSOR_TEST); - ec_frame_stats.draw_state_change++; + void DeleteTexture(const GLuint *tex_id) + { + if (tex_id && *tex_id > 0) + { + texture_clamp_s.erase(*tex_id); + texture_clamp_t.erase(*tex_id); + glDeleteTextures(1, tex_id); + // We don't need to actually perform a texture bind, + // but these should be cleared out to ensure + // we aren't mistakenly using a tex_id that does not + // correlate to the same texture anymore + bind_texture_2d_[0] = 0; + bind_texture_2d_[1] = 0; + } } int frameStateChanges_ = 0; @@ -504,6 +562,8 @@ class RenderState bool enable_scissor_test_; + bool enable_clip_plane_[6]; + GLfloat clear_red_; GLfloat clear_green_; GLfloat clear_blue_; @@ -515,12 +575,17 @@ class RenderState GLint texture_environment_mode_[2]; GLint texture_environment_combine_rgb_[2]; GLint texture_environment_source_0_rgb_[2]; + GLint texture_min_filter_[2]; + GLint texture_mag_filter_[2]; + GLint texture_wrap_s_[2]; GLint texture_wrap_t_[2]; GLuint bind_texture_2d_[2]; - GLenum active_texture_; + GLenum active_texture_ = GL_TEXTURE0; + bool enable_depth_test_; bool depth_mask_; + GLenum depth_function_; GLfloat polygon_offset_factor_; GLfloat polygon_offset_units_; @@ -529,15 +594,34 @@ class RenderState GLenum alpha_function_; GLfloat alpha_function_reference_; + bool enable_lighting_; + + bool enable_color_material_; + + bool enable_stencil_test_; + + bool enable_line_smooth_; + float line_width_; + + bool enable_normalize_; + +#ifndef EDGE_GL_ES2 + bool enable_polygon_smooth_; +#endif + bool enable_fog_; GLint fog_mode_; GLfloat fog_start_; GLfloat fog_end_; GLfloat fog_density_; GLfloat fog_color_[4]; + + HMM_Vec3 normal_vector_; + + GLfloat gl_color_[4]; }; -RenderState *GetRenderState(); +extern RenderState *global_render_state; //--- editor settings --- // vi:ts=4:sw=4:noexpandtab diff --git a/source_files/edge/r_texgl.cc b/source_files/edge/r_texgl.cc index c616c524b..8da695a50 100644 --- a/source_files/edge/r_texgl.cc +++ b/source_files/edge/r_texgl.cc @@ -38,9 +38,10 @@ #include "w_texture.h" #include "w_wad.h" -// clamp cache used by runits to avoid an extremely expensive gl tex param -// lookup -extern std::unordered_map texture_clamp; +// clamp cache used by runits to avoid extremely expensive gl tex param +// lookups +extern std::unordered_map texture_clamp_s; +extern std::unordered_map texture_clamp_t; int MakeValidTextureSize(int value) { @@ -154,20 +155,21 @@ GLuint UploadTexture(ImageData *img, int flags, int max_pix) GLuint id; glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_2D, id); + global_render_state->BindTexture(id); GLint tmode = GL_REPEAT; if (clamp) tmode = renderer_dumb_clamp.d_ ? GL_CLAMP : GL_CLAMP_TO_EDGE; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tmode); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tmode); + global_render_state->TextureWrapS(tmode); + global_render_state->TextureWrapT(tmode); - texture_clamp.emplace(id, tmode); + texture_clamp_s.emplace(id, tmode); + texture_clamp_t.emplace(id, tmode); // magnification mode - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, smooth ? GL_LINEAR : GL_NEAREST); + global_render_state->TextureMagFilter(smooth ? GL_LINEAR : GL_NEAREST); // minification mode int mip_level = HMM_Clamp(0, image_mipmapping, 2); @@ -183,7 +185,7 @@ GLuint UploadTexture(ImageData *img, int flags, int max_pix) GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR}; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minif_modes[(smooth ? 3 : 0) + (nomip ? 0 : mip_level)]); + global_render_state->TextureMinFilter(minif_modes[(smooth ? 3 : 0) + (nomip ? 0 : mip_level)]); for (int mip = 0;; mip++) { @@ -204,13 +206,6 @@ GLuint UploadTexture(ImageData *img, int flags, int max_pix) new_w = HMM_MAX(1, new_w / 2); new_h = HMM_MAX(1, new_h / 2); - - // -AJA- 2003/12/05: workaround for Radeon 7500 driver bug, which - // incorrectly draws the 1x1 mip texture as black. -#ifndef _WIN32 - if (new_w == 1 && new_h == 1) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mip); -#endif } return id; diff --git a/source_files/edge/r_things.cc b/source_files/edge/r_things.cc index 3e2b5dfc3..d17af181b 100644 --- a/source_files/edge/r_things.cc +++ b/source_files/edge/r_things.cc @@ -248,7 +248,7 @@ static void RenderPSprite(PlayerSprite *psp, int which, Player *player, RegionPr y1t = y2t = view_window_height * ty2 / coord_H; // clip psprite to view window - glEnable(GL_SCISSOR_TEST); + global_render_state->Enable(GL_SCISSOR_TEST); glScissor(view_window_x, view_window_y, view_window_width, view_window_height); @@ -437,11 +437,7 @@ static void RenderPSprite(PlayerSprite *psp, int which, Player *player, RegionPr FinishUnitBatch(); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); - glAlphaFunc(GL_GREATER, 0); + global_render_state->Disable(GL_SCISSOR_TEST); } static const RGBAColor crosshair_colors[8] = { @@ -474,38 +470,35 @@ static void DrawStdCrossHair(void) float g = epi::GetRGBAGreen(color) * intensity / 255.0f; float b = epi::GetRGBABlue(color) * intensity / 255.0f; + sg_color sgcol = {r, g, b, 1.0f}; + float x = view_window_x + view_window_width / 2; float y = view_window_y + view_window_height / 2; float w = RoundToInteger(current_screen_width * crosshair_size.f_ / 640.0f); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - glBindTexture(GL_TEXTURE_2D, tex_id); - - // additive blending - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - - glColor3f(r, g, b); - - glBegin(GL_POLYGON); - - glTexCoord2f(0.0f, 0.0f); - glVertex2f(x - w, y - w); - glTexCoord2f(0.0f, 1.0f); - glVertex2f(x - w, y + w); - glTexCoord2f(1.0f, 1.0f); - glVertex2f(x + w, y + w); - glTexCoord2f(1.0f, 0.0f); - glVertex2f(x + w, y - w); - - glEnd(); + StartUnitBatch(false); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + RendererVertex *glvert = + BeginRenderUnit(GL_POLYGON, 4, GL_MODULATE, tex_id, + (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingAdd); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x - w, y - w, 0.0f}}; + glvert++->texture_coordinates[0] = {{0.0f, 0.0f}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x - w, y + w, 0.0f}}; + glvert++->texture_coordinates[0] = {{0.0f, 1.0f}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x + w, y + w, 0.0f}}; + glvert++->texture_coordinates[0] = {{1.0f, 1.0f}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->position = {{x + w, y - w, 0.0f}}; + glvert++->texture_coordinates[0] = {{1.0f, 0.0f}}; + + EndRenderUnit(4); - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); + FinishUnitBatch(); } void RenderWeaponSprites(Player *p) diff --git a/source_files/edge/r_units.cc b/source_files/edge/r_units.cc index cf71174ee..dd426e314 100644 --- a/source_files/edge/r_units.cc +++ b/source_files/edge/r_units.cc @@ -49,13 +49,13 @@ EDGE_DEFINE_CONSOLE_VARIABLE(renderer_dumb_clamp, "1", kConsoleVariableFlagNone) EDGE_DEFINE_CONSOLE_VARIABLE(renderer_dumb_clamp, "0", kConsoleVariableFlagNone) #endif -static constexpr uint16_t kMaximumLocalVertices = 65535; static constexpr uint16_t kMaximumLocalUnits = 1024; extern ConsoleVariable draw_culling; extern ConsoleVariable cull_fog_color; -std::unordered_map texture_clamp; +std::unordered_map texture_clamp_s; +std::unordered_map texture_clamp_t; // a single unit (polygon, quad, etc) to pass to the GL struct RendererUnit @@ -224,39 +224,13 @@ struct Compare_Unit_pred } }; -static void EnableCustomEnvironment(GLuint env, bool enable) -{ - RenderState *state = GetRenderState(); - switch (env) - { - case uint32_t(kTextureEnvironmentSkipRGB): - if (enable) - { - state->TextureEnvironmentMode(GL_COMBINE); - state->TextureEnvironmentCombineRGB(GL_REPLACE); - state->TextureEnvironmentSource0RGB(GL_PREVIOUS); - } - else - { - /* no need to modify TEXTURE_ENV_MODE */ - state->TextureEnvironmentCombineRGB(GL_MODULATE); - state->TextureEnvironmentSource0RGB(GL_TEXTURE); - } - break; - - default: - FatalError("INTERNAL ERROR: no such custom env: %08x\n", env); - } -} - static inline void RendererSendRawVector(const RendererVertex *V) { - glColor4fv(V->rgba_color); - - glMultiTexCoord2fv(GL_TEXTURE0, (const GLfloat *)(&V->texture_coordinates[0])); - glMultiTexCoord2fv(GL_TEXTURE1, (const GLfloat *)(&V->texture_coordinates[1])); + global_render_state->GLColor(V->rgba_color); + global_render_state->SetNormal(V->normal); - glNormal3fv((const GLfloat *)(&V->normal)); + global_render_state->MultiTexCoord(GL_TEXTURE0, &V->texture_coordinates[0]); + global_render_state->MultiTexCoord(GL_TEXTURE1, &V->texture_coordinates[1]); // vertex must be last glVertex3fv((const GLfloat *)(&V->position)); @@ -275,17 +249,6 @@ void RenderCurrentUnits(void) if (current_render_unit == 0) return; - RenderState *state = GetRenderState(); - - GLuint active_tex[2] = {0, 0}; - GLuint active_env[2] = {0, 0}; - - int active_pass = 0; - int active_blending = 0; - - RGBAColor active_fog_rgb = kRGBANoValue; - float active_fog_density = 0; - for (int i = 0; i < current_render_unit; i++) local_unit_map[i] = &local_units[i]; @@ -317,15 +280,15 @@ void RenderCurrentUnits(void) break; } - state->ClearColor(fogColor.r, fogColor.g, fogColor.b, 1.0f); - state->FogMode(GL_LINEAR); - state->FogColor(fogColor.r, fogColor.g, fogColor.b, 1.0f); - state->FogStart(renderer_far_clip.f_ - 750.0f); - state->FogEnd(renderer_far_clip.f_ - 250.0f); - state->Enable(GL_FOG); + global_render_state->ClearColor(fogColor.r, fogColor.g, fogColor.b, 1.0f); + global_render_state->FogMode(GL_LINEAR); + global_render_state->FogColor(fogColor.r, fogColor.g, fogColor.b, 1.0f); + global_render_state->FogStart(renderer_far_clip.f_ - 750.0f); + global_render_state->FogEnd(renderer_far_clip.f_ - 250.0f); + global_render_state->Enable(GL_FOG); } else - state->FogMode(GL_EXP); // if needed + global_render_state->FogMode(GL_EXP); // if needed for (int j = 0; j < current_render_unit; j++) { @@ -335,155 +298,169 @@ void RenderCurrentUnits(void) EPI_ASSERT(unit->count > 0); - // detect changes in texture/alpha/blending state - - if (!draw_culling.d_ && unit->fog_color != kRGBANoValue) + if (!draw_culling.d_ && unit->fog_color != kRGBANoValue && !(unit->blending & kBlendingNoFog)) { - if (unit->fog_color != active_fog_rgb) - { - active_fog_rgb = unit->fog_color; - sg_color fc = sg_make_color_1i(active_fog_rgb); - state->ClearColor(fc.r, fc.g, fc.b, 1.0f); - state->FogColor(fc.r, fc.g, fc.b, 1.0f); - } - if (!AlmostEquals(unit->fog_density, active_fog_density)) - { - active_fog_density = unit->fog_density; - state->FogDensity(std::log1p(active_fog_density)); - } - if (active_fog_density > 0.00009f) - state->Enable(GL_FOG); + float density = unit->fog_density; + sg_color fc = sg_make_color_1i(unit->fog_color); + global_render_state->ClearColor(fc.r, fc.g, fc.b, 1.0f); + global_render_state->FogColor(fc.r, fc.g, fc.b, 1.0f); + global_render_state->FogDensity(std::log1p(density)); + if (density > 0.00009f) + global_render_state->Enable(GL_FOG); else - state->Disable(GL_FOG); + global_render_state->Disable(GL_FOG); } - else if (!draw_culling.d_) - state->Disable(GL_FOG); + else if (!draw_culling.d_ || (unit->blending & kBlendingNoFog)) + global_render_state->Disable(GL_FOG); - if (active_pass != unit->pass) - { - active_pass = unit->pass; + global_render_state->PolygonOffset(0, -unit->pass); - state->PolygonOffset(0, -active_pass); + if (unit->blending & kBlendingLess) + { + // Alpha function is updated below, because the alpha + // value can change from unit to unit while the + // kBlendingLess flag remains set. + global_render_state->Enable(GL_ALPHA_TEST); } - - if ((active_blending ^ unit->blending) & (kBlendingMasked | kBlendingLess)) + else if (unit->blending & kBlendingMasked) { - if (unit->blending & kBlendingLess) - { - // state->AlphaFunction is updated below, because the alpha - // value can change from unit to unit while the - // kBlendingLess flag remains set. - state->Enable(GL_ALPHA_TEST); - } - else if (unit->blending & kBlendingMasked) - { - state->Enable(GL_ALPHA_TEST); - state->AlphaFunction(GL_GREATER, 0); - } - else - state->Disable(GL_ALPHA_TEST); + global_render_state->Enable(GL_ALPHA_TEST); + global_render_state->AlphaFunction(GL_GREATER, 0); } - - if ((active_blending ^ unit->blending) & (kBlendingAlpha | kBlendingAdd)) + else if (unit->blending & kBlendingGEqual) { - if (unit->blending & kBlendingAdd) - { - state->Enable(GL_BLEND); - state->BlendFunction(GL_SRC_ALPHA, GL_ONE); - } - else if (unit->blending & kBlendingAlpha) - { - state->Enable(GL_BLEND); - state->BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else - state->Disable(GL_BLEND); + global_render_state->Enable(GL_ALPHA_TEST); + global_render_state->AlphaFunction(GL_GEQUAL, 1.0f - local_verts[unit->first].rgba_color[3]); } + else + global_render_state->Disable(GL_ALPHA_TEST); - if ((active_blending ^ unit->blending) & (kBlendingCullBack | kBlendingCullFront)) + if (unit->blending & kBlendingAdd) { - if (unit->blending & (kBlendingCullBack | kBlendingCullFront)) - { - state->Enable(GL_CULL_FACE); - state->CullFace((unit->blending & kBlendingCullFront) ? GL_FRONT : GL_BACK); - } - else - state->Disable(GL_CULL_FACE); + global_render_state->Enable(GL_BLEND); + global_render_state->BlendFunction(GL_SRC_ALPHA, GL_ONE); + } + else if (unit->blending & kBlendingAlpha) + { + global_render_state->Enable(GL_BLEND); + global_render_state->BlendFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else if (unit->blending & kBlendingInvert) + { + global_render_state->Enable(GL_BLEND); + global_render_state->BlendFunction(GL_ONE_MINUS_DST_COLOR, GL_ZERO); + } + else if (unit->blending & kBlendingNegativeGamma) + { + global_render_state->Enable(GL_BLEND); + global_render_state->BlendFunction(GL_ZERO, GL_SRC_COLOR); } + else if (unit->blending & kBlendingPositiveGamma) + { + global_render_state->Enable(GL_BLEND); + global_render_state->BlendFunction(GL_DST_COLOR, GL_ONE); + } + else + global_render_state->Disable(GL_BLEND); - if ((active_blending ^ unit->blending) & kBlendingNoZBuffer) + if (unit->blending & (kBlendingCullBack | kBlendingCullFront)) { - state->DepthMask((unit->blending & kBlendingNoZBuffer) ? false : true); + global_render_state->Enable(GL_CULL_FACE); + global_render_state->CullFace((unit->blending & kBlendingCullFront) ? GL_FRONT : GL_BACK); } + else + global_render_state->Disable(GL_CULL_FACE); - active_blending = unit->blending; + global_render_state->DepthMask((unit->blending & kBlendingNoZBuffer) ? false : true); - if (active_blending & kBlendingLess) + if (unit->blending & kBlendingLess) { // NOTE: assumes alpha is constant over whole polygon float a = local_verts[unit->first].rgba_color[3]; - state->AlphaFunction(GL_GREATER, a * 0.66f); + global_render_state->AlphaFunction(GL_GREATER, a * 0.66f); } - GLint old_clamp = kDummyClamp; + GLint old_clamp_s = kDummyClamp; + GLint old_clamp_t = kDummyClamp; for (int t = 1; t >= 0; t--) { - if (active_tex[t] != unit->texture[t] || active_env[t] != unit->environment_mode[t]) - { - state->ActiveTexture(GL_TEXTURE0 + t); - } + global_render_state->ActiveTexture(GL_TEXTURE0 + t); - if (draw_culling.d_) + if (draw_culling.d_ && !(unit->blending & kBlendingNoFog)) { if (unit->pass > 0) - state->Disable(GL_FOG); + global_render_state->Disable(GL_FOG); else - state->Enable(GL_FOG); + global_render_state->Enable(GL_FOG); } - if (active_tex[t] != unit->texture[t]) + if (!unit->texture[t]) + global_render_state->Disable(GL_TEXTURE_2D); + else { - if (unit->texture[t] == 0) - state->Disable(GL_TEXTURE_2D); - else if (active_tex[t] == 0) - state->Enable(GL_TEXTURE_2D); - - if (unit->texture[t] != 0) - state->BindTexture(unit->texture[t]); - - active_tex[t] = unit->texture[t]; + global_render_state->Enable(GL_TEXTURE_2D); + global_render_state->BindTexture(unit->texture[t]); + } - if (!t && (active_blending & kBlendingClampY) && active_tex[0] != 0) + if (!t && (unit->blending & kBlendingRepeatX) && unit->texture[0]) + { + auto existing = texture_clamp_s.find(unit->texture[0]); + if (existing != texture_clamp_s.end()) { - auto existing = texture_clamp.find(active_tex[0]); - if (existing != texture_clamp.end()) + if (existing->second != GL_REPEAT) { - old_clamp = existing->second; + old_clamp_s = existing->second; + global_render_state->TextureWrapS(GL_REPEAT); } - - // This is very expensive, thus the map - // glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - // &old_clamp); - state->TextureWrapT(renderer_dumb_clamp.d_ ? GL_CLAMP : GL_CLAMP_TO_EDGE); } + else + global_render_state->TextureWrapS(GL_REPEAT); } - if (active_env[t] != unit->environment_mode[t]) + if (!t && (unit->blending & (kBlendingClampY|kBlendingRepeatY)) && unit->texture[0]) { - if (active_env[t] == kTextureEnvironmentSkipRGB) + auto existing = texture_clamp_t.find(unit->texture[0]); + if (existing != texture_clamp_t.end()) { - EnableCustomEnvironment(active_env[t], false); + if (unit->blending & kBlendingClampY) + { + if (existing->second != (renderer_dumb_clamp.d_ ? GL_CLAMP : GL_CLAMP_TO_EDGE)) + { + old_clamp_t = existing->second; + global_render_state->TextureWrapT(renderer_dumb_clamp.d_ ? GL_CLAMP : GL_CLAMP_TO_EDGE); + } + } + else + { + if (existing->second != GL_REPEAT) + { + old_clamp_t = existing->second; + global_render_state->TextureWrapT(GL_REPEAT); + } + } } - - if (unit->environment_mode[t] == kTextureEnvironmentSkipRGB) + else { - EnableCustomEnvironment(unit->environment_mode[t], true); + if (unit->blending & kBlendingClampY) + global_render_state->TextureWrapT(renderer_dumb_clamp.d_ ? GL_CLAMP : GL_CLAMP_TO_EDGE); + else + global_render_state->TextureWrapT(GL_REPEAT); } - else if (unit->environment_mode[t] != kTextureEnvironmentDisable) - state->TextureEnvironmentMode(unit->environment_mode[t]); + } - active_env[t] = unit->environment_mode[t]; + if (unit->environment_mode[t] == kTextureEnvironmentSkipRGB) + { + global_render_state->TextureEnvironmentMode(GL_COMBINE); + global_render_state->TextureEnvironmentCombineRGB(GL_REPLACE); + global_render_state->TextureEnvironmentSource0RGB(GL_PREVIOUS); + } + else + { + if (unit->environment_mode[t] != kTextureEnvironmentDisable) + global_render_state->TextureEnvironmentMode(unit->environment_mode[t]); + global_render_state->TextureEnvironmentCombineRGB(GL_MODULATE); + global_render_state->TextureEnvironmentSource0RGB(GL_TEXTURE); } } @@ -496,31 +473,25 @@ void RenderCurrentUnits(void) glEnd(); +#if defined(EDGE_GL_ES2) + gl4es_flush(); +#endif + // restore the clamping mode - if (old_clamp != kDummyClamp) + if (old_clamp_s != kDummyClamp) + { + global_render_state->TextureWrapS(old_clamp_s); + } + if (old_clamp_t != kDummyClamp) { - state->TextureWrapT(old_clamp); + global_render_state->TextureWrapT(old_clamp_t); } } // all done current_render_vert = current_render_unit = 0; - state->PolygonOffset(0, 0); - - for (int t = 1; t >= 0; t--) - { - state->ActiveTexture(GL_TEXTURE0 + t); - - if (active_env[t] == kTextureEnvironmentSkipRGB) - { - EnableCustomEnvironment(active_env[t], false); - } - state->TextureEnvironmentMode(GL_MODULATE); - state->Disable(GL_TEXTURE_2D); - } - - state->ResetDefaultState(); + global_render_state->PolygonOffset(0, 0); } //--- editor settings --- diff --git a/source_files/edge/r_units.h b/source_files/edge/r_units.h index e09b4d79c..2adbe8d1b 100644 --- a/source_files/edge/r_units.h +++ b/source_files/edge/r_units.h @@ -31,6 +31,8 @@ #include "sokol_color.h" constexpr uint16_t kDummyClamp = 789; +constexpr uint8_t kMaximumPolygonVertices = 64; +constexpr uint16_t kMaximumLocalVertices = 65535; // a single vertex to pass to the GPU struct RendererVertex @@ -60,6 +62,19 @@ enum BlendingMode kBlendingCullFront = (1 << 5), // enable front-face culling kBlendingNoZBuffer = (1 << 6), // don't update the Z buffer kBlendingClampY = (1 << 7), // force texture to be Y clamped + + kBlendingNoFog = (1 << 8), // force disable fog (including culling fog) + + kBlendingRepeatX = (1 << 9), // force texture to repeat on X axis + kBlendingRepeatY = (1 << 10), // force texture to repeat on Y axis + + kBlendingGEqual = (1 << 11), // drop fragments when alpha >= 1.0f - color.a + // Dasho - This is super specific and only + // used by the "pixelfade" wipe :/ + + kBlendingInvert = (1 << 12), // color inversion (simple invuln fx) + kBlendingNegativeGamma = (1 << 13), + kBlendingPositiveGamma = (1 << 14) }; enum CustomTextureEnvironment diff --git a/source_files/edge/r_wipe.cc b/source_files/edge/r_wipe.cc index 7bfc4a0b1..d5e78e1b6 100644 --- a/source_files/edge/r_wipe.cc +++ b/source_files/edge/r_wipe.cc @@ -34,6 +34,7 @@ #include "r_image.h" #include "r_modes.h" #include "r_texgl.h" +#include "r_units.h" // we're limited to one wipe at a time... static ScreenWipe current_wipe_effect = kScreenWipeNone; @@ -185,7 +186,7 @@ void StopWipe(void) if (current_wipe_texture != 0) { - glDeleteTextures(1, ¤t_wipe_texture); + global_render_state->DeleteTexture(¤t_wipe_texture); current_wipe_texture = 0; } } @@ -194,71 +195,54 @@ void StopWipe(void) static void RendererWipeFading(float how_far) { - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - glBindTexture(GL_TEXTURE_2D, current_wipe_texture); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f - how_far); - - glBegin(GL_QUADS); - - glTexCoord2f(0.0f, 0.0f); - glVertex2i(0, 0); - glTexCoord2f(0.0f, current_wipe_top); - glVertex2i(0, current_screen_height); - glTexCoord2f(current_wipe_right, current_wipe_top); - glVertex2i(current_screen_width, current_screen_height); - glTexCoord2f(current_wipe_right, 0.0f); - glVertex2i(current_screen_width, 0); - - glEnd(); - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); + sg_color sgcol = {1.0f, 1.0f, 1.0f, 1.0f - how_far}; + + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, current_wipe_texture, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingAlpha); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{0.0f, 0.0f}}; + glvert++->position = {{0, 0, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{0.0f, current_wipe_top}}; + glvert++->position = {{0, (float)current_screen_height, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{current_wipe_right, current_wipe_top}}; + glvert++->position = {{(float)current_screen_width, (float)current_screen_height, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{current_wipe_right, 0.0f}}; + glvert->position = {{(float)current_screen_width, 0, 0}}; + + EndRenderUnit(4); } static void RendererWipePixelfade(float how_far) { - glEnable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - - glAlphaFunc(GL_GEQUAL, how_far); - - glBindTexture(GL_TEXTURE_2D, current_wipe_texture); - glColor3f(1.0f, 1.0f, 1.0f); - - glBegin(GL_QUADS); - - glTexCoord2f(0.0f, 0.0f); - glVertex2i(0, 0); - glTexCoord2f(0.0f, current_wipe_top); - glVertex2i(0, current_screen_height); - glTexCoord2f(current_wipe_right, current_wipe_top); - glVertex2i(current_screen_width, current_screen_height); - glTexCoord2f(current_wipe_right, 0.0f); - glVertex2i(current_screen_width, 0); - - glEnd(); - - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - - glAlphaFunc(GL_GREATER, 0); + sg_color sgcol = {1.0f, 1.0f, 1.0f, 1.0f - how_far}; + + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, current_wipe_texture, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingGEqual); + + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{0.0f, 0.0f}}; + glvert++->position = {{0, 0, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{0.0f, current_wipe_top}}; + glvert++->position = {{0, (float)current_screen_height, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{current_wipe_right, current_wipe_top}}; + glvert++->position = {{(float)current_screen_width, (float)current_screen_height, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{current_wipe_right, 0.0f}}; + glvert->position = {{(float)current_screen_width, 0, 0}}; + + EndRenderUnit(4); } static void RendererWipeMelt(void) { - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); + sg_color sgcol = {1.0f, 1.0f, 1.0f, 1.0f}; + RendererVertex *glvert = BeginRenderUnit(GL_QUAD_STRIP, (kMeltSections + 1) * 2, GL_MODULATE, current_wipe_texture, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNone); - glBindTexture(GL_TEXTURE_2D, current_wipe_texture); - glColor3f(1.0f, 1.0f, 1.0f); - - glBegin(GL_QUAD_STRIP); - - for (int x = 0; x <= kMeltSections; x++) + for (int x = 0; x <= kMeltSections; x++, glvert++) { int yoffs = 0; @@ -272,17 +256,15 @@ static void RendererWipeMelt(void) float tx = current_wipe_right * (float)x / kMeltSections; - glTexCoord2f(tx, current_wipe_top); - glVertex2f(sx, sy); - - glTexCoord2f(tx, 0.0f); - glVertex2f(sx, sy - current_screen_height); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx, current_wipe_top}}; + glvert++->position = {{sx, sy, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{tx, 0.0f}}; + glvert->position = {{sx, sy - current_screen_height, 0}}; } - glEnd(); - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); + EndRenderUnit((kMeltSections + 1) * 2); } static void RendererWipeSlide(float how_far, float dx, float dy) @@ -290,27 +272,24 @@ static void RendererWipeSlide(float how_far, float dx, float dy) dx *= how_far; dy *= how_far; - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - glBindTexture(GL_TEXTURE_2D, current_wipe_texture); - glColor3f(1.0f, 1.0f, 1.0f); - - glBegin(GL_QUADS); + sg_color sgcol = {1.0f, 1.0f, 1.0f, 1.0f}; - glTexCoord2f(0.0f, 0.0f); - glVertex2f(dx, dy); - glTexCoord2f(0.0f, current_wipe_top); - glVertex2f(dx, dy + current_screen_height); - glTexCoord2f(current_wipe_right, current_wipe_top); - glVertex2f(dx + current_screen_width, dy + current_screen_height); - glTexCoord2f(current_wipe_right, 0.0f); - glVertex2f(dx + current_screen_width, dy); + RendererVertex *glvert = BeginRenderUnit(GL_QUADS, 4, GL_MODULATE, current_wipe_texture, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNone); - glEnd(); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{0.0f, 0.0f}}; + glvert++->position = {{dx, dy, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{0.0f, current_wipe_top}}; + glvert++->position = {{dx, dy + current_screen_height, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{current_wipe_right, current_wipe_top}}; + glvert++->position = {{dx + current_screen_width, dy + current_screen_height, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{current_wipe_right, 0.0f}}; + glvert->position = {{dx + current_screen_width, dy, 0}}; - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); + EndRenderUnit(4); } static void RendererWipeDoors(float how_far) @@ -318,11 +297,8 @@ static void RendererWipeDoors(float how_far) float dx = cos(how_far * HMM_PI / 2) * (current_screen_width / 2); float dy = sin(how_far * HMM_PI / 2) * (current_screen_height / 3); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - glBindTexture(GL_TEXTURE_2D, current_wipe_texture); - glColor3f(1.0f, 1.0f, 1.0f); + sg_color sgcol = {1.0f, 1.0f, 1.0f, 1.0f}; + RendererVertex *glvert = nullptr; for (int column = 0; column < 5; column++) { @@ -340,36 +316,30 @@ static void RendererWipeDoors(float how_far) float v_y1 = (side == 0) ? (dy * e) : (dy * (e + 0.2f)); float v_y2 = (side == 1) ? (dy * e) : (dy * (e + 0.2f)); - glBegin(GL_QUAD_STRIP); + glvert = BeginRenderUnit(GL_QUAD_STRIP, 12, GL_MODULATE, current_wipe_texture, (GLuint)kTextureEnvironmentDisable, 0, 0, kBlendingNone); - for (int row = 0; row <= 5; row++) + for (int row = 0; row <= 5; row++, glvert++) { float t_y = current_wipe_top * row / 5.0f; float j1 = (current_screen_height - v_y1 * 2.0f) / 5.0f; float j2 = (current_screen_height - v_y2 * 2.0f) / 5.0f; - glTexCoord2f(t_x2 * current_wipe_right, t_y); - glVertex2f(v_x2, v_y2 + j2 * row); - - glTexCoord2f(t_x1 * current_wipe_right, t_y); - glVertex2f(v_x1, v_y1 + j1 * row); + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{t_x2 * current_wipe_right, t_y}}; + glvert++->position = {{v_x2, v_y2 + j2 * row, 0}}; + memcpy(&glvert->rgba_color, &sgcol, 4 * sizeof(float)); + glvert->texture_coordinates[0] = {{t_x1 * current_wipe_right, t_y}}; + glvert->position = {{v_x1, v_y1 + j1 * row, 0}}; } - glEnd(); + EndRenderUnit(12); } } - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); } bool DoWipe(void) { - // - // NOTE: we assume 2D project matrix is already setup. - // - if (current_wipe_effect == kScreenWipeNone || current_wipe_texture == 0) return true; @@ -398,6 +368,8 @@ bool DoWipe(void) else how_far = (float)current_wipe_progress / 40.0f; + StartUnitBatch(false); + switch (current_wipe_effect) { case kScreenWipeMelt: @@ -436,6 +408,8 @@ bool DoWipe(void) break; } + FinishUnitBatch(); + return false; } From db97246b85e61f802b6669f5d2aade1a8efd7eca Mon Sep 17 00:00:00 2001 From: dashodanger <> Date: Tue, 19 Nov 2024 14:30:33 -0700 Subject: [PATCH 2/2] Add string.h include for nix builds --- source_files/edge/r_state.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source_files/edge/r_state.h b/source_files/edge/r_state.h index 1b68d1630..73c4891b3 100644 --- a/source_files/edge/r_state.h +++ b/source_files/edge/r_state.h @@ -25,6 +25,8 @@ #pragma once +#include + #include // Need data structure definitions.