cvar_t r_waterwarp = {CVAR_SAVE, "r_waterwarp", "1", "warp view while underwater"};
cvar_t gl_polyblend = {CVAR_SAVE, "gl_polyblend", "1", "tints view while underwater, hurt, etc"};
cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1", "enables OpenGL dithering (16bit looks bad with this off)"};
-cvar_t gl_lockarrays = {0, "gl_lockarrays", "0", "enables use of glLockArraysEXT, may cause glitches with some broken drivers, and may be slower than normal"};
-cvar_t gl_lockarrays_minimumvertices = {0, "gl_lockarrays_minimumvertices", "1", "minimum number of vertices required for use of glLockArraysEXT, setting this too low may reduce performance"};
cvar_t gl_vbo = {CVAR_SAVE, "gl_vbo", "3", "make use of GL_ARB_vertex_buffer_object extension to store static geometry in video memory for faster rendering, 0 disables VBO allocation or use, 1 enables VBOs for vertex and triangle data, 2 only for vertex data, 3 for vertex data and triangle data of simple meshes (ones with only one surface)"};
cvar_t gl_fbo = {CVAR_SAVE, "gl_fbo", "1", "make use of GL_ARB_framebuffer_object extension to enable shadowmaps and other features using pixel formats different from the framebuffer"};
cvar_t v_flipped = {0, "v_flipped", "0", "mirror the screen (poor man's left handed mode)"};
qboolean v_flipped_state = false;
+r_viewport_t gl_viewport;
+matrix4x4_t gl_modelmatrix;
+matrix4x4_t gl_viewmatrix;
+matrix4x4_t gl_modelviewmatrix;
+matrix4x4_t gl_projectionmatrix;
+matrix4x4_t gl_modelviewprojectionmatrix;
+float gl_modelview16f[16];
+float gl_modelviewprojection16f[16];
+qboolean gl_modelmatrixchanged;
+
int gl_maxdrawrangeelementsvertices;
int gl_maxdrawrangeelementsindices;
}
#endif
-#define BACKENDACTIVECHECK if (!backendactive) Sys_Error("GL backend function called when backend is not active");
+#define BACKENDACTIVECHECK if (!gl_state.active) Sys_Error("GL backend function called when backend is not active");
void SCR_ScreenShot_f (void);
int arrayenabled;
unsigned int arraycomponents;
int rgbscale, alphascale;
+ int combine;
int combinergb, combinealpha;
// texmatrixenabled exists only to avoid unnecessary texmatrix compares
int texmatrixenabled;
size_t pointer_color_offset;
int pointer_vertex_buffer;
int pointer_color_buffer;
+
+ memexpandablearray_t bufferobjectinfoarray;
+
+ qboolean active;
}
gl_state_t;
static gl_state_t gl_state;
-static memexpandablearray_t gl_bufferobjectinfoarray;
-
-static r_viewport_t backend_viewport;
-static matrix4x4_t backend_modelmatrix;
-static matrix4x4_t backend_modelviewmatrix;
-
-static unsigned int backendactive;
/*
note: here's strip order for a terrain row:
GL_Mesh_ListVBOs(true);
}
+static void GL_Backend_ResetState(void);
+
static void gl_backend_start(void)
{
- CHECKGLERROR
-
- if (qglDrawRangeElements != NULL)
- {
- CHECKGLERROR
- qglGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &gl_maxdrawrangeelementsvertices);
- CHECKGLERROR
- qglGetIntegerv(GL_MAX_ELEMENTS_INDICES, &gl_maxdrawrangeelementsindices);
- CHECKGLERROR
- Con_DPrintf("GL_MAX_ELEMENTS_VERTICES = %i\nGL_MAX_ELEMENTS_INDICES = %i\n", gl_maxdrawrangeelementsvertices, gl_maxdrawrangeelementsindices);
- }
-
- if (gl_support_fragment_shader)
- {
- Con_DPrintf("GLSL shader support detected: texture units = %i texenv, %i image, %i array\n", vid.texunits, vid.teximageunits, vid.texarrayunits);
- vid.teximageunits = bound(1, vid.teximageunits, MAX_TEXTUREUNITS);
- vid.texarrayunits = bound(1, vid.texarrayunits, MAX_TEXTUREUNITS);
- }
- else
- Con_DPrintf("GL_MAX_TEXTUREUNITS = %i\n", vid.texunits);
+ memset(&gl_state, 0, sizeof(gl_state));
- Mem_ExpandableArray_NewArray(&gl_bufferobjectinfoarray, r_main_mempool, sizeof(gl_bufferobjectinfo_t), 128);
+ Mem_ExpandableArray_NewArray(&gl_state.bufferobjectinfoarray, r_main_mempool, sizeof(gl_bufferobjectinfo_t), 128);
Con_DPrintf("OpenGL backend started.\n");
CHECKGLERROR
- backendactive = true;
+ GL_Backend_ResetState();
}
static void gl_backend_shutdown(void)
{
- backendactive = false;
-
Con_DPrint("OpenGL Backend shutting down\n");
- Mem_ExpandableArray_FreeArray(&gl_bufferobjectinfoarray);
+ Mem_ExpandableArray_FreeArray(&gl_state.bufferobjectinfoarray);
+
+ memset(&gl_state, 0, sizeof(gl_state));
}
static void gl_backend_newmap(void)
Cvar_RegisterVariable(&gl_polyblend);
Cvar_RegisterVariable(&v_flipped);
Cvar_RegisterVariable(&gl_dither);
- Cvar_RegisterVariable(&gl_lockarrays);
- Cvar_RegisterVariable(&gl_lockarrays_minimumvertices);
Cvar_RegisterVariable(&gl_vbo);
Cvar_RegisterVariable(&gl_paranoid);
Cvar_RegisterVariable(&gl_printcheckerror);
out[2] = v->z + (out[2] * iw + 1.0f) * v->depth * 0.5f;
}
-static void R_Viewport_ApplyNearClipPlane(r_viewport_t *v, double normalx, double normaly, double normalz, double dist)
+static void R_Viewport_ApplyNearClipPlaneFloatGL(const r_viewport_t *v, float *m, float normalx, float normaly, float normalz, float dist)
{
- double q[4];
- double d;
+ float q[4];
+ float d;
float clipPlane[4], v3[3], v4[3];
float normal[3];
// testing code for comparing results
float clipPlane2[4];
VectorCopy4(clipPlane, clipPlane2);
- R_Mesh_Matrix(&identitymatrix);
+ R_EntityMatrix(&identitymatrix);
VectorSet(q, normal[0], normal[1], normal[2], -dist);
qglClipPlane(GL_CLIP_PLANE0, q);
qglGetClipPlane(GL_CLIP_PLANE0, q);
// as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
// transform it into camera space by multiplying it
// by the inverse of the projection matrix
- q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + v->m[8]) / v->m[0];
- q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + v->m[9]) / v->m[5];
+ q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + m[8]) / m[0];
+ q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + m[9]) / m[5];
q[2] = -1.0f;
- q[3] = (1.0f + v->m[10]) / v->m[14];
+ q[3] = (1.0f + m[10]) / m[14];
// Calculate the scaled plane vector
d = 2.0f / DotProduct4(clipPlane, q);
// Replace the third row of the projection matrix
- v->m[2] = clipPlane[0] * d;
- v->m[6] = clipPlane[1] * d;
- v->m[10] = clipPlane[2] * d + 1.0f;
- v->m[14] = clipPlane[3] * d;
+ m[2] = clipPlane[0] * d;
+ m[6] = clipPlane[1] * d;
+ m[10] = clipPlane[2] * d + 1.0f;
+ m[14] = clipPlane[3] * d;
}
-void R_Viewport_InitOrtho(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, double x1, double y1, double x2, double y2, double nearclip, double farclip, const double *nearplane)
+void R_Viewport_InitOrtho(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float x1, float y1, float x2, float y2, float nearclip, float farclip, const float *nearplane)
{
float left = x1, right = x2, bottom = y2, top = y1, zNear = nearclip, zFar = farclip;
+ float m[16];
memset(v, 0, sizeof(*v));
v->type = R_VIEWPORTTYPE_ORTHO;
v->cameramatrix = *cameramatrix;
v->width = width;
v->height = height;
v->depth = 1;
- v->m[0] = 2/(right - left);
- v->m[5] = 2/(top - bottom);
- v->m[10] = -2/(zFar - zNear);
- v->m[12] = - (right + left)/(right - left);
- v->m[13] = - (top + bottom)/(top - bottom);
- v->m[14] = - (zFar + zNear)/(zFar - zNear);
- v->m[15] = 1;
+ memset(m, 0, sizeof(m));
+ m[0] = 2/(right - left);
+ m[5] = 2/(top - bottom);
+ m[10] = -2/(zFar - zNear);
+ m[12] = - (right + left)/(right - left);
+ m[13] = - (top + bottom)/(top - bottom);
+ m[14] = - (zFar + zNear)/(zFar - zNear);
+ m[15] = 1;
+ v->screentodepth[0] = -farclip / (farclip - nearclip);
+ v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
Matrix4x4_Invert_Full(&v->viewmatrix, &v->cameramatrix);
- Matrix4x4_FromArrayDoubleGL(&v->projectmatrix, v->m);
if (nearplane)
- R_Viewport_ApplyNearClipPlane(v, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+ R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+
+ Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
#if 0
{
#endif
}
-void R_Viewport_InitPerspective(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, double frustumx, double frustumy, double nearclip, double farclip, const double *nearplane)
+void R_Viewport_InitPerspective(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, float farclip, const float *nearplane)
{
matrix4x4_t tempmatrix, basematrix;
+ float m[16];
memset(v, 0, sizeof(*v));
if(v_flipped.integer)
v->width = width;
v->height = height;
v->depth = 1;
- v->m[0] = 1.0 / frustumx;
- v->m[5] = 1.0 / frustumy;
- v->m[10] = -(farclip + nearclip) / (farclip - nearclip);
- v->m[11] = -1;
- v->m[14] = -2 * nearclip * farclip / (farclip - nearclip);
+ memset(m, 0, sizeof(m));
+ m[0] = 1.0 / frustumx;
+ m[5] = 1.0 / frustumy;
+ m[10] = -(farclip + nearclip) / (farclip - nearclip);
+ m[11] = -1;
+ m[14] = -2 * nearclip * farclip / (farclip - nearclip);
+ v->screentodepth[0] = -farclip / (farclip - nearclip);
+ v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
- Matrix4x4_FromArrayDoubleGL(&v->projectmatrix, v->m);
-
if (nearplane)
- R_Viewport_ApplyNearClipPlane(v, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+ R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+
+ Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
}
-void R_Viewport_InitPerspectiveInfinite(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, double frustumx, double frustumy, double nearclip, const double *nearplane)
+void R_Viewport_InitPerspectiveInfinite(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, const float *nearplane)
{
matrix4x4_t tempmatrix, basematrix;
- const double nudge = 1.0 - 1.0 / (1<<23);
+ const float nudge = 1.0 - 1.0 / (1<<23);
+ float m[16];
memset(v, 0, sizeof(*v));
if(v_flipped.integer)
v->width = width;
v->height = height;
v->depth = 1;
- v->m[ 0] = 1.0 / frustumx;
- v->m[ 5] = 1.0 / frustumy;
- v->m[10] = -nudge;
- v->m[11] = -1;
- v->m[14] = -2 * nearclip * nudge;
+ memset(m, 0, sizeof(m));
+ m[ 0] = 1.0 / frustumx;
+ m[ 5] = 1.0 / frustumy;
+ m[10] = -nudge;
+ m[11] = -1;
+ m[14] = -2 * nearclip * nudge;
+ v->screentodepth[0] = (m[10] + 1) * 0.5 - 1;
+ v->screentodepth[1] = m[14] * -0.5;
Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
- Matrix4x4_FromArrayDoubleGL(&v->projectmatrix, v->m);
-
if (nearplane)
- R_Viewport_ApplyNearClipPlane(v, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+ R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+
+ Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
}
float cubeviewmatrix[6][16] =
void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane)
{
matrix4x4_t tempmatrix, basematrix;
+ float m[16];
memset(v, 0, sizeof(*v));
v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
v->cameramatrix = *cameramatrix;
v->width = size;
v->height = size;
v->depth = 1;
- v->m[0] = v->m[5] = 1.0f;
- v->m[10] = -(farclip + nearclip) / (farclip - nearclip);
- v->m[11] = -1;
- v->m[14] = -2 * nearclip * farclip / (farclip - nearclip);
+ memset(m, 0, sizeof(m));
+ m[0] = m[5] = 1.0f;
+ m[10] = -(farclip + nearclip) / (farclip - nearclip);
+ m[11] = -1;
+ m[14] = -2 * nearclip * farclip / (farclip - nearclip);
Matrix4x4_FromArrayFloatGL(&basematrix, cubeviewmatrix[side]);
Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
- Matrix4x4_FromArrayDoubleGL(&v->projectmatrix, v->m);
if (nearplane)
- R_Viewport_ApplyNearClipPlane(v, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+ R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+
+ Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
}
void R_Viewport_InitRectSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, int border, float nearclip, float farclip, const float *nearplane)
{
matrix4x4_t tempmatrix, basematrix;
+ float m[16];
memset(v, 0, sizeof(*v));
v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE;
v->cameramatrix = *cameramatrix;
v->width = size;
v->height = size;
v->depth = 1;
- v->m[0] = v->m[5] = 1.0f * ((float)size - border) / size;
- v->m[10] = -(farclip + nearclip) / (farclip - nearclip);
- v->m[11] = -1;
- v->m[14] = -2 * nearclip * farclip / (farclip - nearclip);
+ memset(m, 0, sizeof(m));
+ m[0] = m[5] = 1.0f * ((float)size - border) / size;
+ m[10] = -(farclip + nearclip) / (farclip - nearclip);
+ m[11] = -1;
+ m[14] = -2 * nearclip * farclip / (farclip - nearclip);
Matrix4x4_FromArrayFloatGL(&basematrix, rectviewmatrix[side]);
Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix);
Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
- Matrix4x4_FromArrayDoubleGL(&v->projectmatrix, v->m);
if (nearplane)
- R_Viewport_ApplyNearClipPlane(v, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+ R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+
+ Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
}
void R_SetViewport(const r_viewport_t *v)
{
- float glmatrix[16];
- backend_viewport = *v;
+ float m[16];
+ gl_viewport = *v;
CHECKGLERROR
qglViewport(v->x, v->y, v->width, v->height);CHECKGLERROR
- // Load the projection matrix into OpenGL
- qglMatrixMode(GL_PROJECTION);CHECKGLERROR
- qglLoadMatrixd(backend_viewport.m);CHECKGLERROR
- qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
-
// FIXME: v_flipped_state is evil, this probably breaks somewhere
GL_SetMirrorState(v_flipped.integer && (v->type == R_VIEWPORTTYPE_PERSPECTIVE || v->type == R_VIEWPORTTYPE_PERSPECTIVE_INFINITEFARCLIP));
- // directly force an update of the modelview matrix
- Matrix4x4_Concat(&backend_modelviewmatrix, &backend_viewport.viewmatrix, &backend_modelmatrix);
- Matrix4x4_ToArrayFloatGL(&backend_modelviewmatrix, glmatrix);
- qglLoadMatrixf(glmatrix);CHECKGLERROR
+ // copy over the matrices to our state
+ gl_viewmatrix = v->viewmatrix;
+ gl_projectionmatrix = v->projectmatrix;
+
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL20:
+ case RENDERPATH_CGGL:
+// break;
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL11:
+ // Load the projection matrix into OpenGL
+ qglMatrixMode(GL_PROJECTION);CHECKGLERROR
+ Matrix4x4_ToArrayFloatGL(&gl_projectionmatrix, m);
+ qglLoadMatrixf(m);CHECKGLERROR
+ qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
+ break;
+ }
+
+ // force an update of the derived matrices
+ gl_modelmatrixchanged = true;
+ R_EntityMatrix(&gl_modelmatrix);
}
void R_GetViewport(r_viewport_t *v)
{
- *v = backend_viewport;
+ *v = gl_viewport;
}
static void GL_BindVBO(int bufferobject)
}
}
-void GL_SetupTextureState(void)
+static void GL_Backend_ResetState(void)
{
unsigned int i;
- gltextureunit_t *unit;
- CHECKGLERROR
- gl_state.unit = MAX_TEXTUREUNITS;
- gl_state.clientunit = MAX_TEXTUREUNITS;
- for (i = 0;i < MAX_TEXTUREUNITS;i++)
- {
- unit = gl_state.units + i;
- unit->t2d = 0;
- unit->t3d = 0;
- unit->tcubemap = 0;
- unit->arrayenabled = false;
- unit->arraycomponents = 0;
- unit->pointer_texcoord = NULL;
- unit->pointer_texcoord_buffer = 0;
- unit->pointer_texcoord_offset = 0;
- unit->rgbscale = 1;
- unit->alphascale = 1;
- unit->combinergb = GL_MODULATE;
- unit->combinealpha = GL_MODULATE;
- unit->texmatrixenabled = false;
- unit->matrix = identitymatrix;
- }
-
- for (i = 0;i < vid.teximageunits;i++)
- {
- GL_ActiveTexture(i);
- qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
- if (gl_texture3d)
- {
- qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
- }
- if (gl_texturecubemap)
- {
- qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
- }
- if (gl_texturerectangle)
- {
- qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);CHECKGLERROR
- }
- }
-
- for (i = 0;i < vid.texarrayunits;i++)
- {
- GL_ClientActiveTexture(i);
- GL_BindVBO(0);
- qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
- qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
- }
-
- for (i = 0;i < vid.texunits;i++)
- {
- GL_ActiveTexture(i);
- qglDisable(GL_TEXTURE_2D);CHECKGLERROR
- if (gl_texture3d)
- {
- qglDisable(GL_TEXTURE_3D);CHECKGLERROR
- }
- if (gl_texturecubemap)
- {
- qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
- }
- if (gl_texturerectangle)
- {
- qglDisable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
- }
- qglMatrixMode(GL_TEXTURE);CHECKGLERROR
- qglLoadIdentity();CHECKGLERROR
- qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
- if (gl_combine.integer)
- {
- qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_CONSTANT_ARB);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);CHECKGLERROR
- }
- else
- {
- qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
- }
- CHECKGLERROR
- }
- CHECKGLERROR
-}
-
-void GL_Backend_ResetState(void)
-{
- memset(&gl_state, 0, sizeof(gl_state));
+ gl_state.active = true;
gl_state.depthtest = true;
gl_state.alphatest = false;
gl_state.blendfunc1 = GL_ONE;
qglDepthMask(gl_state.depthmask);CHECKGLERROR
qglPolygonOffset(gl_state.polygonoffset[0], gl_state.polygonoffset[1]);
- if (gl_support_arb_vertex_buffer_object)
+ if (vid.support.arb_vertex_buffer_object)
{
qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
- if (gl_support_ext_framebuffer_object)
+ if (vid.support.ext_framebuffer_object)
{
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
GL_Color(0, 0, 0, 0);
GL_Color(1, 1, 1, 1);
- GL_SetupTextureState();
+ gl_state.unit = MAX_TEXTUREUNITS;
+ gl_state.clientunit = MAX_TEXTUREUNITS;
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL20:
+ case RENDERPATH_CGGL:
+ for (i = 0;i < vid.teximageunits;i++)
+ {
+ GL_ActiveTexture(i);
+ qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
+ if (vid.support.ext_texture_3d)
+ {
+ qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
+ }
+ if (vid.support.arb_texture_cube_map)
+ {
+ qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
+ }
+ if (vid.support.arb_texture_rectangle)
+ {
+ qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);CHECKGLERROR
+ }
+ }
+
+ for (i = 0;i < vid.texarrayunits;i++)
+ {
+ GL_ClientActiveTexture(i);
+ GL_BindVBO(0);
+ qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
+ qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
+ }
+ CHECKGLERROR
+ break;
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL11:
+ for (i = 0;i < vid.texunits;i++)
+ {
+ GL_ActiveTexture(i);
+ GL_ClientActiveTexture(i);
+ qglDisable(GL_TEXTURE_2D);CHECKGLERROR
+ qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
+ if (vid.support.ext_texture_3d)
+ {
+ qglDisable(GL_TEXTURE_3D);CHECKGLERROR
+ qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
+ }
+ if (vid.support.arb_texture_cube_map)
+ {
+ qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
+ qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
+ }
+ if (vid.support.arb_texture_rectangle)
+ {
+ qglDisable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
+ qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);CHECKGLERROR
+ }
+ GL_BindVBO(0);
+ qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), NULL);CHECKGLERROR
+ qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
+ qglMatrixMode(GL_TEXTURE);CHECKGLERROR
+ qglLoadIdentity();CHECKGLERROR
+ qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
+ qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
+ }
+ CHECKGLERROR
+ break;
+ }
}
void GL_ActiveTexture(unsigned int num)
}
}
-void GL_LockArrays(int first, int count)
-{
- if (count < gl_lockarrays_minimumvertices.integer)
- {
- first = 0;
- count = 0;
- }
- if (gl_state.lockrange_count != count || gl_state.lockrange_first != first)
- {
- if (gl_state.lockrange_count)
- {
- gl_state.lockrange_count = 0;
- CHECKGLERROR
- qglUnlockArraysEXT();
- CHECKGLERROR
- }
- if (count && gl_supportslockarrays && gl_lockarrays.integer)
- {
- gl_state.lockrange_first = first;
- gl_state.lockrange_count = count;
- CHECKGLERROR
- qglLockArraysEXT(first, count);
- CHECKGLERROR
- }
- }
-}
-
void GL_Scissor (int x, int y, int width, int height)
{
CHECKGLERROR
Con_Printf("WARNING: gl_printcheckerror is on but gl_paranoid is off, turning it on...\n");
Cvar_SetValueQuick(&gl_paranoid, 1);
}
- GL_Backend_ResetState();
}
qboolean GL_Backend_CompileShader(int programobject, GLenum shadertypeenum, const char *shadertype, int numstrings, const char **strings)
qglCompileShaderARB(shaderobject);CHECKGLERROR
qglGetObjectParameterivARB(shaderobject, GL_OBJECT_COMPILE_STATUS_ARB, &shadercompiled);CHECKGLERROR
qglGetInfoLogARB(shaderobject, sizeof(compilelog), NULL, compilelog);CHECKGLERROR
- if (compilelog[0] && developer.integer > 0)
+ if (compilelog[0] && (strstr(compilelog, "error") || strstr(compilelog, "ERROR") || strstr(compilelog, "Error") || strstr(compilelog, "WARNING") || strstr(compilelog, "warning") || strstr(compilelog, "Warning")))
{
int i, j, pretextlines = 0;
for (i = 0;i < numstrings - 1;i++)
for (j = 0;strings[i][j];j++)
if (strings[i][j] == '\n')
pretextlines++;
- Con_DPrintf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
+ Con_Printf("%s shader compile log:\n%s\n(line offset for any above warnings/errors: %i)\n", shadertype, compilelog, pretextlines);
}
if (!shadercompiled)
{
qglGetInfoLogARB(programobject, sizeof(linklog), NULL, linklog);CHECKGLERROR
if (linklog[0])
{
- Con_DPrintf("program link log:\n%s\n", linklog);
+ if (strstr(linklog, "error") || strstr(linklog, "ERROR") || strstr(linklog, "Error") || strstr(linklog, "WARNING") || strstr(linklog, "warning") || strstr(linklog, "Warning"))
+ Con_DPrintf("program link log:\n%s\n", linklog);
// software vertex shader is ok but software fragment shader is WAY
// too slow, fail program if so.
// NOTE: this string might be ATI specific, but that's ok because the
unsigned int numelements = numtriangles * 3;
if (numvertices < 3 || numtriangles < 1)
{
- if (numvertices < 0 || numtriangles < 0 || developer.integer >= 100)
- Con_Printf("R_Mesh_Draw(%d, %d, %d, %d, %8p, %8p, %i, %i);\n", firstvertex, numvertices, firsttriangle, numtriangles, (void *)element3i, (void *)element3s, bufferobject3i, bufferobject3s);
+ if (numvertices < 0 || numtriangles < 0 || developer_extra.integer)
+ Con_DPrintf("R_Mesh_Draw(%d, %d, %d, %d, %8p, %8p, %i, %i);\n", firstvertex, numvertices, firsttriangle, numtriangles, (void *)element3i, (void *)element3s, bufferobject3i, bufferobject3s);
return;
}
if (!gl_mesh_prefer_short_elements.integer)
// restores backend state, used when done with 3D rendering
void R_Mesh_Finish(void)
{
- unsigned int i;
- BACKENDACTIVECHECK
- CHECKGLERROR
- GL_LockArrays(0, 0);
- CHECKGLERROR
-
- for (i = 0;i < vid.teximageunits;i++)
- {
- GL_ActiveTexture(i);
- qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
- if (gl_texture3d)
- {
- qglBindTexture(GL_TEXTURE_3D, 0);CHECKGLERROR
- }
- if (gl_texturecubemap)
- {
- qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);CHECKGLERROR
- }
- if (gl_texturerectangle)
- {
- qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);CHECKGLERROR
- }
- }
- for (i = 0;i < vid.texarrayunits;i++)
- {
- GL_ActiveTexture(vid.texarrayunits - 1 - i);
- qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
- }
- for (i = 0;i < vid.texunits;i++)
- {
- GL_ActiveTexture(vid.texunits - 1 - i);
- qglDisable(GL_TEXTURE_2D);CHECKGLERROR
- if (gl_texture3d)
- {
- qglDisable(GL_TEXTURE_3D);CHECKGLERROR
- }
- if (gl_texturecubemap)
- {
- qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
- }
- if (gl_texturerectangle)
- {
- qglDisable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
- }
- qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
- if (gl_combine.integer)
- {
- qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1);CHECKGLERROR
- qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);CHECKGLERROR
- }
- }
- qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
- qglDisableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
-
- qglDisable(GL_BLEND);CHECKGLERROR
- qglEnable(GL_DEPTH_TEST);CHECKGLERROR
- qglDepthMask(GL_TRUE);CHECKGLERROR
- qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);CHECKGLERROR
}
int R_Mesh_CreateStaticBufferObject(unsigned int target, void *data, size_t size, const char *name)
}
qglBufferDataARB(target, size, data, GL_STATIC_DRAW_ARB);
- info = (gl_bufferobjectinfo_t *) Mem_ExpandableArray_AllocRecord(&gl_bufferobjectinfoarray);
+ info = (gl_bufferobjectinfo_t *) Mem_ExpandableArray_AllocRecord(&gl_state.bufferobjectinfoarray);
memset(info, 0, sizeof(*info));
info->target = target;
info->object = bufferobject;
qglDeleteBuffersARB(1, (GLuint *)&bufferobject);
- endindex = Mem_ExpandableArray_IndexRange(&gl_bufferobjectinfoarray);
+ endindex = Mem_ExpandableArray_IndexRange(&gl_state.bufferobjectinfoarray);
for (i = 0;i < endindex;i++)
{
- info = (gl_bufferobjectinfo_t *) Mem_ExpandableArray_RecordAtIndex(&gl_bufferobjectinfoarray, i);
+ info = (gl_bufferobjectinfo_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.bufferobjectinfoarray, i);
if (!info)
continue;
if (info->object == bufferobject)
{
- Mem_ExpandableArray_FreeRecord(&gl_bufferobjectinfoarray, (void *)info);
+ Mem_ExpandableArray_FreeRecord(&gl_state.bufferobjectinfoarray, (void *)info);
break;
}
}
size_t ebocount = 0, ebomemory = 0;
size_t vbocount = 0, vbomemory = 0;
gl_bufferobjectinfo_t *info;
- endindex = Mem_ExpandableArray_IndexRange(&gl_bufferobjectinfoarray);
+ endindex = Mem_ExpandableArray_IndexRange(&gl_state.bufferobjectinfoarray);
for (i = 0;i < endindex;i++)
{
- info = (gl_bufferobjectinfo_t *) Mem_ExpandableArray_RecordAtIndex(&gl_bufferobjectinfoarray, i);
+ info = (gl_bufferobjectinfo_t *) Mem_ExpandableArray_RecordAtIndex(&gl_state.bufferobjectinfoarray, i);
if (!info)
continue;
switch(info->target)
Con_Printf("vertex buffers: %i element buffers totalling %i bytes (%.3f MB), %i vertex buffers totalling %i bytes (%.3f MB), combined %i bytes (%.3fMB)\n", (int)ebocount, (int)ebomemory, ebomemory / 1048576.0, (int)vbocount, (int)vbomemory, vbomemory / 1048576.0, (int)(ebomemory + vbomemory), (ebomemory + vbomemory) / 1048576.0);
}
-void R_Mesh_Matrix(const matrix4x4_t *matrix)
-{
- if (memcmp(matrix, &backend_modelmatrix, sizeof(matrix4x4_t)))
- {
- float glmatrix[16];
- backend_modelmatrix = *matrix;
- Matrix4x4_Concat(&backend_modelviewmatrix, &backend_viewport.viewmatrix, &backend_modelmatrix);
- Matrix4x4_ToArrayFloatGL(&backend_modelviewmatrix, glmatrix);
- CHECKGLERROR
- qglLoadMatrixf(glmatrix);CHECKGLERROR
- }
-}
-
void R_Mesh_VertexPointer(const float *vertex3f, int bufferobject, size_t bufferoffset)
{
if (!gl_vbo.integer || gl_mesh_testarrayelement.integer)
}
}
-void R_Mesh_TexBindAll(unsigned int unitnum, int tex2d, int tex3d, int texcubemap, int texrectangle)
+int R_Mesh_TexBound(unsigned int unitnum, int id)
{
gltextureunit_t *unit = gl_state.units + unitnum;
if (unitnum >= vid.teximageunits)
- return;
- // update 2d texture binding
- if (unit->t2d != tex2d)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (tex2d)
- {
- if (unit->t2d == 0)
- {
- qglEnable(GL_TEXTURE_2D);CHECKGLERROR
- }
- }
- else
- {
- if (unit->t2d)
- {
- qglDisable(GL_TEXTURE_2D);CHECKGLERROR
- }
- }
- }
- unit->t2d = tex2d;
- qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
- }
- // update 3d texture binding
- if (unit->t3d != tex3d)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (tex3d)
- {
- if (unit->t3d == 0)
- {
- qglEnable(GL_TEXTURE_3D);CHECKGLERROR
- }
- }
- else
- {
- if (unit->t3d)
- {
- qglDisable(GL_TEXTURE_3D);CHECKGLERROR
- }
- }
- }
- unit->t3d = tex3d;
- qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
- }
- // update cubemap texture binding
- if (unit->tcubemap != texcubemap)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (texcubemap)
- {
- if (unit->tcubemap == 0)
- {
- qglEnable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
- }
- }
- else
- {
- if (unit->tcubemap)
- {
- qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
- }
- }
- }
- unit->tcubemap = texcubemap;
- qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
- }
- // update rectangle texture binding
- if (unit->trectangle != texrectangle)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (texrectangle)
- {
- if (unit->trectangle == 0)
- {
- qglEnable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
- }
- }
- else
- {
- if (unit->trectangle)
- {
- qglDisable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
- }
- }
- }
- unit->trectangle = texrectangle;
- qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, unit->trectangle);CHECKGLERROR
- }
+ return 0;
+ if (id == GL_TEXTURE_2D)
+ return unit->t2d;
+ if (id == GL_TEXTURE_3D)
+ return unit->t3d;
+ if (id == GL_TEXTURE_CUBE_MAP_ARB)
+ return unit->tcubemap;
+ if (id == GL_TEXTURE_RECTANGLE_ARB)
+ return unit->trectangle;
+ return 0;
}
-void R_Mesh_TexBind(unsigned int unitnum, int texnum)
+void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
+{
+ R_Mesh_TexBind(0, tex);
+ GL_ActiveTexture(0);CHECKGLERROR
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, sx, sy, width, height);CHECKGLERROR
+}
+
+void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
{
gltextureunit_t *unit = gl_state.units + unitnum;
+ int tex2d, tex3d, texcubemap, texnum;
if (unitnum >= vid.teximageunits)
return;
- // update 2d texture binding
- if (unit->t2d != texnum)
+ switch(vid.renderpath)
{
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
+ case RENDERPATH_GL20:
+ case RENDERPATH_CGGL:
+ if (!tex)
+ tex = r_texture_white;
+ texnum = R_GetTexture(tex);
+ switch(tex->gltexturetypeenum)
{
- if (texnum)
+ case GL_TEXTURE_2D: if (unit->t2d != texnum) {GL_ActiveTexture(unitnum);unit->t2d = texnum;qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR}break;
+ case GL_TEXTURE_3D: if (unit->t3d != texnum) {GL_ActiveTexture(unitnum);unit->t3d = texnum;qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR}break;
+ case GL_TEXTURE_CUBE_MAP_ARB: if (unit->tcubemap != texnum) {GL_ActiveTexture(unitnum);unit->tcubemap = texnum;qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR}break;
+ case GL_TEXTURE_RECTANGLE_ARB: if (unit->trectangle != texnum) {GL_ActiveTexture(unitnum);unit->trectangle = texnum;qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, unit->trectangle);CHECKGLERROR}break;
+ }
+ break;
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL11:
+ tex2d = 0;
+ tex3d = 0;
+ texcubemap = 0;
+ if (tex)
+ {
+ texnum = R_GetTexture(tex);
+ switch(tex->gltexturetypeenum)
+ {
+ case GL_TEXTURE_2D:
+ tex2d = texnum;
+ break;
+ case GL_TEXTURE_3D:
+ tex3d = texnum;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ texcubemap = texnum;
+ break;
+ }
+ }
+ // update 2d texture binding
+ if (unit->t2d != tex2d)
+ {
+ GL_ActiveTexture(unitnum);
+ if (tex2d)
{
if (unit->t2d == 0)
{
qglDisable(GL_TEXTURE_2D);CHECKGLERROR
}
}
+ unit->t2d = tex2d;
+ qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
}
- unit->t2d = texnum;
- qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
- }
- // update 3d texture binding
- if (unit->t3d)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->t3d)
- {
- qglDisable(GL_TEXTURE_3D);CHECKGLERROR
- }
- }
- unit->t3d = 0;
- qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
- }
- // update cubemap texture binding
- if (unit->tcubemap != 0)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->tcubemap)
- {
- qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
- }
- }
- unit->tcubemap = 0;
- qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
- }
- // update rectangle texture binding
- if (unit->trectangle != 0)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->trectangle)
- {
- qglDisable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
- }
- }
- unit->trectangle = 0;
- qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, unit->trectangle);CHECKGLERROR
- }
-}
-
-void R_Mesh_TexBind3D(unsigned int unitnum, int texnum)
-{
- gltextureunit_t *unit = gl_state.units + unitnum;
- if (unitnum >= vid.teximageunits)
- return;
- // update 2d texture binding
- if (unit->t2d)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->t2d)
- {
- qglDisable(GL_TEXTURE_2D);CHECKGLERROR
- }
- }
- unit->t2d = 0;
- qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
- }
- // update 3d texture binding
- if (unit->t3d != texnum)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
+ // update 3d texture binding
+ if (unit->t3d != tex3d)
{
- if (texnum)
+ GL_ActiveTexture(unitnum);
+ if (tex3d)
{
if (unit->t3d == 0)
{
qglDisable(GL_TEXTURE_3D);CHECKGLERROR
}
}
+ unit->t3d = tex3d;
+ qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
}
- unit->t3d = texnum;
- qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
- }
- // update cubemap texture binding
- if (unit->tcubemap != 0)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->tcubemap)
- {
- qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
- }
- }
- unit->tcubemap = 0;
- qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
- }
- // update rectangle texture binding
- if (unit->trectangle != 0)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->trectangle)
- {
- qglDisable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
- }
- }
- unit->trectangle = 0;
- qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, unit->trectangle);CHECKGLERROR
- }
-}
-
-void R_Mesh_TexBindCubeMap(unsigned int unitnum, int texnum)
-{
- gltextureunit_t *unit = gl_state.units + unitnum;
- if (unitnum >= vid.teximageunits)
- return;
- // update 2d texture binding
- if (unit->t2d)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->t2d)
- {
- qglDisable(GL_TEXTURE_2D);CHECKGLERROR
- }
- }
- unit->t2d = 0;
- qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
- }
- // update 3d texture binding
- if (unit->t3d)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->t3d)
- {
- qglDisable(GL_TEXTURE_3D);CHECKGLERROR
- }
- }
- unit->t3d = 0;
- qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
- }
- // update cubemap texture binding
- if (unit->tcubemap != texnum)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
+ // update cubemap texture binding
+ if (unit->tcubemap != texcubemap)
{
- if (texnum)
+ GL_ActiveTexture(unitnum);
+ if (texcubemap)
{
if (unit->tcubemap == 0)
{
qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
}
}
+ unit->tcubemap = texcubemap;
+ qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
}
- unit->tcubemap = texnum;
- qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
- }
- // update rectangle texture binding
- if (unit->trectangle != 0)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->trectangle)
- {
- qglDisable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
- }
- }
- unit->trectangle = 0;
- qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, unit->trectangle);CHECKGLERROR
- }
-}
-
-void R_Mesh_TexBindRectangle(unsigned int unitnum, int texnum)
-{
- gltextureunit_t *unit = gl_state.units + unitnum;
- if (unitnum >= vid.teximageunits)
- return;
- // update 2d texture binding
- if (unit->t2d)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->t2d)
- {
- qglDisable(GL_TEXTURE_2D);CHECKGLERROR
- }
- }
- unit->t2d = 0;
- qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
- }
- // update 3d texture binding
- if (unit->t3d)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->t3d)
- {
- qglDisable(GL_TEXTURE_3D);CHECKGLERROR
- }
- }
- unit->t3d = 0;
- qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
- }
- // update cubemap texture binding
- if (unit->tcubemap != 0)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (unit->tcubemap)
- {
- qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
- }
- }
- unit->tcubemap = 0;
- qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
- }
- // update rectangle texture binding
- if (unit->trectangle != texnum)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
- {
- if (texnum)
- {
- if (unit->trectangle == 0)
- {
- qglEnable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
- }
- }
- else
- {
- if (unit->trectangle)
- {
- qglDisable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
- }
- }
- }
- unit->trectangle = texnum;
- qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, unit->trectangle);CHECKGLERROR
+ break;
}
}
-static const float gl_identitymatrix[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
-
void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
{
gltextureunit_t *unit = gl_state.units + unitnum;
- if (matrix->m[3][3])
+ if (matrix && matrix->m[3][3])
{
// texmatrix specified, check if it is different
if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
{
gltextureunit_t *unit = gl_state.units + unitnum;
CHECKGLERROR
- if (gl_combine.integer)
+ switch(vid.renderpath)
{
+ case RENDERPATH_GL20:
+ case RENDERPATH_CGGL:
+ // do nothing
+ break;
+ case RENDERPATH_GL13:
// GL_ARB_texture_env_combine
if (!combinergb)
combinergb = GL_MODULATE;
rgbscale = 1;
if (!alphascale)
alphascale = 1;
- if (unit->combinergb != combinergb)
- {
- unit->combinergb = combinergb;
- GL_ActiveTexture(unitnum);
- qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
- }
- if (unit->combinealpha != combinealpha)
+ if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
{
- unit->combinealpha = combinealpha;
- GL_ActiveTexture(unitnum);
- qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
- }
- if (unit->rgbscale != rgbscale)
- {
- GL_ActiveTexture(unitnum);
- qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (unit->rgbscale = rgbscale));CHECKGLERROR
+ if (combinergb == GL_DECAL)
+ combinergb = GL_INTERPOLATE_ARB;
+ if (unit->combine != GL_COMBINE_ARB)
+ {
+ unit->combine = GL_COMBINE_ARB;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);CHECKGLERROR
+ qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
+ }
+ if (unit->combinergb != combinergb)
+ {
+ unit->combinergb = combinergb;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
+ }
+ if (unit->combinealpha != combinealpha)
+ {
+ unit->combinealpha = combinealpha;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
+ }
+ if (unit->rgbscale != rgbscale)
+ {
+ unit->rgbscale = rgbscale;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, unit->rgbscale);CHECKGLERROR
+ }
+ if (unit->alphascale != alphascale)
+ {
+ unit->alphascale = alphascale;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
+ }
}
- if (unit->alphascale != alphascale)
+ else
{
- GL_ActiveTexture(unitnum);
- qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, (unit->alphascale = alphascale));CHECKGLERROR
+ if (unit->combine != combinergb)
+ {
+ unit->combine = combinergb;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
+ }
}
- }
- else
- {
+ break;
+ case RENDERPATH_GL11:
// normal GL texenv
if (!combinergb)
combinergb = GL_MODULATE;
- if (unit->combinergb != combinergb)
+ if (unit->combine != combinergb)
{
- unit->combinergb = combinergb;
+ unit->combine = combinergb;
GL_ActiveTexture(unitnum);
- qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combinergb);CHECKGLERROR
+ qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
}
+ break;
}
}
-void R_Mesh_TextureState(const rmeshstate_t *m)
-{
- unsigned int i;
-
- BACKENDACTIVECHECK
-
- CHECKGLERROR
- for (i = 0;i < vid.teximageunits;i++)
- R_Mesh_TexBindAll(i, m->tex[i], m->tex3d[i], m->texcubemap[i], m->texrectangle[i]);
- for (i = 0;i < vid.texarrayunits;i++)
- {
- if (m->pointer_texcoord3f[i])
- R_Mesh_TexCoordPointer(i, 3, m->pointer_texcoord3f[i], m->pointer_texcoord_bufferobject[i], m->pointer_texcoord_bufferoffset[i]);
- else
- R_Mesh_TexCoordPointer(i, 2, m->pointer_texcoord[i], m->pointer_texcoord_bufferobject[i], m->pointer_texcoord_bufferoffset[i]);
- }
- for (i = 0;i < vid.texunits;i++)
- {
- R_Mesh_TexMatrix(i, &m->texmatrix[i]);
- R_Mesh_TexCombine(i, m->texcombinergb[i], m->texcombinealpha[i], m->texrgbscale[i], m->texalphascale[i]);
- }
- CHECKGLERROR
-}
-
void R_Mesh_ResetTextureState(void)
{
unsigned int unitnum;
BACKENDACTIVECHECK
CHECKGLERROR
- for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
+ switch(vid.renderpath)
{
- gltextureunit_t *unit = gl_state.units + unitnum;
- // update 2d texture binding
- if (unit->t2d)
+ case RENDERPATH_GL20:
+ case RENDERPATH_CGGL:
+ for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
{
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
+ gltextureunit_t *unit = gl_state.units + unitnum;
+ if (unit->t2d)
{
- qglDisable(GL_TEXTURE_2D);CHECKGLERROR
+ unit->t2d = 0;
+ GL_ActiveTexture(unitnum);
+ qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
}
- unit->t2d = 0;
- qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
- }
- // update 3d texture binding
- if (unit->t3d)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
+ if (unit->t3d)
{
- qglDisable(GL_TEXTURE_3D);CHECKGLERROR
+ unit->t3d = 0;
+ GL_ActiveTexture(unitnum);
+ qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
}
- unit->t3d = 0;
- qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
- }
- // update cubemap texture binding
- if (unit->tcubemap)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
+ if (unit->tcubemap)
{
- qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
+ unit->tcubemap = 0;
+ GL_ActiveTexture(unitnum);
+ qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
}
- unit->tcubemap = 0;
- qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
- }
- // update rectangle texture binding
- if (unit->trectangle)
- {
- GL_ActiveTexture(unitnum);
- if (unitnum < vid.texunits)
+ if (unit->trectangle)
{
- qglDisable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
+ unit->trectangle = 0;
+ GL_ActiveTexture(unitnum);
+ qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, unit->trectangle);CHECKGLERROR
}
- unit->trectangle = 0;
- qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, unit->trectangle);CHECKGLERROR
}
- }
- for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
- {
- gltextureunit_t *unit = gl_state.units + unitnum;
- // texture array unit is disabled, disable the array
- if (unit->arrayenabled)
+ for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
{
- unit->arrayenabled = false;
- GL_ClientActiveTexture(unitnum);
- qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
+ gltextureunit_t *unit = gl_state.units + unitnum;
+ if (unit->arrayenabled)
+ {
+ unit->arrayenabled = false;
+ GL_ClientActiveTexture(unitnum);
+ qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
+ }
}
- }
- for (unitnum = 0;unitnum < vid.texunits;unitnum++)
- {
- gltextureunit_t *unit = gl_state.units + unitnum;
- // no texmatrix specified, revert to identity
- if (unit->texmatrixenabled)
+ for (unitnum = 0;unitnum < vid.texunits;unitnum++)
{
- unit->texmatrixenabled = false;
- unit->matrix = identitymatrix;
- CHECKGLERROR
- GL_ActiveTexture(unitnum);
- qglMatrixMode(GL_TEXTURE);CHECKGLERROR
- qglLoadIdentity();CHECKGLERROR
- qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
+ gltextureunit_t *unit = gl_state.units + unitnum;
+ if (unit->texmatrixenabled)
+ {
+ unit->texmatrixenabled = false;
+ unit->matrix = identitymatrix;
+ CHECKGLERROR
+ GL_ActiveTexture(unitnum);
+ qglMatrixMode(GL_TEXTURE);CHECKGLERROR
+ qglLoadIdentity();CHECKGLERROR
+ qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
+ }
}
- if (gl_combine.integer)
+ break;
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL11:
+ for (unitnum = 0;unitnum < vid.texunits;unitnum++)
{
- // GL_ARB_texture_env_combine
- if (unit->combinergb != GL_MODULATE)
+ gltextureunit_t *unit = gl_state.units + unitnum;
+ if (unit->t2d)
{
- unit->combinergb = GL_MODULATE;
+ unit->t2d = 0;
GL_ActiveTexture(unitnum);
- qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit->combinergb);CHECKGLERROR
+ qglDisable(GL_TEXTURE_2D);CHECKGLERROR
+ qglBindTexture(GL_TEXTURE_2D, unit->t2d);CHECKGLERROR
}
- if (unit->combinealpha != GL_MODULATE)
+ if (unit->t3d)
{
- unit->combinealpha = GL_MODULATE;
+ unit->t3d = 0;
GL_ActiveTexture(unitnum);
- qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, unit->combinealpha);CHECKGLERROR
+ qglDisable(GL_TEXTURE_3D);CHECKGLERROR
+ qglBindTexture(GL_TEXTURE_3D, unit->t3d);CHECKGLERROR
}
- if (unit->rgbscale != 1)
+ if (unit->tcubemap)
{
+ unit->tcubemap = 0;
GL_ActiveTexture(unitnum);
- qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (unit->rgbscale = 1));CHECKGLERROR
+ qglDisable(GL_TEXTURE_CUBE_MAP_ARB);CHECKGLERROR
+ qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, unit->tcubemap);CHECKGLERROR
}
- if (unit->alphascale != 1)
+ if (unit->trectangle)
{
+ unit->trectangle = 0;
GL_ActiveTexture(unitnum);
- qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, (unit->alphascale = 1));CHECKGLERROR
+ qglDisable(GL_TEXTURE_RECTANGLE_ARB);CHECKGLERROR
+ qglBindTexture(GL_TEXTURE_RECTANGLE_ARB, unit->trectangle);CHECKGLERROR
}
- }
- else
- {
- // normal GL texenv
- if (unit->combinergb != GL_MODULATE)
+ if (unit->arrayenabled)
{
- unit->combinergb = GL_MODULATE;
+ unit->arrayenabled = false;
+ GL_ClientActiveTexture(unitnum);
+ qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
+ }
+ if (unit->texmatrixenabled)
+ {
+ unit->texmatrixenabled = false;
+ unit->matrix = identitymatrix;
+ CHECKGLERROR
GL_ActiveTexture(unitnum);
- qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combinergb);CHECKGLERROR
+ qglMatrixMode(GL_TEXTURE);CHECKGLERROR
+ qglLoadIdentity();CHECKGLERROR
+ qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
+ }
+ if (unit->combine != GL_MODULATE)
+ {
+ unit->combine = GL_MODULATE;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
}
}
+ break;
}
}