From 55dfaa2e3ba9be15b2b63239ea1b4e0a66cd9d45 Mon Sep 17 00:00:00 2001 From: Jaime Moreira Date: Mon, 15 Jul 2024 11:20:26 -0400 Subject: [PATCH] GL1 unified draw calls, 05 Buffered 'alias' models. Logic from R_DrawAliasModel() and R_DrawAliasFrameLerp() was moved to R_ApplyGLBuffer(). --- src/client/refresh/gl1/gl1_buffer.c | 107 ++++++++++- src/client/refresh/gl1/gl1_mesh.c | 258 ++++++-------------------- src/client/refresh/gl1/header/local.h | 1 + 3 files changed, 162 insertions(+), 204 deletions(-) diff --git a/src/client/refresh/gl1/gl1_buffer.c b/src/client/refresh/gl1/gl1_buffer.c index 4b48cf30..f27e815e 100644 --- a/src/client/refresh/gl1/gl1_buffer.c +++ b/src/client/refresh/gl1/gl1_buffer.c @@ -61,7 +61,8 @@ R_ApplyGLBuffer(void) { // Properties of batched draws here GLint vtx_size; - qboolean texture, mtex, alpha, color, texenv_set; + qboolean texture, mtex, alpha, color, alias, texenv_set; + float fovy, dist; if (gl_buf.vtx_ptr == 0 || gl_buf.idx_ptr == 0) { @@ -71,7 +72,7 @@ R_ApplyGLBuffer(void) // defaults for drawing (mostly buf_singletex features) vtx_size = 3; texture = true; - mtex = alpha = color = texenv_set = false; + mtex = alpha = color = alias = texenv_set = false; // choosing features by type switch (gl_buf.type) @@ -85,6 +86,9 @@ R_ApplyGLBuffer(void) case buf_alpha: alpha = true; break; + case buf_alias: + alias = color = true; + break; case buf_flash: color = true; texture = false; @@ -95,6 +99,53 @@ R_ApplyGLBuffer(void) R_EnableMultitexture(mtex); + if (alias) + { + if (gl_buf.flags & RF_DEPTHHACK) + { + // hack the depth range to prevent view model from poking into walls + glDepthRange(gldepthmin, gldepthmin + 0.3 * (gldepthmax - gldepthmin)); + } + + if (gl_buf.flags & RF_WEAPONMODEL) + { + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + if (gl_lefthand->value == 1.0f) + { + glScalef(-1, 1, 1); + } + + fovy = (r_gunfov->value < 0) ? r_newrefdef.fov_y : r_gunfov->value; + dist = (r_farsee->value == 0) ? 4096.0f : 8192.0f; + R_MYgluPerspective(fovy, (float)r_newrefdef.width / r_newrefdef.height, 4, dist); + + glMatrixMode(GL_MODELVIEW); + + if (gl_lefthand->value == 1.0f) + { + glCullFace(GL_BACK); + } + } + + glShadeModel(GL_SMOOTH); + R_TexEnv(GL_MODULATE); + + if (gl_buf.flags & RF_TRANSLUCENT) + { + glEnable(GL_BLEND); + } + + if (gl_buf.flags & (RF_SHELL_RED | RF_SHELL_GREEN | + RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM)) + { + texture = false; + glDisable(GL_TEXTURE_2D); + } + } + if (alpha) { // the textures are prescaled up for a better @@ -192,6 +243,39 @@ R_ApplyGLBuffer(void) R_TexEnv(GL_REPLACE); } + if (alias) + { + if (gl_buf.flags & (RF_SHELL_RED | RF_SHELL_GREEN | + RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM)) + { + glEnable(GL_TEXTURE_2D); + } + + if (gl_buf.flags & RF_TRANSLUCENT) + { + glDisable(GL_BLEND); + } + + R_TexEnv(GL_REPLACE); + glShadeModel(GL_FLAT); + + if (gl_buf.flags & RF_WEAPONMODEL) + { + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + if (gl_lefthand->value == 1.0F) + { + glCullFace(GL_FRONT); + } + } + + if (gl_buf.flags & RF_DEPTHHACK) + { + glDepthRange(gldepthmin, gldepthmax); + } + } + gl_buf.vtx_ptr = gl_buf.idx_ptr = 0; } @@ -200,7 +284,7 @@ R_UpdateGLBuffer(buffered_draw_t type, int colortex, int lighttex, int flags, fl { 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_singletex || type == buf_alias) && gl_buf.flags != flags) || (type == buf_alpha && gl_buf.alpha != alpha)) { R_ApplyGLBuffer(); @@ -285,6 +369,23 @@ R_SetBufferIndices(GLenum type, GLuint vertices_num) gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+2; } break; + case GL_TRIANGLE_STRIP: + for (i = 0; i < vertices_num-2; i++) + { + if (i % 2 == 0) + { + gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i; + gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+1; + gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+2; + } + else // backwards order + { + gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+2; + gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+1; + gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i; + } + } + break; default: R_Printf(PRINT_DEVELOPER, "R_SetBufferIndices: no such type %d\n", type); return; diff --git a/src/client/refresh/gl1/gl1_mesh.c b/src/client/refresh/gl1/gl1_mesh.c index e4ab4f8c..78d15e60 100644 --- a/src/client/refresh/gl1/gl1_mesh.c +++ b/src/client/refresh/gl1/gl1_mesh.c @@ -86,19 +86,13 @@ R_LerpVerts(entity_t *currententity, int nverts, dtrivertx_t *v, dtrivertx_t *ov static void R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp) { - unsigned short total; - GLenum type; - float l; daliasframe_t *frame, *oldframe; dtrivertx_t *v, *ov, *verts; int *order; - int count; - float frontlerp; - float alpha; + int count, i, index_xyz; + float tex[2], frontlerp, l, alpha; vec3_t move, delta, vectors[3]; vec3_t frontv, backv; - int i; - int index_xyz; float *lerp; frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames @@ -120,13 +114,6 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp) alpha = 1.0; } - if (currententity->flags & - (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | - RF_SHELL_HALF_DAM)) - { - glDisable(GL_TEXTURE_2D); - } - frontlerp = 1.0 - backlerp; /* move should be the delta back to the previous frame * backlerp */ @@ -154,127 +141,66 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp) R_LerpVerts(currententity, paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv); -#ifdef _MSC_VER // workaround for lack of VLAs (=> our workaround uses alloca() which is bad in loops) - int maxCount = 0; - const int* tmpOrder = order; while (1) { - int c = *tmpOrder++; - if (!c) - break; - if ( c < 0 ) - c = -c; - if ( c > maxCount ) - maxCount = c; + /* get the vertex count and primitive type */ + count = *order++; - tmpOrder += 3 * c; - } - - YQ2_VLA( GLfloat, vtx, 3 * maxCount ); - YQ2_VLA( GLfloat, tex, 2 * maxCount ); - YQ2_VLA( GLfloat, clr, 4 * maxCount ); -#endif - - while (1) + if (!count) { - /* get the vertex count and primitive type */ - count = *order++; - - if (!count) - { - break; /* done */ - } - - if (count < 0) - { - count = -count; - - type = GL_TRIANGLE_FAN; - } - else - { - type = GL_TRIANGLE_STRIP; - } - - total = count; - -#ifndef _MSC_VER // we have real VLAs, so it's safe to use one in this loop - YQ2_VLA(GLfloat, vtx, 3*total); - YQ2_VLA(GLfloat, tex, 2*total); - YQ2_VLA(GLfloat, clr, 4*total); -#endif - unsigned int index_vtx = 0; - unsigned int index_tex = 0; - unsigned int index_clr = 0; - - if (currententity->flags & - (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE)) - { - do - { - index_xyz = order[2]; - order += 3; - - clr[index_clr++] = shadelight[0]; - clr[index_clr++] = shadelight[1]; - clr[index_clr++] = shadelight[2]; - clr[index_clr++] = alpha; - - vtx[index_vtx++] = s_lerped[index_xyz][0]; - vtx[index_vtx++] = s_lerped[index_xyz][1]; - vtx[index_vtx++] = s_lerped[index_xyz][2]; - } - while (--count); - } - else - { - do - { - /* texture coordinates come from the draw list */ - tex[index_tex++] = ((float *) order)[0]; - tex[index_tex++] = ((float *) order)[1]; - - index_xyz = order[2]; - order += 3; - - /* normals and vertexes come from the frame list */ - l = shadedots[verts[index_xyz].lightnormalindex]; - - clr[index_clr++] = l * shadelight[0]; - clr[index_clr++] = l * shadelight[1]; - clr[index_clr++] = l * shadelight[2]; - clr[index_clr++] = alpha; - - vtx[index_vtx++] = s_lerped[index_xyz][0]; - vtx[index_vtx++] = s_lerped[index_xyz][1]; - vtx[index_vtx++] = s_lerped[index_xyz][2]; - } - while (--count); - } - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - glVertexPointer(3, GL_FLOAT, 0, vtx); - glTexCoordPointer(2, GL_FLOAT, 0, tex); - glColorPointer(4, GL_FLOAT, 0, clr); - glDrawArrays(type, 0, total); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); + break; /* done */ } - YQ2_VLAFREE( vtx ); - YQ2_VLAFREE( tex ); - YQ2_VLAFREE( clr ) + if (count < 0) + { + count = -count; + R_SetBufferIndices(GL_TRIANGLE_FAN, count); + } + else + { + R_SetBufferIndices(GL_TRIANGLE_STRIP, count); + } - if (currententity->flags & - (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | - RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM)) - { - glEnable(GL_TEXTURE_2D); + if (currententity->flags & + (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE)) + { + do + { + index_xyz = order[2]; + order += 3; + + R_BufferVertex(s_lerped[index_xyz][0], + s_lerped[index_xyz][1], s_lerped[index_xyz][2]); + + R_BufferColor(shadelight[0], shadelight[1], + shadelight[2], alpha); + } + while (--count); + } + else + { + do + { + /* texture coordinates come from the draw list */ + tex[0] = ((float *)order)[0]; + tex[1] = ((float *)order)[1]; + + index_xyz = order[2]; + order += 3; + + /* normals and vertexes come from the frame list */ + l = shadedots[verts[index_xyz].lightnormalindex]; + + R_BufferVertex(s_lerped[index_xyz][0], + s_lerped[index_xyz][1], s_lerped[index_xyz][2]); + + R_BufferSingleTex(tex[0], tex[1]); + + R_BufferColor(l * shadelight[0], l * shadelight[1], + l * shadelight[2], alpha); + } + while (--count); + } } } @@ -557,7 +483,6 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel) } } - R_EnableMultitexture(false); paliashdr = (dmdl_t *)currentmodel->extradata; /* get lighting information */ @@ -685,7 +610,6 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel) } - /* ir goggles color override */ if (r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE) @@ -707,45 +631,6 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel) /* locate the proper data */ c_alias_polys += paliashdr->num_tris; - /* draw all the triangles */ - if (currententity->flags & RF_DEPTHHACK) - { - /* hack the depth range to prevent view model from poking into walls */ - glDepthRange(gldepthmin, gldepthmin + 0.3 * (gldepthmax - gldepthmin)); - } - - if (currententity->flags & RF_WEAPONMODEL) - { - extern void R_MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - if (gl_lefthand->value == 1.0F) - { - glScalef(-1, 1, 1); - } - - float dist = (r_farsee->value == 0) ? 4096.0f : 8192.0f; - - if (r_gunfov->value < 0) - { - R_MYgluPerspective(r_newrefdef.fov_y, (float)r_newrefdef.width / r_newrefdef.height, 4, dist); - } - else - { - R_MYgluPerspective(r_gunfov->value, (float)r_newrefdef.width / r_newrefdef.height, 4, dist); - } - - glMatrixMode(GL_MODELVIEW); - - if (gl_lefthand->value == 1.0F) - { - glCullFace(GL_BACK); - } - } - glPushMatrix(); currententity->angles[PITCH] = -currententity->angles[PITCH]; R_RotateForEntity(currententity); @@ -778,18 +663,6 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel) skin = r_notexture; /* fallback... */ } - R_Bind(skin->texnum); - - /* draw it */ - glShadeModel(GL_SMOOTH); - - R_TexEnv(GL_MODULATE); - - if (currententity->flags & RF_TRANSLUCENT) - { - glEnable(GL_BLEND); - } - if ((currententity->frame >= paliashdr->num_frames) || (currententity->frame < 0)) { @@ -813,7 +686,9 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel) currententity->backlerp = 0; } + R_UpdateGLBuffer(buf_alias, skin->texnum, 0, currententity->flags, 1); R_DrawAliasFrameLerp(currententity, paliashdr, currententity->backlerp); + R_ApplyGLBuffer(); R_TexEnv(GL_REPLACE); glShadeModel(GL_FLAT); @@ -836,25 +711,6 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel) glEnable(GL_CULL_FACE); } - if (currententity->flags & RF_WEAPONMODEL) - { - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - if (gl_lefthand->value == 1.0F) - glCullFace(GL_FRONT); - } - - if (currententity->flags & RF_TRANSLUCENT) - { - glDisable(GL_BLEND); - } - - if (currententity->flags & RF_DEPTHHACK) - { - glDepthRange(gldepthmin, gldepthmax); - } - if (gl_shadows->value && !(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW))) { diff --git a/src/client/refresh/gl1/header/local.h b/src/client/refresh/gl1/header/local.h index 50545517..bf843387 100644 --- a/src/client/refresh/gl1/header/local.h +++ b/src/client/refresh/gl1/header/local.h @@ -113,6 +113,7 @@ typedef enum buf_singletex, buf_mtex, buf_alpha, + buf_alias, buf_flash } buffered_draw_t;