GL1 unified draw calls, 05

Buffered 'alias' models. Logic from R_DrawAliasModel() and
R_DrawAliasFrameLerp() was moved to R_ApplyGLBuffer().
This commit is contained in:
Jaime Moreira 2024-07-15 11:20:26 -04:00
parent e8b2e36bd8
commit 55dfaa2e3b
3 changed files with 162 additions and 204 deletions

View file

@ -61,7 +61,8 @@ R_ApplyGLBuffer(void)
{ {
// Properties of batched draws here // Properties of batched draws here
GLint vtx_size; 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) 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) // defaults for drawing (mostly buf_singletex features)
vtx_size = 3; vtx_size = 3;
texture = true; texture = true;
mtex = alpha = color = texenv_set = false; mtex = alpha = color = alias = texenv_set = false;
// choosing features by type // choosing features by type
switch (gl_buf.type) switch (gl_buf.type)
@ -85,6 +86,9 @@ R_ApplyGLBuffer(void)
case buf_alpha: case buf_alpha:
alpha = true; alpha = true;
break; break;
case buf_alias:
alias = color = true;
break;
case buf_flash: case buf_flash:
color = true; color = true;
texture = false; texture = false;
@ -95,6 +99,53 @@ R_ApplyGLBuffer(void)
R_EnableMultitexture(mtex); 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) if (alpha)
{ {
// the textures are prescaled up for a better // the textures are prescaled up for a better
@ -192,6 +243,39 @@ R_ApplyGLBuffer(void)
R_TexEnv(GL_REPLACE); 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; 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 || if ( gl_buf.type != type || gl_buf.texture[0] != colortex ||
(gl_config.multitexture && type == buf_mtex && gl_buf.texture[1] != lighttex) || (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)) (type == buf_alpha && gl_buf.alpha != alpha))
{ {
R_ApplyGLBuffer(); 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; gl_buf.idx[gl_buf.idx_ptr++] = gl_buf.vtx_ptr+i+2;
} }
break; 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: default:
R_Printf(PRINT_DEVELOPER, "R_SetBufferIndices: no such type %d\n", type); R_Printf(PRINT_DEVELOPER, "R_SetBufferIndices: no such type %d\n", type);
return; return;

View file

@ -86,19 +86,13 @@ R_LerpVerts(entity_t *currententity, int nverts, dtrivertx_t *v, dtrivertx_t *ov
static void static void
R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp) R_DrawAliasFrameLerp(entity_t *currententity, dmdl_t *paliashdr, float backlerp)
{ {
unsigned short total;
GLenum type;
float l;
daliasframe_t *frame, *oldframe; daliasframe_t *frame, *oldframe;
dtrivertx_t *v, *ov, *verts; dtrivertx_t *v, *ov, *verts;
int *order; int *order;
int count; int count, i, index_xyz;
float frontlerp; float tex[2], frontlerp, l, alpha;
float alpha;
vec3_t move, delta, vectors[3]; vec3_t move, delta, vectors[3];
vec3_t frontv, backv; vec3_t frontv, backv;
int i;
int index_xyz;
float *lerp; float *lerp;
frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames 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; 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; frontlerp = 1.0 - backlerp;
/* move should be the delta back to the previous frame * 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); 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) while (1)
{ {
int c = *tmpOrder++; /* get the vertex count and primitive type */
if (!c) count = *order++;
break;
if ( c < 0 )
c = -c;
if ( c > maxCount )
maxCount = c;
tmpOrder += 3 * c; if (!count)
}
YQ2_VLA( GLfloat, vtx, 3 * maxCount );
YQ2_VLA( GLfloat, tex, 2 * maxCount );
YQ2_VLA( GLfloat, clr, 4 * maxCount );
#endif
while (1)
{ {
/* get the vertex count and primitive type */ break; /* done */
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);
} }
YQ2_VLAFREE( vtx ); if (count < 0)
YQ2_VLAFREE( tex ); {
YQ2_VLAFREE( clr ) count = -count;
R_SetBufferIndices(GL_TRIANGLE_FAN, count);
}
else
{
R_SetBufferIndices(GL_TRIANGLE_STRIP, count);
}
if (currententity->flags & if (currententity->flags &
(RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE))
RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM)) {
{ do
glEnable(GL_TEXTURE_2D); {
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; paliashdr = (dmdl_t *)currentmodel->extradata;
/* get lighting information */ /* get lighting information */
@ -685,7 +610,6 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
} }
/* ir goggles color override */ /* ir goggles color override */
if (r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & if (r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags &
RF_IR_VISIBLE) RF_IR_VISIBLE)
@ -707,45 +631,6 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
/* locate the proper data */ /* locate the proper data */
c_alias_polys += paliashdr->num_tris; 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(); glPushMatrix();
currententity->angles[PITCH] = -currententity->angles[PITCH]; currententity->angles[PITCH] = -currententity->angles[PITCH];
R_RotateForEntity(currententity); R_RotateForEntity(currententity);
@ -778,18 +663,6 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
skin = r_notexture; /* fallback... */ 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) || if ((currententity->frame >= paliashdr->num_frames) ||
(currententity->frame < 0)) (currententity->frame < 0))
{ {
@ -813,7 +686,9 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
currententity->backlerp = 0; currententity->backlerp = 0;
} }
R_UpdateGLBuffer(buf_alias, skin->texnum, 0, currententity->flags, 1);
R_DrawAliasFrameLerp(currententity, paliashdr, currententity->backlerp); R_DrawAliasFrameLerp(currententity, paliashdr, currententity->backlerp);
R_ApplyGLBuffer();
R_TexEnv(GL_REPLACE); R_TexEnv(GL_REPLACE);
glShadeModel(GL_FLAT); glShadeModel(GL_FLAT);
@ -836,25 +711,6 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
glEnable(GL_CULL_FACE); 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 && if (gl_shadows->value &&
!(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW))) !(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW)))
{ {

View file

@ -113,6 +113,7 @@ typedef enum
buf_singletex, buf_singletex,
buf_mtex, buf_mtex,
buf_alpha, buf_alpha,
buf_alias,
buf_flash buf_flash
} buffered_draw_t; } buffered_draw_t;