X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_backend.c;h=a815ba6254d857d1bb59351174c9c240c062d471;hb=200ecb6b75b266bbace45e68aa9139a942c4896b;hp=c9d9ec8a89bd2c737c761b1a3738f99e6d0700d2;hpb=63a4ff4563c4bbd232c265a288e9890e4015bd93;p=xonotic%2Fdarkplaces.git diff --git a/gl_backend.c b/gl_backend.c index c9d9ec8a..a815ba62 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -80,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) @@ -272,6 +290,22 @@ void GL_SetupView_Mode_PerspectiveInfiniteFarClip (double fovx, double fovy, dou qglLoadMatrixd(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) @@ -289,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 } @@ -327,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 } @@ -429,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) { @@ -481,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) { @@ -524,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 @@ -562,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 @@ -637,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 @@ -764,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 = rgbscale));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_ALPHA_SCALE, (gl_state.units[i].alphascale = scale));CHECKGLERROR } } } @@ -822,8 +871,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) {