X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_backend.c;h=c5fa542f4783654d115021070022080bcbb7d53c;hb=d276f1a6f80c5b55e89406e19c2d6028f41da34d;hp=65b2c4a1c8e1769ce02445f1058b33c7fbc63730;hpb=bcdca3f76b1e1020eeebd27e5721ec4fe57523a1;p=xonotic%2Fdarkplaces.git diff --git a/gl_backend.c b/gl_backend.c index 65b2c4a1..c5fa542f 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -1,5 +1,6 @@ #include "quakedef.h" +#include "image.h" cvar_t gl_mesh_maxverts = {0, "gl_mesh_maxverts", "1024"}; cvar_t gl_mesh_floatcolors = {0, "gl_mesh_floatcolors", "1"}; @@ -79,11 +80,29 @@ static matrix4x4_t backend_viewmatrix; static matrix4x4_t backend_modelmatrix; static matrix4x4_t backend_modelviewmatrix; static matrix4x4_t backend_glmodelviewmatrix; +static matrix4x4_t backend_projectmatrix; static int backendunits, backendactive; static qbyte *varray_bcolor; static mempool_t *gl_backend_mempool; +/* +note: here's strip order for a terrain row: +0--1--2--3--4 +|\ |\ |\ |\ | +| \| \| \| \| +A--B--C--D--E + +A0B, 01B, B1C, 12C, C2D, 23D, D3E, 34E + +*elements++ = i + row; +*elements++ = i; +*elements++ = i + row + 1; +*elements++ = i; +*elements++ = i + 1; +*elements++ = i + row + 1; +*/ + int polygonelements[768]; void GL_Backend_AllocArrays(void) @@ -230,7 +249,7 @@ void GL_SetupView_Mode_Perspective (double fovx, double fovy, double zNear, doub // set up viewpoint qglMatrixMode(GL_PROJECTION);CHECKGLERROR - qglLoadIdentity ();CHECKGLERROR + qglLoadIdentity();CHECKGLERROR // pyramid slopes xmax = zNear * tan(fovx * M_PI / 360.0); ymax = zNear * tan(fovy * M_PI / 360.0); @@ -242,14 +261,14 @@ void GL_SetupView_Mode_Perspective (double fovx, double fovy, double zNear, doub void GL_SetupView_Mode_PerspectiveInfiniteFarClip (double fovx, double fovy, double zNear) { - double nudge, m[16]; + float nudge, m[16]; if (!r_render.integer) return; // set up viewpoint qglMatrixMode(GL_PROJECTION);CHECKGLERROR - qglLoadIdentity ();CHECKGLERROR + qglLoadIdentity();CHECKGLERROR // set view pyramid nudge = 1.0 - 1.0 / (1<<23); m[ 0] = 1.0 / tan(fovx * M_PI / 360.0); @@ -268,9 +287,25 @@ void GL_SetupView_Mode_PerspectiveInfiniteFarClip (double fovx, double fovy, dou m[13] = 0; m[14] = -2 * zNear * nudge; m[15] = 0; - qglLoadMatrixd(m); + qglLoadMatrixf(m); qglMatrixMode(GL_MODELVIEW);CHECKGLERROR GL_SetupView_Orientation_Identity(); + backend_projectmatrix.m[0][0] = m[0]; + backend_projectmatrix.m[1][0] = m[1]; + backend_projectmatrix.m[2][0] = m[2]; + backend_projectmatrix.m[3][0] = m[3]; + backend_projectmatrix.m[0][1] = m[4]; + backend_projectmatrix.m[1][1] = m[5]; + backend_projectmatrix.m[2][1] = m[6]; + backend_projectmatrix.m[3][1] = m[7]; + backend_projectmatrix.m[0][2] = m[8]; + backend_projectmatrix.m[1][2] = m[9]; + backend_projectmatrix.m[2][2] = m[10]; + backend_projectmatrix.m[3][2] = m[11]; + backend_projectmatrix.m[0][3] = m[12]; + backend_projectmatrix.m[1][3] = m[13]; + backend_projectmatrix.m[2][3] = m[14]; + backend_projectmatrix.m[3][3] = m[15]; } void GL_SetupView_Mode_Ortho (double x1, double y1, double x2, double y2, double zNear, double zFar) @@ -280,7 +315,7 @@ void GL_SetupView_Mode_Ortho (double x1, double y1, double x2, double y2, double // set up viewpoint qglMatrixMode(GL_PROJECTION);CHECKGLERROR - qglLoadIdentity ();CHECKGLERROR + qglLoadIdentity();CHECKGLERROR qglOrtho(x1, x2, y2, y1, zNear, zFar); qglMatrixMode(GL_MODELVIEW);CHECKGLERROR GL_SetupView_Orientation_Identity(); @@ -288,9 +323,9 @@ void GL_SetupView_Mode_Ortho (double x1, double y1, double x2, double y2, double typedef struct gltextureunit_s { - unsigned int t1d, t2d, t3d, tcubemap; - unsigned int arrayenabled; - float rgbscale; + int t1d, t2d, t3d, tcubemap; + int arrayenabled; + float rgbscale, alphascale; int combinergb, combinealpha; // FIXME: add more combine stuff } @@ -326,11 +361,12 @@ void GL_SetupTextureState(void) unit->t3d = 0; unit->tcubemap = 0; unit->rgbscale = 1; + unit->alphascale = 1; unit->combinergb = GL_MODULATE; unit->combinealpha = GL_MODULATE; unit->arrayenabled = false; qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR - if (gl_texture3d) + if (gl_texture3d || gl_texturecubemap) { qglTexCoordPointer(3, GL_FLOAT, sizeof(float[4]), varray_texcoord[i]);CHECKGLERROR } @@ -428,6 +464,18 @@ void GL_Color(float cr, float cg, float cb, float ca) qglColor4f(cr, cg, cb, ca); } +void GL_TransformToScreen(const vec4_t in, vec4_t out) +{ + vec4_t temp; + float iw; + Matrix4x4_Transform4 (&backend_viewmatrix, in, temp); + Matrix4x4_Transform4 (&backend_projectmatrix, temp, out); + iw = 1.0f / out[3]; + out[0] = r_refdef.x + (out[0] * iw + 1.0f) * r_refdef.width * 0.5f; + out[1] = r_refdef.y + (out[1] * iw + 1.0f) * r_refdef.height * 0.5f; + out[2] = out[2] * iw; +} + // called at beginning of frame void R_Mesh_Start(void) { @@ -480,35 +528,6 @@ void GL_ConvertColorsFloatToByte(int numverts) } } -void GL_DrawRangeElements(int firstvert, int endvert, int indexcount, const int *index) -{ - int arraylocked = false; - c_meshs++; - c_meshelements += indexcount; - if (indexcount == 0 || endvert == firstvert) - { - Con_Printf("GL_DrawRangeElements(%d, %d, %d, %08p);\n", firstvert, endvert, indexcount, index); - return; - } - if (gl_supportslockarrays && gl_lockarrays.integer) - { - qglLockArraysEXT(firstvert, endvert - firstvert); - CHECKGLERROR - arraylocked = true; - } - if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL) - qglDrawRangeElements(GL_TRIANGLES, firstvert, endvert, indexcount, GL_UNSIGNED_INT, (const GLuint *) index); - else - qglDrawElements(GL_TRIANGLES, indexcount, GL_UNSIGNED_INT, (const GLuint *) index); - CHECKGLERROR - if (arraylocked) - { - qglUnlockArraysEXT(); - CHECKGLERROR - arraylocked = false; - } -} - // enlarges geometry buffers if they are too small void _R_Mesh_ResizeCheck(int numverts) { @@ -523,15 +542,36 @@ void _R_Mesh_ResizeCheck(int numverts) // renders the mesh void R_Mesh_Draw(int numverts, int numtriangles, const int *elements) { - BACKENDACTIVECHECK - - CHECKGLERROR - + int numelements; + if (numtriangles == 0 || numverts == 0) + { + Con_Printf("R_Mesh_Draw(%d, %d, %08p);\n", numverts, numtriangles, elements); + return; + } + numelements = numtriangles * 3; + c_meshs++; + c_meshelements += numelements; if (gl_state.colorarray && !gl_mesh_floatcolors.integer) GL_ConvertColorsFloatToByte(numverts); if (!r_render.integer) return; - GL_DrawRangeElements(0, numverts, numtriangles * 3, elements); + if (gl_supportslockarrays && gl_lockarrays.integer) + { + qglLockArraysEXT(0, numverts); + CHECKGLERROR + if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL) + qglDrawRangeElements(GL_TRIANGLES, 0, numverts, numelements, GL_UNSIGNED_INT, (const GLuint *) elements); + else + qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) elements); + CHECKGLERROR + qglUnlockArraysEXT(); + CHECKGLERROR + } + else + { + qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) elements); + CHECKGLERROR + } } // restores backend state, used when done with 3D rendering @@ -561,6 +601,7 @@ void R_Mesh_Finish(void) 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 @@ -636,7 +677,7 @@ void R_Mesh_MainState(const rmeshstate_t *m) void R_Mesh_TextureState(const rmeshstate_t *m) { int i, combinergb, combinealpha; - float rgbscale; + float scale; gltextureunit_t *unit; BACKENDACTIVECHECK @@ -763,14 +804,23 @@ void R_Mesh_TextureState(const rmeshstate_t *m) qglBindTexture(GL_TEXTURE_CUBE_MAP_ARB, (unit->tcubemap = m->texcubemap[i]));CHECKGLERROR } } - rgbscale = max(m->texrgbscale[i], 1); - if (gl_state.units[i].rgbscale != rgbscale) + scale = max(m->texrgbscale[i], 1); + if (gl_state.units[i].rgbscale != scale) + { + if (gl_state.unit != i) + { + qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR + } + qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (gl_state.units[i].rgbscale = scale));CHECKGLERROR + } + scale = max(m->texalphascale[i], 1); + if (gl_state.units[i].alphascale != scale) { if (gl_state.unit != i) { qglActiveTexture(GL_TEXTURE0_ARB + (gl_state.unit = i));CHECKGLERROR } - qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, (gl_state.units[i].rgbscale = rgbscale));CHECKGLERROR + qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, (gl_state.units[i].alphascale = scale));CHECKGLERROR } } } @@ -792,7 +842,7 @@ void R_Mesh_State(const rmeshstate_t *m) qboolean SCR_ScreenShot(char *filename, int x, int y, int width, int height) { qboolean ret; - int i; + int i, j; qbyte *buffer; if (!r_render.integer) @@ -804,8 +854,13 @@ qboolean SCR_ScreenShot(char *filename, int x, int y, int width, int height) // LordHavoc: compensate for v_overbrightbits when using hardware gamma if (v_hwgamma.integer) + { for (i = 0;i < width * height * 3;i++) - buffer[i] <<= v_overbrightbits.integer; + { + j = buffer[i] << v_overbrightbits.integer; + buffer[i] = (qbyte) (bound(0, j, 255)); + } + } ret = Image_WriteTGARGB_preflipped(filename, width, height, buffer); @@ -821,8 +876,16 @@ void R_ClearScreen(void) { // clear to black qglClearColor(0,0,0,0);CHECKGLERROR + qglClearDepth(1);CHECKGLERROR + if (gl_stencil) + { + // LordHavoc: we use a stencil centered around 128 instead of 0, + // to avoid clamping interfering with strange shadow volume + // drawing orders + qglClearStencil(128);CHECKGLERROR + } // clear the screen - qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);CHECKGLERROR + qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (gl_stencil ? GL_STENCIL_BUFFER_BIT : 0));CHECKGLERROR // set dithering mode if (gl_dither.integer) {