From 749e70b9885ff61f32455ab9220115e6cfbbb1dc Mon Sep 17 00:00:00 2001 From: Jaime Moreira Date: Mon, 15 Jul 2024 09:05:21 -0400 Subject: [PATCH] GL1 unified draw calls, part 3 Batching / buffered procedure, applied to multitexture surfaces. This solves the issue with gl1_overbrightbits, when jumping between 0 and 2-4. --- src/client/refresh/gl1/gl1_buffer.c | 45 ++++++++++++++-- src/client/refresh/gl1/gl1_surf.c | 75 ++++----------------------- src/client/refresh/gl1/header/local.h | 2 + 3 files changed, 55 insertions(+), 67 deletions(-) diff --git a/src/client/refresh/gl1/gl1_buffer.c b/src/client/refresh/gl1/gl1_buffer.c index cbcbb5df..2632516f 100644 --- a/src/client/refresh/gl1/gl1_buffer.c +++ b/src/client/refresh/gl1/gl1_buffer.c @@ -61,7 +61,7 @@ R_ApplyGLBuffer(void) { // Properties of batched draws here GLint vtx_size; - qboolean texture, alpha, texenv_set; + qboolean texture, mtex, alpha, texenv_set; if (gl_buf.vtx_ptr == 0 || gl_buf.idx_ptr == 0) { @@ -71,7 +71,7 @@ R_ApplyGLBuffer(void) // defaults for drawing (mostly buf_singletex features) vtx_size = 3; texture = true; - alpha = texenv_set = false; + mtex = alpha = texenv_set = false; // choosing features by type switch (gl_buf.type) @@ -79,6 +79,9 @@ R_ApplyGLBuffer(void) case buf_2d: vtx_size = 2; break; + case buf_mtex: + mtex = true; + break; case buf_alpha: alpha = true; break; @@ -86,6 +89,8 @@ R_ApplyGLBuffer(void) break; } + R_EnableMultitexture(mtex); + if (alpha) { // the textures are prescaled up for a better @@ -130,7 +135,27 @@ R_ApplyGLBuffer(void) if (texture) { - R_Bind(gl_buf.texture[0]); + if (mtex) + { + // TMU 1: Lightmap texture + R_MBind(GL_TEXTURE1, gl_state.lightmap_textures + gl_buf.texture[1]); + + if (gl1_overbrightbits->value) + { + R_TexEnv(GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, gl1_overbrightbits->value); + } + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, gl_buf.tex[1]); + + // TMU 0: Color texture + R_MBind(GL_TEXTURE0, gl_buf.texture[0]); + } + else + { + R_Bind(gl_buf.texture[0]); + } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, gl_buf.tex[0]); @@ -159,6 +184,7 @@ void R_UpdateGLBuffer(buffered_draw_t type, int colortex, int lighttex, int flags, float alpha) { if ( gl_buf.type != type || gl_buf.texture[0] != colortex || + (gl_config.multitexture && type == buf_mtex && gl_buf.texture[1] != lighttex) || (type == buf_singletex && gl_buf.flags != flags) || (type == buf_alpha && gl_buf.alpha != alpha)) { @@ -279,3 +305,16 @@ R_BufferSingleTex(GLfloat s, GLfloat t) gl_buf.tex[0][tx++] = s; gl_buf.tex[0][tx++] = t; } + +/* + * Adds texture coordinates for color and lightmap + */ +void +R_BufferMultiTex(GLfloat cs, GLfloat ct, GLfloat ls, GLfloat lt) +{ + gl_buf.tex[0][tx] = cs; + gl_buf.tex[0][tx+1] = ct; + gl_buf.tex[1][tx] = ls; + gl_buf.tex[1][tx+1] = lt; + tx += 2; +} diff --git a/src/client/refresh/gl1/gl1_surf.c b/src/client/refresh/gl1/gl1_surf.c index d63d0ac9..25050188 100644 --- a/src/client/refresh/gl1/gl1_surf.c +++ b/src/client/refresh/gl1/gl1_surf.c @@ -573,15 +573,6 @@ R_RenderLightmappedPoly(entity_t *currententity, msurface_t *surf) float scroll; float *v; - R_MBind(GL_TEXTURE1, gl_state.lightmap_textures + surf->lightmaptexturenum); - - // Apply overbrightbits to TMU 1 (lightmap) - if (gl1_overbrightbits->value) - { - R_TexEnv(GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, gl1_overbrightbits->value); - } - c_brush_polys++; v = surf->polys->verts[0]; @@ -593,60 +584,19 @@ R_RenderLightmappedPoly(entity_t *currententity, msurface_t *surf) { scroll = -64.0; } - - YQ2_VLA(GLfloat, tex, 4 * nv); - unsigned int index_tex = 0; - - for (i = 0; i < nv; i++, v += VERTEXSIZE) - { - tex[index_tex++] = v[3] + scroll; - tex[index_tex++] = v[4]; - tex[index_tex++] = v[5]; - tex[index_tex++] = v[6]; - } - v = surf->polys->verts[0]; - - // Polygon - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, VERTEXSIZE * sizeof(GLfloat), v); - - // Texture - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - qglClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(GLfloat), tex); - - // Lightmap - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - qglClientActiveTexture(GL_TEXTURE1); - glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(GLfloat), tex + 2); - - // Draw the thing - glDrawArrays(GL_TRIANGLE_FAN, 0, nv); - - YQ2_VLAFREE(tex); } else { - // Polygon - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, VERTEXSIZE * sizeof(GLfloat), v); - - // Texture - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - qglClientActiveTexture(GL_TEXTURE0); - glTexCoordPointer(2, GL_FLOAT, VERTEXSIZE * sizeof(GLfloat), v + 3); - - // Lightmap - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - qglClientActiveTexture(GL_TEXTURE1); - glTexCoordPointer(2, GL_FLOAT, VERTEXSIZE * sizeof(GLfloat), v + 5); - - // Draw it - glDrawArrays(GL_TRIANGLE_FAN, 0, nv); + scroll = 0.0; } - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + R_SetBufferIndices(GL_TRIANGLE_FAN, nv); + + for (i = 0; i < nv; i++, v += VERTEXSIZE) + { + R_BufferVertex( v[0], v[1], v[2] ); + R_BufferMultiTex( v[3] + scroll, v[4], v[5], v[6] ); + } } /* Upload dynamic lights to each lightmap texture (multitexture path only) */ @@ -782,8 +732,6 @@ R_DrawTextureChains(entity_t *currententity) } else // multitexture { - R_EnableMultitexture(true); - for (i = 0, image = gltextures; i < numgltextures; i++, image++) { if (!image->registration_sequence || !image->texturechain) @@ -791,17 +739,18 @@ R_DrawTextureChains(entity_t *currententity) continue; } - R_MBind(GL_TEXTURE0, image->texnum); // setting it only once c_visible_textures++; for (s = image->texturechain; s; s = s->texturechain) { if (!(s->flags & SURF_DRAWTURB)) { + R_UpdateGLBuffer(buf_mtex, image->texnum, s->lightmaptexturenum, 0, 1); R_RenderLightmappedPoly(currententity, s); } } } + R_ApplyGLBuffer(); R_EnableMultitexture(false); // force disabling, SURF_DRAWTURB surfaces may not exist @@ -884,8 +833,7 @@ R_DrawInlineBModel(entity_t *currententity, const model_t *currentmodel) if (gl_config.multitexture && !(psurf->flags & SURF_DRAWTURB)) { // Dynamic lighting already generated in R_GetBrushesLighting() - R_EnableMultitexture(true); - R_MBind(GL_TEXTURE0, image->texnum); + R_UpdateGLBuffer(buf_mtex, image->texnum, psurf->lightmaptexturenum, 0, 1); R_RenderLightmappedPoly(currententity, psurf); } else @@ -896,7 +844,6 @@ R_DrawInlineBModel(entity_t *currententity, const model_t *currentmodel) } } } - R_EnableMultitexture(false); R_ApplyGLBuffer(); if (!(currententity->flags & RF_TRANSLUCENT)) diff --git a/src/client/refresh/gl1/header/local.h b/src/client/refresh/gl1/header/local.h index b6a24e9b..cb56a1df 100644 --- a/src/client/refresh/gl1/header/local.h +++ b/src/client/refresh/gl1/header/local.h @@ -111,6 +111,7 @@ typedef enum { buf_2d, buf_singletex, + buf_mtex, buf_alpha } buffered_draw_t; @@ -295,6 +296,7 @@ void R_Buffer2DQuad(GLfloat ul_vx, GLfloat ul_vy, GLfloat dr_vx, GLfloat dr_vy, void R_SetBufferIndices(GLenum type, GLuint vertices_num); void R_BufferVertex(GLfloat x, GLfloat y, GLfloat z); void R_BufferSingleTex(GLfloat s, GLfloat t); +void R_BufferMultiTex(GLfloat cs, GLfloat ct, GLfloat ls, GLfloat lt); #ifdef DEBUG void glCheckError_(const char *file, const char *function, int line);