From b2a1ec8cb2a845e6440d0dbc5a9a84464f3deecc Mon Sep 17 00:00:00 2001 From: havoc Date: Sat, 13 Mar 2004 23:26:17 +0000 Subject: [PATCH] added texmatrix[] to rmeshstate_t and removed R_Mesh_TextureMatrix function reorganized water rendering code to make it a lot less confusing (especially the r_watershader code) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4014 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_backend.c | 47 ++++++++++++-------- gl_backend.h | 5 +-- gl_rsurf.c | 120 ++++++++++++++++++++++----------------------------- r_sky.c | 11 ++--- 4 files changed, 86 insertions(+), 97 deletions(-) diff --git a/gl_backend.c b/gl_backend.c index 7b21ec7c..11b89b71 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -363,6 +363,7 @@ void GL_SetupTextureState(void) { int i; gltextureunit_t *unit; + CHECKGLERROR gl_state.unit = -1; gl_state.clientunit = -1; for (i = 0;i < backendunits;i++) @@ -374,11 +375,14 @@ void GL_SetupTextureState(void) unit->t2d = 0; unit->t3d = 0; unit->tcubemap = 0; + unit->arrayenabled = false; + unit->arrayis3d = false; unit->pointer_texcoord = NULL; unit->rgbscale = 1; unit->alphascale = 1; unit->combinergb = GL_MODULATE; unit->combinealpha = GL_MODULATE; + unit->matrix = r_identitymatrix; qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR @@ -418,6 +422,7 @@ void GL_SetupTextureState(void) qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR } } + CHECKGLERROR } void GL_Backend_ResetState(void) @@ -708,7 +713,7 @@ void R_Mesh_Draw(int numverts, int numtriangles, const int *elements) { if (gl_state.units[i].arrayenabled && !(gl_state.units[i].t1d || gl_state.units[i].t2d || gl_state.units[i].t3d || gl_state.units[i].tcubemap)) Con_Print("R_Mesh_Draw: array enabled but no texture bound\n"); - GL_ActiveTexture(i); + GL_ClientActiveTexture(i); if (!qglIsEnabled(GL_TEXTURE_COORD_ARRAY)) Con_Print("R_Mesh_Draw: texcoord array set but not enabled\n"); for (j = 0, size = numverts * ((gl_state.units[i].t3d || gl_state.units[i].tcubemap) ? (int)sizeof(float[3]) : (int)sizeof(float[2])), p = gl_state.units[i].pointer_texcoord;j < size;j += sizeof(int), p++) @@ -854,24 +859,13 @@ void R_Mesh_Matrix(const matrix4x4_t *matrix) } } -void R_Mesh_TextureMatrix(int unitnumber, const matrix4x4_t *matrix) -{ - if (memcmp(&gl_state.units[unitnumber].matrix, matrix, sizeof(matrix4x4_t))) - { - matrix4x4_t tempmatrix; - gl_state.units[unitnumber].matrix = *matrix; - Matrix4x4_Transpose(&tempmatrix, &gl_state.units[unitnumber].matrix); - qglMatrixMode(GL_TEXTURE); - GL_ActiveTexture(unitnumber); - qglLoadMatrixf(&tempmatrix.m[0][0]); - qglMatrixMode(GL_MODELVIEW); - } -} - void R_Mesh_State(const rmeshstate_t *m) { int i, combinergb, combinealpha, scale, arrayis3d; gltextureunit_t *unit; + const matrix4x4_t *texmatrix; + matrix4x4_t tempmatrix; + const float *texcoords; BACKENDACTIVECHECK @@ -1016,10 +1010,13 @@ void R_Mesh_State(const rmeshstate_t *m) qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, (unit->alphascale = scale));CHECKGLERROR } arrayis3d = unit->t3d || unit->tcubemap; - if (unit->pointer_texcoord != m->pointer_texcoord[i] || unit->arrayis3d != arrayis3d) + texcoords = m->pointer_texcoord[i]; + if (texcoords && !unit->t1d && !unit->t2d && !unit->t3d && !unit->tcubemap) + texcoords = NULL; + if (unit->pointer_texcoord != texcoords || unit->arrayis3d != arrayis3d) { GL_ClientActiveTexture(i); - if (m->pointer_texcoord[i]) + if (texcoords) { if (!unit->arrayenabled) { @@ -1035,7 +1032,7 @@ void R_Mesh_State(const rmeshstate_t *m) qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR } } - unit->pointer_texcoord = m->pointer_texcoord[i]; + unit->pointer_texcoord = texcoords; unit->arrayis3d = arrayis3d; if (unit->arrayis3d) qglTexCoordPointer(3, GL_FLOAT, sizeof(float[3]), unit->pointer_texcoord); @@ -1043,6 +1040,20 @@ void R_Mesh_State(const rmeshstate_t *m) qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), unit->pointer_texcoord); CHECKGLERROR } + // if texmatrix is not set (3,3 should always be 1 in a texture matrix) just compare to the identity matrix + if (m->texmatrix[i].m[3][3]) + texmatrix = &m->texmatrix[i]; + else + texmatrix = &r_identitymatrix; + if (memcmp(&unit->matrix, texmatrix, sizeof(matrix4x4_t))) + { + unit->matrix = *texmatrix; + Matrix4x4_Transpose(&tempmatrix, &unit->matrix); + qglMatrixMode(GL_TEXTURE); + GL_ActiveTexture(i); + qglLoadMatrixf(&tempmatrix.m[0][0]); + qglMatrixMode(GL_MODELVIEW); + } } } diff --git a/gl_backend.h b/gl_backend.h index d5940a37..c97fd14f 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -46,6 +46,8 @@ typedef struct int texalphascale[MAX_TEXTUREUNITS]; // used only if COMBINE is present int texcombinergb[MAX_TEXTUREUNITS]; // works with or without combine for some operations int texcombinealpha[MAX_TEXTUREUNITS]; // does nothing without combine + // matrices + matrix4x4_t texmatrix[MAX_TEXTUREUNITS]; // pointers const float *pointer_texcoord[MAX_TEXTUREUNITS]; @@ -68,9 +70,6 @@ void R_Mesh_Finish(void); // sets up the requested transform matrix void R_Mesh_Matrix(const matrix4x4_t *matrix); -// sets up the requested transform matrix -void R_Mesh_TextureMatrix(int unitnumber, const matrix4x4_t *matrix); - // set up the requested state void R_Mesh_State(const rmeshstate_t *m); diff --git a/gl_rsurf.c b/gl_rsurf.c index 14c3dd8f..cabf4bbf 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -785,27 +785,11 @@ static void RSurfShader_Water_Callback(const void *calldata1, int calldata2) float alpha; float modelorg[3]; texture_t *texture; - matrix4x4_t tempmatrix; - float args[4] = {0.05f,0,0,0.04f}; - - if (gl_textureshader && r_watershader.value && !fogenabled) - { - Matrix4x4_CreateTranslate(&tempmatrix, sin(cl.time) * 0.025 * r_waterscroll.value, sin(cl.time * 0.8f) * 0.025 * r_waterscroll.value, 0); - R_Mesh_TextureMatrix(1, &tempmatrix); - Matrix4x4_CreateFromQuakeEntity(&tempmatrix, 0, 0, 0, 0, 0, 0, r_watershader.value); - R_Mesh_TextureMatrix(0, &tempmatrix); - } - else if (r_waterscroll.value) - { - // scrolling in texture matrix - Matrix4x4_CreateTranslate(&tempmatrix, sin(cl.time) * 0.025 * r_waterscroll.value, sin(cl.time * 0.8f) * 0.025 * r_waterscroll.value, 0); - R_Mesh_TextureMatrix(0, &tempmatrix); - } + float args[4] = {0.05f,0,0,0.04f}; R_Mesh_Matrix(&ent->matrix); Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg); - memset(&m, 0, sizeof(m)); texture = surf->texinfo->texture->currentframe; alpha = texture->currentalpha; if (texture->rendertype == SURFRENDER_ADD) @@ -823,72 +807,70 @@ static void RSurfShader_Water_Callback(const void *calldata1, int calldata2) GL_BlendFunc(GL_ONE, GL_ZERO); GL_DepthMask(true); } + GL_DepthTest(true); + GL_Color(1, 1, 1, alpha); + memset(&m, 0, sizeof(m)); + m.pointer_vertex = surf->mesh.data_vertex3f; if (gl_textureshader && r_watershader.value && !fogenabled) { m.tex[0] = R_GetTexture(mod_shared_distorttexture[(int)(cl.time * 16)&63]); m.tex[1] = R_GetTexture(texture->skin.base); - } - else - m.tex[0] = R_GetTexture(texture->skin.base); - GL_DepthTest(true); - if (fogenabled) - m.pointer_color = varray_color4f; - else - GL_Color(1, 1, 1, alpha); - if (gl_textureshader && r_watershader.value && !fogenabled) - { - GL_ActiveTexture (0); - qglTexEnvi (GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D); - GL_ActiveTexture (1); - qglTexEnvi (GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D); - qglTexEnvi (GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV); - qglTexEnvi (GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB); - qglTexEnvfv (GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[0]); - qglEnable (GL_TEXTURE_SHADER_NV); - } + m.texcombinergb[0] = GL_REPLACE; + m.texcombinergb[1] = GL_REPLACE; + m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f; + m.pointer_texcoord[1] = surf->mesh.data_texcoordtexture2f; + Matrix4x4_CreateFromQuakeEntity(&m.texmatrix[0], 0, 0, 0, 0, 0, 0, r_watershader.value); + Matrix4x4_CreateTranslate(&m.texmatrix[1], sin(cl.time) * 0.025 * r_waterscroll.value, sin(cl.time * 0.8f) * 0.025 * r_waterscroll.value, 0); + R_Mesh_State(&m); - if (fogenabled) - { - R_FillColors(varray_color4f, surf->mesh.num_vertices, 1, 1, 1, alpha); - RSurf_FogColors_Vertex3f_Color4f(surf->mesh.data_vertex3f, varray_color4f, 1, surf->mesh.num_vertices, modelorg); - } - m.pointer_vertex = surf->mesh.data_vertex3f; - m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f; - m.pointer_texcoord[1] = surf->mesh.data_texcoordtexture2f; - m.texcombinergb[1] = GL_REPLACE; - R_Mesh_State(&m); - GL_LockArrays(0, surf->mesh.num_vertices); - R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i); - GL_LockArrays(0, 0); + GL_ActiveTexture(0); + qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D); + GL_ActiveTexture(1); + qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV); + qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB); + qglTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[0]); + qglEnable(GL_TEXTURE_SHADER_NV); - if (gl_textureshader && r_watershader.value && !fogenabled) - { - qglDisable (GL_TEXTURE_SHADER_NV); - GL_ActiveTexture (0); - } + GL_LockArrays(0, surf->mesh.num_vertices); + R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i); + GL_LockArrays(0, 0); - if (fogenabled) + qglDisable(GL_TEXTURE_SHADER_NV); + qglTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D); + GL_ActiveTexture(0); + } + else { - memset(&m, 0, sizeof(m)); - m.pointer_vertex = surf->mesh.data_vertex3f; - GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); - GL_DepthMask(false); - GL_DepthTest(true); - m.tex[0] = R_GetTexture(texture->skin.fog); + if (fogenabled) + { + R_FillColors(varray_color4f, surf->mesh.num_vertices, 1, 1, 1, alpha); + RSurf_FogColors_Vertex3f_Color4f(surf->mesh.data_vertex3f, varray_color4f, 1, surf->mesh.num_vertices, modelorg); + m.pointer_color = varray_color4f; + } + m.tex[0] = R_GetTexture(texture->skin.base); m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f; - m.pointer_color = varray_color4f; + if (r_waterscroll.value) + { + // scrolling in texture matrix + Matrix4x4_CreateTranslate(&m.texmatrix[0], sin(cl.time) * 0.025 * r_waterscroll.value, sin(cl.time * 0.8f) * 0.025 * r_waterscroll.value, 0); + } R_Mesh_State(&m); - RSurf_FogPassColors_Vertex3f_Color4f(surf->mesh.data_vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], alpha, 1, surf->mesh.num_vertices, modelorg); + GL_LockArrays(0, surf->mesh.num_vertices); R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i); GL_LockArrays(0, 0); - } - if ((gl_textureshader && r_watershader.value && !fogenabled) || r_waterscroll.value) - { - Matrix4x4_CreateIdentity(&tempmatrix); - R_Mesh_TextureMatrix(0, &tempmatrix); - R_Mesh_TextureMatrix(1, &tempmatrix); + if (fogenabled && texture->rendertype != SURFRENDER_ADD) + { + GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); + GL_DepthMask(false); + RSurf_FogPassColors_Vertex3f_Color4f(surf->mesh.data_vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], alpha, 1, surf->mesh.num_vertices, modelorg); + m.tex[0] = R_GetTexture(texture->skin.fog); + R_Mesh_State(&m); + GL_LockArrays(0, surf->mesh.num_vertices); + R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i); + GL_LockArrays(0, 0); + } } } diff --git a/r_sky.c b/r_sky.c index bb3f8ddd..a830e85b 100644 --- a/r_sky.c +++ b/r_sky.c @@ -311,7 +311,7 @@ static void R_SkySphere(void) float speedscale; static qboolean skysphereinitialized = false; rmeshstate_t m; - matrix4x4_t scroll1matrix, scroll2matrix, identitymatrix; + matrix4x4_t scroll1matrix, scroll2matrix; if (!skysphereinitialized) { skysphereinitialized = true; @@ -326,7 +326,6 @@ static void R_SkySphere(void) // scroll the lower cloud layer twice as fast (just like quake did) Matrix4x4_CreateTranslate(&scroll1matrix, speedscale, speedscale, 0); Matrix4x4_CreateTranslate(&scroll2matrix, speedscale * 2, speedscale * 2, 0); - Matrix4x4_CreateIdentity(&identitymatrix); GL_Color(1, 1, 1, 1); GL_BlendFunc(GL_ONE, GL_ZERO); @@ -336,19 +335,18 @@ static void R_SkySphere(void) m.pointer_vertex = skysphere_vertex3f; m.tex[0] = R_GetTexture(solidskytexture); m.pointer_texcoord[0] = skysphere_texcoord2f; - R_Mesh_TextureMatrix(0, &scroll1matrix); + m.texmatrix[0] = scroll1matrix; if (r_textureunits.integer >= 2) { // one pass using GL_DECAL or GL_INTERPOLATE_ARB for alpha layer m.tex[1] = R_GetTexture(alphaskytexture); m.texcombinergb[1] = gl_combine.integer ? GL_INTERPOLATE_ARB : GL_DECAL; m.pointer_texcoord[1] = skysphere_texcoord2f; + m.texmatrix[1] = scroll2matrix; R_Mesh_State(&m); - R_Mesh_TextureMatrix(1, &scroll2matrix); GL_LockArrays(0, skysphere_numverts); R_Mesh_Draw(skysphere_numverts, skysphere_numtriangles, skysphere_element3i); GL_LockArrays(0, 0); - R_Mesh_TextureMatrix(1, &identitymatrix); } else { @@ -360,13 +358,12 @@ static void R_SkySphere(void) GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); m.tex[0] = R_GetTexture(alphaskytexture); + m.texmatrix[0] = scroll2matrix; R_Mesh_State(&m); - R_Mesh_TextureMatrix(0, &scroll2matrix); GL_LockArrays(0, skysphere_numverts); R_Mesh_Draw(skysphere_numverts, skysphere_numtriangles, skysphere_element3i); GL_LockArrays(0, 0); } - R_Mesh_TextureMatrix(0, &identitymatrix); } void R_Sky(void) -- 2.39.2