{
int i;
gltextureunit_t *unit;
+ CHECKGLERROR
gl_state.unit = -1;
gl_state.clientunit = -1;
for (i = 0;i < backendunits;i++)
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
qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
}
}
+ CHECKGLERROR
}
void GL_Backend_ResetState(void)
{
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++)
}
}
-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
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)
{
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);
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);
+ }
}
}
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)
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);
+ }
}
}
float speedscale;
static qboolean skysphereinitialized = false;
rmeshstate_t m;
- matrix4x4_t scroll1matrix, scroll2matrix, identitymatrix;
+ matrix4x4_t scroll1matrix, scroll2matrix;
if (!skysphereinitialized)
{
skysphereinitialized = true;
// 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);
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
{
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)