X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=gl_backend.c;h=5b9a8d2985046049befab0019d80beb805c9f03b;hp=e03740b1ffef52c117c1984c6c100ded82fd9743;hb=f8b3aa66d600adec1c48753320d207b2817188d4;hpb=bc6e12f9c8c430e98d6cf89c96c3bfeb903e90d1 diff --git a/gl_backend.c b/gl_backend.c index e03740b1..5b9a8d29 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -1,34 +1,92 @@ #include "quakedef.h" -cvar_t r_render = {0, "r_render", "1"}; -cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1"}; // whether or not to use dithering +//cvar_t gl_mesh_maxtriangles = {0, "gl_mesh_maxtriangles", "21760"}; +cvar_t gl_mesh_maxtriangles = {0, "gl_mesh_maxtriangles", "8192"}; +//cvar_t gl_mesh_batchtriangles = {0, "gl_mesh_batchtriangles", "1024"}; +cvar_t gl_mesh_batchtriangles = {0, "gl_mesh_batchtriangles", "0"}; +cvar_t gl_mesh_floatcolors = {0, "gl_mesh_floatcolors", "0"}; +cvar_t gl_mesh_drawmode = {CVAR_SAVE, "gl_mesh_drawmode", "3"}; + +cvar_t r_render = {0, "r_render", "1"}; +cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1"}; // whether or not to use dithering +cvar_t gl_lockarrays = {0, "gl_lockarrays", "1"}; + +#ifdef DEBUGGL +int errornumber = 0; + +void GL_PrintError(int errornumber, char *filename, int linenumber) +{ + switch(errornumber) + { +#ifdef GL_INVALID_ENUM + case GL_INVALID_ENUM: + Con_Printf("GL_INVALID_ENUM at %s:%i\n", filename, linenumber); + break; +#endif +#ifdef GL_INVALID_VALUE + case GL_INVALID_VALUE: + Con_Printf("GL_INVALID_VALUE at %s:%i\n", filename, linenumber); + break; +#endif +#ifdef GL_INVALID_OPERATION + case GL_INVALID_OPERATION: + Con_Printf("GL_INVALID_OPERATION at %s:%i\n", filename, linenumber); + break; +#endif +#ifdef GL_STACK_OVERFLOW + case GL_STACK_OVERFLOW: + Con_Printf("GL_STACK_OVERFLOW at %s:%i\n", filename, linenumber); + break; +#endif +#ifdef GL_STACK_UNDERFLOW + case GL_STACK_UNDERFLOW: + Con_Printf("GL_STACK_UNDERFLOW at %s:%i\n", filename, linenumber); + break; +#endif +#ifdef GL_OUT_OF_MEMORY + case GL_OUT_OF_MEMORY: + Con_Printf("GL_OUT_OF_MEMORY at %s:%i\n", filename, linenumber); + break; +#endif +#ifdef GL_TABLE_TOO_LARGE + case GL_TABLE_TOO_LARGE: + Con_Printf("GL_TABLE_TOO_LARGE at %s:%i\n", filename, linenumber); + break; +#endif + default: + Con_Printf("GL UNKNOWN (%i) at %s:%i\n", errornumber, filename, linenumber); + break; + } +} +#endif + +float r_farclip, r_newfarclip; + +int polyindexarray[768]; + +static float viewdist; + +int c_meshs, c_meshtris, c_transmeshs, c_transtris; int lightscalebit; float lightscale; float overbrightscale; void SCR_ScreenShot_f (void); -static void R_Envmap_f (void); static int max_meshs; static int max_batch; static int max_verts; // always max_meshs * 3 #define TRANSDEPTHRES 4096 -//static cvar_t gl_mesh_maxtriangles = {0, "gl_mesh_maxtriangles", "21760"}; -static cvar_t gl_mesh_maxtriangles = {0, "gl_mesh_maxtriangles", "8192"}; -static cvar_t gl_mesh_batchtriangles = {0, "gl_mesh_batchtriangles", "1024"}; -static cvar_t gl_mesh_merge = {0, "gl_mesh_merge", "1"}; -static cvar_t gl_mesh_floatcolors = {0, "gl_mesh_floatcolors", "0"}; - typedef struct buf_mesh_s { int depthmask; int depthtest; int blendfunc1, blendfunc2; int textures[MAX_TEXTUREUNITS]; - float texturergbscale[MAX_TEXTUREUNITS]; + int texturergbscale[MAX_TEXTUREUNITS]; int firsttriangle; int triangles; int firstvert; @@ -67,7 +125,7 @@ buf_fcolor_t; typedef struct { - byte c[4]; + qbyte c[4]; } buf_bcolor_t; @@ -186,32 +244,26 @@ static void gl_backend_bufferchanges(int init) } } -float r_farclip, r_newfarclip; - static void gl_backend_newmap(void) { r_farclip = r_newfarclip = 2048.0f; } -int polyindexarray[768]; - void gl_backend_init(void) { int i; - Cvar_RegisterVariable (&r_render); - Cvar_RegisterVariable (&gl_dither); + Cvar_RegisterVariable(&r_render); + Cvar_RegisterVariable(&gl_dither); + Cvar_RegisterVariable(&gl_lockarrays); #ifdef NORENDER Cvar_SetValue("r_render", 0); #endif - Cmd_AddCommand ("screenshot",SCR_ScreenShot_f); - Cmd_AddCommand ("envmap", R_Envmap_f); - Cvar_RegisterVariable(&gl_mesh_maxtriangles); Cvar_RegisterVariable(&gl_mesh_batchtriangles); - Cvar_RegisterVariable(&gl_mesh_merge); Cvar_RegisterVariable(&gl_mesh_floatcolors); + Cvar_RegisterVariable(&gl_mesh_drawmode); R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap); gl_backend_bufferchanges(true); for (i = 0;i < 256;i++) @@ -222,16 +274,29 @@ void gl_backend_init(void) } } -static void MYgluPerspective(GLdouble fovx, GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar ) -{ - GLdouble xmax, ymax; +int arraylocked = false; - xmax = zNear * tan( fovx * M_PI / 360.0 ) * aspect; - ymax = zNear * tan( fovy * M_PI / 360.0 ); +void GL_LockArray(int first, int count) +{ + if (!arraylocked && gl_supportslockarrays && gl_lockarrays.integer && gl_mesh_drawmode.integer != 0) + { + qglLockArraysEXT(first, count); + CHECKGLERROR + arraylocked = true; + } +} - glFrustum(-xmax, xmax, -ymax, ymax, zNear, zFar ); +void GL_UnlockArray(void) +{ + if (arraylocked) + { + qglUnlockArraysEXT(); + CHECKGLERROR + arraylocked = false; + } } +//static float gldepthmin, gldepthmax; /* ============= @@ -240,65 +305,182 @@ GL_SetupFrame */ static void GL_SetupFrame (void) { + double xmax, ymax; + double fovx, fovy, zNear, zFar, aspect; + + // update farclip based on previous frame + r_farclip = r_newfarclip; + if (!r_render.integer) return; -// glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: moved to SCR_UpdateScreen - gldepthmin = 0; - gldepthmax = 1; - glDepthFunc (GL_LEQUAL); +// qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: moved to SCR_UpdateScreen +// gldepthmin = 0; +// gldepthmax = 1; + qglDepthFunc (GL_LEQUAL);CHECKGLERROR - glDepthRange (gldepthmin, gldepthmax); - - // update farclip based on previous frame - r_farclip = r_newfarclip; +// qglDepthRange (gldepthmin, gldepthmax);CHECKGLERROR // set up viewpoint - glMatrixMode(GL_PROJECTION); - glLoadIdentity (); + qglMatrixMode(GL_PROJECTION);CHECKGLERROR + qglLoadIdentity ();CHECKGLERROR // y is weird beause OpenGL is bottom to top, we use top to bottom - glViewport(r_refdef.x, vid.realheight - (r_refdef.y + r_refdef.height), r_refdef.width, r_refdef.height); -// yfov = 2*atan((float)r_refdef.height/r_refdef.width)*180/M_PI; - MYgluPerspective (r_refdef.fov_x, r_refdef.fov_y, r_refdef.width/r_refdef.height, 4.0 / 3.0, r_farclip); + qglViewport(r_refdef.x, vid.realheight - (r_refdef.y + r_refdef.height), r_refdef.width, r_refdef.height);CHECKGLERROR + + // depth range + zNear = 1.0; + zFar = r_farclip; + + // fov angles + fovx = r_refdef.fov_x; + fovy = r_refdef.fov_y; + aspect = r_refdef.width / r_refdef.height; + + // pyramid slopes + xmax = zNear * tan(fovx * M_PI / 360.0) * aspect; + ymax = zNear * tan(fovy * M_PI / 360.0); - glCullFace(GL_FRONT); + // set view pyramid + qglFrustum(-xmax, xmax, -ymax, ymax, zNear, zFar);CHECKGLERROR - glMatrixMode(GL_MODELVIEW); - glLoadIdentity (); +// qglCullFace(GL_FRONT);CHECKGLERROR - glRotatef (-90, 1, 0, 0); // put Z going up - glRotatef (90, 0, 0, 1); // put Z going up - glRotatef (-r_refdef.viewangles[2], 1, 0, 0); - glRotatef (-r_refdef.viewangles[0], 0, 1, 0); - glRotatef (-r_refdef.viewangles[1], 0, 0, 1); - glTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]); + qglMatrixMode(GL_MODELVIEW);CHECKGLERROR + qglLoadIdentity ();CHECKGLERROR -// glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix); + // put Z going up + qglRotatef (-90, 1, 0, 0);CHECKGLERROR + qglRotatef (90, 0, 0, 1);CHECKGLERROR + // camera rotation + qglRotatef (-r_refdef.viewangles[2], 1, 0, 0);CHECKGLERROR + qglRotatef (-r_refdef.viewangles[0], 0, 1, 0);CHECKGLERROR + qglRotatef (-r_refdef.viewangles[1], 0, 0, 1);CHECKGLERROR + // camera location + qglTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]);CHECKGLERROR + +// qglGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix); // // set drawing parms // // if (gl_cull.integer) - glEnable(GL_CULL_FACE); +// { +// qglEnable(GL_CULL_FACE);CHECKGLERROR +// } // else -// glDisable(GL_CULL_FACE); +// { +// qglDisable(GL_CULL_FACE);CHECKGLERROR +// } - glEnable(GL_BLEND); // was Disable - glEnable(GL_DEPTH_TEST); - glDepthMask(1); +// qglEnable(GL_BLEND);CHECKGLERROR +// qglEnable(GL_DEPTH_TEST);CHECKGLERROR +// qglDepthMask(1);CHECKGLERROR } -static float viewdist; - -int c_meshs, c_meshtris, c_transmeshs, c_transtris; +static int mesh_blendfunc1; +static int mesh_blendfunc2; +static int mesh_blend; +static GLboolean mesh_depthmask; +static int mesh_depthtest; +static int mesh_unit; +static int mesh_clientunit; +static int mesh_texture[MAX_TEXTUREUNITS]; +static float mesh_texturergbscale[MAX_TEXTUREUNITS]; + +void GL_SetupTextureState(void) +{ + int i; + if (backendunits > 1) + { + for (i = 0;i < backendunits;i++) + { + qglActiveTexture(GL_TEXTURE0_ARB + (mesh_unit = i));CHECKGLERROR + qglBindTexture(GL_TEXTURE_2D, mesh_texture[i]);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_CONSTANT_ARB);CHECKGLERROR + 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, mesh_texturergbscale[i]);CHECKGLERROR + qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);CHECKGLERROR + } + else + { + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR + } + if (mesh_texture[i]) + { + qglEnable(GL_TEXTURE_2D);CHECKGLERROR + } + else + { + qglDisable(GL_TEXTURE_2D);CHECKGLERROR + } + if (gl_mesh_drawmode.integer != 0) + { + qglClientActiveTexture(GL_TEXTURE0_ARB + (mesh_clientunit = i));CHECKGLERROR + qglTexCoordPointer(2, GL_FLOAT, sizeof(buf_texcoord_t), buf_texcoord[i]);CHECKGLERROR + if (mesh_texture[i]) + { + qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + else + { + qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + } + } + } + else + { + qglBindTexture(GL_TEXTURE_2D, mesh_texture[0]);CHECKGLERROR + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR + if (mesh_texture[0]) + { + qglEnable(GL_TEXTURE_2D);CHECKGLERROR + } + else + { + qglDisable(GL_TEXTURE_2D);CHECKGLERROR + } + if (gl_mesh_drawmode.integer != 0) + { + qglTexCoordPointer(2, GL_FLOAT, sizeof(buf_texcoord_t), buf_texcoord[0]);CHECKGLERROR + if (mesh_texture[0]) + { + qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + else + { + qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + } + } +} // called at beginning of frame -void R_Mesh_Clear(void) +int usedarrays; +void R_Mesh_Start(void) { + int i; if (!backendactive) Sys_Error("R_Mesh_Clear: called when backend is not active\n"); + CHECKGLERROR + gl_backend_bufferchanges(false); currentmesh = 0; @@ -317,64 +499,61 @@ void R_Mesh_Clear(void) c_transtris = 0; GL_SetupFrame(); -} -#ifdef DEBUGGL -void GL_PrintError(int errornumber, char *filename, int linenumber) -{ - switch(errornumber) + mesh_unit = 0; + mesh_clientunit = 0; + + for (i = 0;i < backendunits;i++) { - case GL_INVALID_ENUM: - Con_Printf("GL_INVALID_ENUM at %s:%i\n", filename, linenumber); - break; - case GL_INVALID_VALUE: - Con_Printf("GL_INVALID_VALUE at %s:%i\n", filename, linenumber); - break; - case GL_INVALID_OPERATION: - Con_Printf("GL_INVALID_OPERATION at %s:%i\n", filename, linenumber); - break; - case GL_STACK_OVERFLOW: - Con_Printf("GL_STACK_OVERFLOW at %s:%i\n", filename, linenumber); - break; - case GL_STACK_UNDERFLOW: - Con_Printf("GL_STACK_UNDERFLOW at %s:%i\n", filename, linenumber); - break; - case GL_OUT_OF_MEMORY: - Con_Printf("GL_OUT_OF_MEMORY at %s:%i\n", filename, linenumber); - break; -#ifdef GL_TABLE_TOO_LARGE - case GL_TABLE_TOO_LARGE: - Con_Printf("GL_TABLE_TOO_LARGE at %s:%i\n", filename, linenumber); - break; -#endif - default: - Con_Printf("GL UNKNOWN (%i) at %s:%i\n", errornumber, filename, linenumber); - break; + mesh_texture[i] = 0; + mesh_texturergbscale[i] = 1; } + + qglEnable(GL_CULL_FACE);CHECKGLERROR + qglCullFace(GL_FRONT);CHECKGLERROR + + mesh_depthtest = true; + qglEnable(GL_DEPTH_TEST);CHECKGLERROR + + mesh_blendfunc1 = GL_ONE; + mesh_blendfunc2 = GL_ZERO; + qglBlendFunc(mesh_blendfunc1, mesh_blendfunc2);CHECKGLERROR + + mesh_blend = 0; + qglDisable(GL_BLEND);CHECKGLERROR + + mesh_depthmask = GL_TRUE; + qglDepthMask(mesh_depthmask);CHECKGLERROR + + usedarrays = false; + if (gl_mesh_drawmode.integer != 0) + { + usedarrays = true; + qglVertexPointer(3, GL_FLOAT, sizeof(buf_vertex_t), &buf_vertex[0].v[0]);CHECKGLERROR + qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR + if (gl_mesh_floatcolors.integer) + { + qglColorPointer(4, GL_FLOAT, sizeof(buf_fcolor_t), &buf_fcolor[0].c[0]);CHECKGLERROR + } + else + { + qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(buf_bcolor_t), &buf_bcolor[0].c[0]);CHECKGLERROR + } + qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR + } + + GL_SetupTextureState(); } -int errornumber = 0; -#endif +int gl_backend_rebindtextures; -// renders mesh buffers, called to flush buffers when full -void R_Mesh_Render(void) +void GL_UpdateFarclip(void) { - int i, k, blendfunc1, blendfunc2, blend, depthmask, depthtest, unit = 0, clientunit = 0, firsttriangle, endtriangle, indexcount, firstvert, endvert, texture[MAX_TEXTUREUNITS]; - float farclip, texturergbscale[MAX_TEXTUREUNITS]; - buf_mesh_t *mesh; - unsigned int *index; - // float to byte color conversion - int *icolor; - float *fcolor; - byte *bcolor; - if (!backendactive) - Sys_Error("R_Mesh_Render: called when backend is not active\n"); - if (!currentmesh) - return; - -CHECKGLERROR + int i; + float farclip; // push out farclip based on vertices + // FIXME: wouldn't this be slow when using matrix transforms? for (i = 0;i < currentvertex;i++) { farclip = DotProduct(buf_vertex[i].v, vpn); @@ -387,391 +566,338 @@ CHECKGLERROR // push out farclip for next frame if (farclip > r_newfarclip) r_newfarclip = ceil((farclip + 255) / 256) * 256 + 256; +} - for (i = 0;i < backendunits;i++) - texturergbscale[i] = 1; - - glEnable(GL_CULL_FACE); -CHECKGLERROR - glCullFace(GL_FRONT); -CHECKGLERROR - depthtest = true; - glEnable(GL_DEPTH_TEST); -CHECKGLERROR - blendfunc1 = GL_ONE; - blendfunc2 = GL_ZERO; - glBlendFunc(blendfunc1, blendfunc2); -CHECKGLERROR - blend = 0; - glDisable(GL_BLEND); -CHECKGLERROR - depthmask = true; - glDepthMask((GLboolean) depthmask); -CHECKGLERROR - - glVertexPointer(3, GL_FLOAT, sizeof(buf_vertex_t), &buf_vertex[0].v[0]); -CHECKGLERROR - glEnableClientState(GL_VERTEX_ARRAY); -CHECKGLERROR - if (gl_mesh_floatcolors.integer) +void GL_ConvertColorsFloatToByte(void) +{ + int i, k, *icolor; + float *fcolor; + qbyte *bcolor; + + // shift float to have 8bit fraction at base of number + for (i = 0, fcolor = &buf_fcolor->c[0];i < currentvertex;i++) { - glColorPointer(4, GL_FLOAT, sizeof(buf_fcolor_t), &buf_fcolor[0].c[0]); -CHECKGLERROR + *fcolor++ += 32768.0f; + *fcolor++ += 32768.0f; + *fcolor++ += 32768.0f; + *fcolor++ += 32768.0f; } - else + // then read as integer and kill float bits... + for (i = 0, icolor = (int *)&buf_fcolor->c[0], bcolor = &buf_bcolor->c[0];i < currentvertex;i++) { - // shift float to have 8bit fraction at base of number - for (i = 0, fcolor = &buf_fcolor->c[0];i < currentvertex;i++) - { - *fcolor++ += 32768.0f; - *fcolor++ += 32768.0f; - *fcolor++ += 32768.0f; - *fcolor++ += 32768.0f; - } - // then read as integer and kill float bits... - for (i = 0, icolor = (int *)&buf_fcolor->c[0], bcolor = &buf_bcolor->c[0];i < currentvertex;i++) - { - k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; - k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; - k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; - k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; - } - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(buf_bcolor_t), &buf_bcolor[0].c[0]); -CHECKGLERROR + k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; + k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; + k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; + k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k; } - glEnableClientState(GL_COLOR_ARRAY); -CHECKGLERROR +} +void GL_MeshState(buf_mesh_t *mesh) +{ + int i; if (backendunits > 1) { for (i = 0;i < backendunits;i++) { - qglActiveTexture(GL_TEXTURE0_ARB + (unit = i)); -CHECKGLERROR - glBindTexture(GL_TEXTURE_2D, (texture[i] = 0)); -CHECKGLERROR - glDisable(GL_TEXTURE_2D); -CHECKGLERROR - if (gl_combine.integer) - { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_CONSTANT_ARB); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA); -CHECKGLERROR - glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0f); -CHECKGLERROR - glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0f); -CHECKGLERROR - } - else - { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -CHECKGLERROR - } - - qglClientActiveTexture(GL_TEXTURE0_ARB + (clientunit = i)); -CHECKGLERROR - glTexCoordPointer(2, GL_FLOAT, sizeof(buf_texcoord_t), buf_texcoord[i]); -CHECKGLERROR - glEnableClientState(GL_TEXTURE_COORD_ARRAY); -CHECKGLERROR - } - } - else - { - glBindTexture(GL_TEXTURE_2D, (texture[0] = 0)); -CHECKGLERROR - glDisable(GL_TEXTURE_2D); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -CHECKGLERROR - - glTexCoordPointer(2, GL_FLOAT, sizeof(buf_texcoord_t), buf_texcoord[0]); -CHECKGLERROR - glEnableClientState(GL_TEXTURE_COORD_ARRAY); -CHECKGLERROR - } - - // lock as early as possible - GL_LockArray(0, currentvertex); -CHECKGLERROR - - for (k = 0;k < currentmesh;) - { - mesh = &buf_mesh[k]; - - if (backendunits > 1) - { -// int topunit = 0; - for (i = 0;i < backendunits;i++) + if (mesh_texture[i] != mesh->textures[i]) { - if (texture[i] != mesh->textures[i]) + if (mesh_unit != i) { - if (unit != i) - { - qglActiveTexture(GL_TEXTURE0_ARB + (unit = i)); -CHECKGLERROR - } - if (texture[i] == 0) - { - glEnable(GL_TEXTURE_2D); -CHECKGLERROR - // have to disable texcoord array on disabled texture - // units due to NVIDIA driver bug with - // compiled_vertex_array - if (clientunit != i) - { - qglClientActiveTexture(GL_TEXTURE0_ARB + (clientunit = i)); -CHECKGLERROR - } - glEnableClientState(GL_TEXTURE_COORD_ARRAY); -CHECKGLERROR - } - glBindTexture(GL_TEXTURE_2D, (texture[i] = mesh->textures[i])); -CHECKGLERROR - if (texture[i] == 0) + qglActiveTexture(GL_TEXTURE0_ARB + (mesh_unit = i));CHECKGLERROR + } + if (mesh_texture[i] == 0) + { + qglEnable(GL_TEXTURE_2D);CHECKGLERROR + // have to disable texcoord array on disabled texture + // units due to NVIDIA driver bug with + // compiled_vertex_array + if (mesh_clientunit != i) { - glDisable(GL_TEXTURE_2D); -CHECKGLERROR - // have to disable texcoord array on disabled texture - // units due to NVIDIA driver bug with - // compiled_vertex_array - if (clientunit != i) - { - qglClientActiveTexture(GL_TEXTURE0_ARB + (clientunit = i)); -CHECKGLERROR - } - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -CHECKGLERROR + qglClientActiveTexture(GL_TEXTURE0_ARB + (mesh_clientunit = i));CHECKGLERROR } + qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR } - if (texturergbscale[i] != mesh->texturergbscale[i]) + qglBindTexture(GL_TEXTURE_2D, (mesh_texture[i] = mesh->textures[i]));CHECKGLERROR + if (mesh_texture[i] == 0) { - if (unit != i) + qglDisable(GL_TEXTURE_2D);CHECKGLERROR + // have to disable texcoord array on disabled texture + // units due to NVIDIA driver bug with + // compiled_vertex_array + if (mesh_clientunit != i) { - qglActiveTexture(GL_TEXTURE0_ARB + (unit = i)); -CHECKGLERROR + qglClientActiveTexture(GL_TEXTURE0_ARB + (mesh_clientunit = i));CHECKGLERROR } - glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (texturergbscale[i] = mesh->texturergbscale[i])); -CHECKGLERROR + qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR } -// if (texture[i]) -// topunit = i; } -// if (unit != topunit) -// { -// qglActiveTexture(GL_TEXTURE0_ARB + (unit = topunit)); -//CHECKGLERROR -// } - } - else - { - if (texture[0] != mesh->textures[0]) + if (mesh_texturergbscale[i] != mesh->texturergbscale[i]) { - if (texture[0] == 0) + if (mesh_unit != i) { - glEnable(GL_TEXTURE_2D); -CHECKGLERROR - glEnableClientState(GL_TEXTURE_COORD_ARRAY); -CHECKGLERROR - } - glBindTexture(GL_TEXTURE_2D, (texture[0] = mesh->textures[0])); -CHECKGLERROR - if (texture[0] == 0) - { - glDisable(GL_TEXTURE_2D); -CHECKGLERROR - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -CHECKGLERROR + qglActiveTexture(GL_TEXTURE0_ARB + (mesh_unit = i));CHECKGLERROR } + qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (mesh_texturergbscale[i] = mesh->texturergbscale[i]));CHECKGLERROR } } - if (blendfunc1 != mesh->blendfunc1 || blendfunc2 != mesh->blendfunc2) + } + else + { + if (mesh_texture[0] != mesh->textures[0]) { - blendfunc1 = mesh->blendfunc1; - blendfunc2 = mesh->blendfunc2; - glBlendFunc(blendfunc1, blendfunc2); -CHECKGLERROR - if (blendfunc2 == GL_ZERO) + if (mesh_texture[0] == 0) { - if (blendfunc1 == GL_ONE) - { - if (blend) - { - blend = 0; - glDisable(GL_BLEND); -CHECKGLERROR - } - } - else + qglEnable(GL_TEXTURE_2D);CHECKGLERROR + qglEnableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + qglBindTexture(GL_TEXTURE_2D, (mesh_texture[0] = mesh->textures[0]));CHECKGLERROR + if (mesh_texture[0] == 0) + { + qglDisable(GL_TEXTURE_2D);CHECKGLERROR + qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + } + } + if (mesh_blendfunc1 != mesh->blendfunc1 || mesh_blendfunc2 != mesh->blendfunc2) + { + qglBlendFunc(mesh_blendfunc1 = mesh->blendfunc1, mesh_blendfunc2 = mesh->blendfunc2);CHECKGLERROR + if (mesh_blendfunc2 == GL_ZERO) + { + if (mesh_blendfunc1 == GL_ONE) + { + if (mesh_blend) { - if (!blend) - { - blend = 1; - glEnable(GL_BLEND); -CHECKGLERROR - } + mesh_blend = 0; + qglDisable(GL_BLEND);CHECKGLERROR } } else { - if (!blend) + if (!mesh_blend) { - blend = 1; - glEnable(GL_BLEND); -CHECKGLERROR + mesh_blend = 1; + qglEnable(GL_BLEND);CHECKGLERROR } } } - if (depthtest != mesh->depthtest) - { - depthtest = mesh->depthtest; - if (depthtest) - glEnable(GL_DEPTH_TEST); - else - glDisable(GL_DEPTH_TEST); - } - if (depthmask != mesh->depthmask) + else { - depthmask = mesh->depthmask; - glDepthMask((GLboolean) depthmask); -CHECKGLERROR + if (!mesh_blend) + { + mesh_blend = 1; + qglEnable(GL_BLEND);CHECKGLERROR + } } + } + if (mesh_depthtest != mesh->depthtest) + { + mesh_depthtest = mesh->depthtest; + if (mesh_depthtest) + qglEnable(GL_DEPTH_TEST); + else + qglDisable(GL_DEPTH_TEST); + } + if (mesh_depthmask != mesh->depthmask) + { + qglDepthMask(mesh_depthmask = mesh->depthmask);CHECKGLERROR + } +} - firsttriangle = mesh->firsttriangle; - firstvert = mesh->firstvert; - endtriangle = firsttriangle + mesh->triangles; - endvert = firstvert + mesh->verts; +void GL_DrawRangeElements(int firstvert, int endvert, int indexcount, GLuint *index) +{ + unsigned int i, j, in; + if (gl_mesh_drawmode.integer == 3 && qglDrawRangeElements == NULL) + Cvar_SetValueQuick(&gl_mesh_drawmode, 2); - mesh = &buf_mesh[++k]; - if (gl_mesh_merge.integer) + if (gl_mesh_drawmode.integer == 3) + { + // GL 1.2 or GL 1.1 with extension + qglDrawRangeElements(GL_TRIANGLES, firstvert, endvert, indexcount, GL_UNSIGNED_INT, index); + } + else if (gl_mesh_drawmode.integer == 2) + { + // GL 1.1 + qglDrawElements(GL_TRIANGLES, indexcount, GL_UNSIGNED_INT, index); + } + else if (gl_mesh_drawmode.integer == 1) + { + // GL 1.1 + // feed it manually using glArrayElement + qglBegin(GL_TRIANGLES); + for (i = 0;i < indexcount;i++) + qglArrayElement(index[i]); + qglEnd(); + } + else + { + // GL 1.1 but not using vertex arrays - 3dfx glquake minigl driver + // feed it manually + if (gl_mesh_drawmode.integer != 0) + Cvar_SetValueQuick(&gl_mesh_drawmode, 0); + qglBegin(GL_TRIANGLES); + if (r_multitexture.integer) + { + // the minigl doesn't have this (because it does not have ARB_multitexture) + for (i = 0;i < indexcount;i++) + { + in = index[i]; + qglColor4ub(buf_bcolor[in].c[0], buf_bcolor[in].c[1], buf_bcolor[in].c[2], buf_bcolor[in].c[3]); + for (j = 0;j < backendunits;j++) + if (mesh_texture[j]) + qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, buf_texcoord[j][in].t[0], buf_texcoord[j][in].t[1]); + qglVertex3f(buf_vertex[in].v[0], buf_vertex[in].v[1], buf_vertex[in].v[2]); + } + } + else { - #if MAX_TEXTUREUNITS != 4 - #error update this code - #endif - while (k < currentmesh - && mesh->firsttriangle == endtriangle - && mesh->firstvert == endvert - && mesh->depthmask == depthmask - && mesh->depthtest == depthtest - && mesh->blendfunc1 == blendfunc1 - && mesh->blendfunc2 == blendfunc2 - && mesh->textures[0] == texture[0] - && mesh->textures[1] == texture[1] - && mesh->textures[2] == texture[2] - && mesh->textures[3] == texture[3] - && mesh->texturergbscale[0] == texturergbscale[0] - && mesh->texturergbscale[1] == texturergbscale[1] - && mesh->texturergbscale[2] == texturergbscale[2] - && mesh->texturergbscale[3] == texturergbscale[3]) + for (i = 0;i < indexcount;i++) { - endtriangle += mesh->triangles; - endvert += mesh->verts; - mesh = &buf_mesh[++k]; + in = index[i]; + qglColor4ub(buf_bcolor[in].c[0], buf_bcolor[in].c[1], buf_bcolor[in].c[2], buf_bcolor[in].c[3]); + if (mesh_texture[0]) + qglTexCoord2f(buf_texcoord[0][in].t[0], buf_texcoord[0][in].t[1]); + qglVertex3f(buf_vertex[in].v[0], buf_vertex[in].v[1], buf_vertex[in].v[2]); } } + qglEnd(); + } + /* + if (qglDrawRangeElements) + qglDrawRangeElements(GL_TRIANGLES, firstvert, endvert, indexcount, index); + else + { + } + #ifdef WIN32 + // FIXME: dynamic link to GL so we can get DrawRangeElements on WIN32 + qglDrawElements(GL_TRIANGLES, indexcount, GL_UNSIGNED_INT, index);CHECKGLERROR + #else + qglDrawRangeElements(GL_TRIANGLES, firstvert, firstvert + mesh->verts, indexcount, GL_UNSIGNED_INT, index);CHECKGLERROR + #endif + */ +} - indexcount = (endtriangle - firsttriangle) * 3; - index = (unsigned int *)&buf_tri[firsttriangle].index[0]; - for (i = 0;i < indexcount;i++) - index[i] += firstvert; +// renders mesh buffers, called to flush buffers when full +void R_Mesh_Render(void) +{ + int i; + int k; + int indexcount; + int firstvert; + buf_mesh_t *mesh; + unsigned int *index; -#ifdef WIN32 - // FIXME: dynamic link to GL so we can get DrawRangeElements on WIN32 - glDrawElements(GL_TRIANGLES, indexcount, GL_UNSIGNED_INT, index); -#else - glDrawRangeElements(GL_TRIANGLES, firstvert, endvert, indexcount, GL_UNSIGNED_INT, index); -#endif -CHECKGLERROR + if (!backendactive) + Sys_Error("R_Mesh_Render: called when backend is not active\n"); + + if (!currentmesh) + return; + + CHECKGLERROR + + GL_UpdateFarclip(); + + if (!gl_mesh_floatcolors.integer || gl_mesh_drawmode.integer == 0) + GL_ConvertColorsFloatToByte(); + + // lock the arrays now that they will have no further modifications + //GL_LockArray(0, currentvertex);CHECKGLERROR + if (gl_backend_rebindtextures) + { + gl_backend_rebindtextures = false; + GL_SetupTextureState(); + } + + GL_MeshState(buf_mesh); + GL_LockArray(0, currentvertex); + GL_DrawRangeElements(buf_mesh->firstvert, buf_mesh->firstvert + buf_mesh->verts, buf_mesh->triangles * 3, (unsigned int *)&buf_tri[buf_mesh->firsttriangle].index[0]);CHECKGLERROR + + if (currentmesh >= 2) + { + for (k = 1, mesh = buf_mesh + k;k < currentmesh;k++, mesh++) + { + GL_MeshState(mesh); + + firstvert = mesh->firstvert; + indexcount = mesh->triangles * 3; + index = (unsigned int *)&buf_tri[mesh->firsttriangle].index[0]; + + // if not using batching, skip the index adjustment + if (firstvert != 0) + for (i = 0;i < indexcount;i++) + index[i] += firstvert; + + GL_DrawRangeElements(firstvert, firstvert + mesh->verts, indexcount, index);CHECKGLERROR + } } currentmesh = 0; currenttriangle = 0; currentvertex = 0; - GL_UnlockArray(); -CHECKGLERROR + GL_UnlockArray();CHECKGLERROR +} + +// restores backend state, used when done with 3D rendering +void R_Mesh_Finish(void) +{ + int i; + // flush any queued meshs + R_Mesh_Render(); if (backendunits > 1) { for (i = backendunits - 1;i >= 0;i--) { - qglActiveTexture(GL_TEXTURE0_ARB + (unit = i)); -CHECKGLERROR - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -CHECKGLERROR + qglActiveTexture(GL_TEXTURE0_ARB + i);CHECKGLERROR + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR if (gl_combine.integer) { - glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0f); -CHECKGLERROR + qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1);CHECKGLERROR } if (i > 0) { - glDisable(GL_TEXTURE_2D); -CHECKGLERROR + qglDisable(GL_TEXTURE_2D);CHECKGLERROR } else { - glEnable(GL_TEXTURE_2D); -CHECKGLERROR + qglEnable(GL_TEXTURE_2D);CHECKGLERROR } - glBindTexture(GL_TEXTURE_2D, 0); -CHECKGLERROR + qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR - qglClientActiveTexture(GL_TEXTURE0_ARB + (clientunit = i)); -CHECKGLERROR - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -CHECKGLERROR + if (usedarrays) + { + qglClientActiveTexture(GL_TEXTURE0_ARB + i);CHECKGLERROR + qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } } } else { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -CHECKGLERROR - glEnable(GL_TEXTURE_2D); -CHECKGLERROR - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -CHECKGLERROR + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR + qglEnable(GL_TEXTURE_2D);CHECKGLERROR + if (usedarrays) + { + qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR + } + } + if (usedarrays) + { + qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR + qglDisableClientState(GL_VERTEX_ARRAY);CHECKGLERROR } - glDisableClientState(GL_COLOR_ARRAY); -CHECKGLERROR - glDisableClientState(GL_VERTEX_ARRAY); -CHECKGLERROR - - glDisable(GL_BLEND); -CHECKGLERROR - glEnable(GL_DEPTH_TEST); -CHECKGLERROR - glDepthMask(true); -CHECKGLERROR - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -CHECKGLERROR + + qglDisable(GL_BLEND);CHECKGLERROR + qglEnable(GL_DEPTH_TEST);CHECKGLERROR + qglDepthMask(GL_TRUE);CHECKGLERROR + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);CHECKGLERROR +} + +void R_Mesh_ClearDepth(void) +{ + R_Mesh_AddTransparent(); + R_Mesh_Finish(); + qglClear(GL_DEPTH_BUFFER_BIT); + R_Mesh_Start(); } void R_Mesh_AddTransparent(void) @@ -833,7 +959,7 @@ void R_Mesh_AddTransparent(void) if (center < 0.0f) center = 0.0f; center += 8388608.0f; - i = *((long *)¢er) & 0x7FFFFF; + i = *((int *)¢er) & 0x7FFFFF; i = min(i, (TRANSDEPTHRES - 1)); #endif tri->next = buf_sorttranstri_list[i]; @@ -1398,16 +1524,17 @@ void R_Mesh_DrawPolygon(rmeshinfo_t *m, int numverts) ============================================================================== */ -float CalcFov (float fov_x, float width, float height); -void R_ClearScreen(void); - -void SCR_ScreenShot(char *filename, int x, int y, int width, int height) +qboolean SCR_ScreenShot(char *filename, int x, int y, int width, int height) { + qboolean ret; int i; - byte *buffer; + qbyte *buffer; + + if (!r_render.integer) + return false; buffer = Mem_Alloc(tempmempool, width*height*3); - glReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer); + qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer); CHECKGLERROR // LordHavoc: compensate for v_overbrightbits when using hardware gamma @@ -1415,114 +1542,10 @@ void SCR_ScreenShot(char *filename, int x, int y, int width, int height) for (i = 0;i < width * height * 3;i++) buffer[i] <<= v_overbrightbits.integer; - Image_WriteTGARGB_preflipped(filename, width, height, buffer); + ret = Image_WriteTGARGB_preflipped(filename, width, height, buffer); Mem_Free(buffer); -} - -/* -================== -SCR_ScreenShot_f -================== -*/ -void SCR_ScreenShot_f (void) -{ - int i; - char filename[16]; - char checkname[MAX_OSPATH]; -// -// find a file name to save it to -// - strcpy(filename, "dp0000.tga"); - - for (i=0 ; i<=9999 ; i++) - { - filename[2] = (i/1000)%10 + '0'; - filename[3] = (i/ 100)%10 + '0'; - filename[4] = (i/ 10)%10 + '0'; - filename[5] = (i/ 1)%10 + '0'; - sprintf (checkname, "%s/%s", com_gamedir, filename); - if (Sys_FileTime(checkname) == -1) - break; // file doesn't exist - } - if (i==10000) - { - Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n"); - return; - } - - SCR_ScreenShot(filename, vid.realx, vid.realy, vid.realwidth, vid.realheight); - Con_Printf ("Wrote %s\n", filename); -} - -/* -=============== -R_Envmap_f - -Grab six views for environment mapping tests -=============== -*/ -struct -{ - float angles[3]; - char *name; -} -envmapinfo[6] = -{ - {{ 0, 0, 0}, "ft"}, - {{ 0, 90, 0}, "rt"}, - {{ 0, 180, 0}, "bk"}, - {{ 0, 270, 0}, "lf"}, - {{-90, 90, 0}, "up"}, - {{ 90, 90, 0}, "dn"} -}; -static void R_Envmap_f (void) -{ - int j, size; - char filename[256], basename[256]; - - if (Cmd_Argc() != 3) - { - Con_Printf ("envmap : save out 6 cubic environment map images, usable with loadsky, note that size must one of 128, 256, 512, or 1024 and can't be bigger than your current resolution\n"); - return; - } - - if (!r_render.integer) - return; - - strcpy(basename, Cmd_Argv(1)); - size = atoi(Cmd_Argv(2)); - if (size != 128 && size != 256 && size != 512 && size != 1024) - { - Con_Printf("envmap: size must be one of 128, 256, 512, or 1024\n"); - return; - } - if (size > vid.realwidth || size > vid.realheight) - { - Con_Printf("envmap: your resolution is not big enough to render that size\n"); - return; - } - - envmap = true; - - r_refdef.x = 0; - r_refdef.y = 0; - r_refdef.width = size; - r_refdef.height = size; - - r_refdef.fov_x = 90; - r_refdef.fov_y = 90; - - for (j = 0;j < 6;j++) - { - sprintf(filename, "env/%s%s.tga", basename, envmapinfo[j].name); - VectorCopy(envmapinfo[j].angles, r_refdef.viewangles); - R_ClearScreen(); - R_RenderView (); - SCR_ScreenShot(filename, vid.realx, vid.realy, size, size); - } - - envmap = false; + return ret; } //============================================================================= @@ -1531,15 +1554,19 @@ void R_ClearScreen(void) { if (r_render.integer) { - glClearColor(0,0,0,0); - CHECKGLERROR - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // LordHavoc: clear the screen (around the view as well) - CHECKGLERROR + // clear to black + qglClearColor(0,0,0,0);CHECKGLERROR + // clear the screen + qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);CHECKGLERROR + // set dithering mode if (gl_dither.integer) - glEnable(GL_DITHER); + { + qglEnable(GL_DITHER);CHECKGLERROR + } else - glDisable(GL_DITHER); - CHECKGLERROR + { + qglDisable(GL_DITHER);CHECKGLERROR + } } } @@ -1556,9 +1583,6 @@ void SCR_UpdateScreen (void) //Mem_CheckSentinelsGlobal(); //R_TimeReport("memtest"); - glFinish (); - CHECKGLERROR - VID_Finish (); R_TimeReport("finish"); @@ -1584,4 +1608,8 @@ void SCR_UpdateScreen (void) // draw 2D stuff R_DrawQueue(); + + // tell driver to commit it's partially full geometry queue to the rendering queue + // (this doesn't wait for the commands themselves to complete) + qglFlush(); }