From 8fc0df0f441ced485cf73d197c3c98aa1aeafefd Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 23 Jan 2011 03:44:49 +0000 Subject: [PATCH] vid_gl_contex_gles cvar mostly works. Most of the shaders still have no program attached to them - pics+font have it disabled due to nvidia driver crashes, I wanna check if ATI crashes too. Merged GL+D3D builds should work now too, but still not stable if you vid_restart too much. git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3716 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/r_surf.c | 7 +- engine/client/view.c | 2 +- engine/common/mathlib.c | 8 +- engine/d3d/vid_d3d.c | 13 + engine/dotnet2005/ftequake.vcproj | 57 +-- engine/gl/gl_backend.c | 518 ++++++++++++-------- engine/gl/gl_draw.c | 18 +- engine/gl/gl_font.c | 135 ++--- engine/gl/gl_hlmdl.c | 4 +- engine/gl/gl_model.h | 1 + engine/gl/gl_rmain.c | 46 +- engine/gl/gl_rsurf.c | 2 +- engine/gl/gl_shader.c | 788 ++++++++++++++++++++++++------ engine/gl/gl_shadow.c | 28 -- engine/gl/gl_vidcommon.c | 197 +++++--- engine/gl/gl_vidnt.c | 33 +- engine/gl/gl_warp.c | 2 +- engine/gl/glquake.h | 40 +- engine/gl/gltod3d/gl_fakegl.cpp | 4 +- engine/gl/shader.h | 47 +- 20 files changed, 1328 insertions(+), 622 deletions(-) diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 63892a037..80b69fd4f 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -2552,7 +2552,12 @@ void Surf_BuildLightmaps (void) case QR_OPENGL: /*favour bgra if the gpu supports it, otherwise use rgb only if it'll be used*/ lightmap_bgra = false; - if (gl_config.glversion >= 1.2) + if (gl_config.gles) + { + lightmap_bytes = 3; + lightmap_bgra = false; + } + else if (gl_config.glversion >= 1.2) { /*the more common case*/ lightmap_bytes = 4; diff --git a/engine/client/view.c b/engine/client/view.c index bf225ee49..19533b756 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -628,7 +628,7 @@ void GLV_CalcBlend (float *hw_blend) } else { - if (/*j == CSHIFT_BONUS || j == CSHIFT_DAMAGE ||*/ gl_nohwblend.ival) + if (j == CSHIFT_BONUS || j == CSHIFT_DAMAGE || gl_nohwblend.ival) blend = sw_blend; else //powerup or contents? blend = hw_blend; diff --git a/engine/common/mathlib.c b/engine/common/mathlib.c index 67e748132..45c01beb0 100644 --- a/engine/common/mathlib.c +++ b/engine/common/mathlib.c @@ -1224,23 +1224,23 @@ void Matrix4_Projection2(float *proj, float fovx, float fovy, float neard) proj[15] = 0; } -void Matrix4_Orthographic(float *proj, float xmin, float xmax, float ymax, float ymin, +void Matrix4_Orthographic(float *proj, float xmin, float xmax, float ymin, float ymax, float znear, float zfar) { proj[0] = 2/(xmax-xmin); proj[4] = 0; proj[8] = 0; - proj[12] = (xmax+xmin)/(xmax-xmin); + proj[12] = -(xmax+xmin)/(xmax-xmin); proj[1] = 0; proj[5] = 2/(ymax-ymin); proj[9] = 0; - proj[13] = (ymax+ymin)/(ymax-ymin); + proj[13] = -(ymax+ymin)/(ymax-ymin); proj[2] = 0; proj[6] = 0; proj[10] = -2/(zfar-znear); - proj[14] = (zfar+znear)/(zfar-znear); + proj[14] = -(zfar+znear)/(zfar-znear); proj[3] = 0; proj[7] = 0; diff --git a/engine/d3d/vid_d3d.c b/engine/d3d/vid_d3d.c index 914199d83..a5e9c6908 100644 --- a/engine/d3d/vid_d3d.c +++ b/engine/d3d/vid_d3d.c @@ -1231,6 +1231,19 @@ rendererinfo_t d3drendererinfo = D3D9_SCR_UpdateScreen, + D3DBE_SelectMode, + D3DBE_DrawMesh_List, + D3DBE_DrawMesh_Single, + D3DBE_SubmitBatch, + D3DBE_GetTempBatch, + D3DBE_DrawWorld, + D3DBE_Init, + D3DBE_GenBrushModelVBO, + D3DBE_ClearVBO, + D3DBE_UploadAllLightmaps, + NULL, + D3DBE_LightCullModel, + "no more" }; diff --git a/engine/dotnet2005/ftequake.vcproj b/engine/dotnet2005/ftequake.vcproj index 046621c62..47d9d8401 100644 --- a/engine/dotnet2005/ftequake.vcproj +++ b/engine/dotnet2005/ftequake.vcproj @@ -251,7 +251,7 @@ - - - + + + - - - - - - - - - - - - - - - 0) { GL_SelectTexture(--shaderstate.lastpasstmus); @@ -617,7 +649,6 @@ static void RevertToKnownState(void) GL_SelectTexture(0); qglEnableClientState(GL_VERTEX_ARRAY); - checkerror(); GL_TexEnv(GL_REPLACE); @@ -845,8 +876,6 @@ void GLBE_Init(void) int i; double t; - checkerror(); - be_maxpasses = gl_mtexarbable; for (i = 0; i < FTABLE_SIZE; i++) @@ -882,7 +911,9 @@ void GLBE_Init(void) shaderstate.shaderbits = ~0; BE_SendPassBlendAndDepth(0); - qglEnableClientState(GL_VERTEX_ARRAY); + + if (qglEnableClientState) + qglEnableClientState(GL_VERTEX_ARRAY); currententity = &r_worldentity; } @@ -1646,7 +1677,6 @@ static void GenerateColourMods(const shaderpass_t *pass) qglDisableClientState(GL_COLOR_ARRAY); qglColor4fv(scol); qglShadeModel(GL_FLAT); - checkerror(); } else { @@ -1682,7 +1712,6 @@ static void GenerateColourMods(const shaderpass_t *pass) ambientlight[2]*0.5+shadelight[2], shaderstate.curentity->shaderRGBAf[3]); qglShadeModel(GL_FLAT); - checkerror(); return; } } @@ -1982,7 +2011,7 @@ static void BE_SubmitMeshChain(void) } qglDrawRangeElements(GL_TRIANGLES, startv, endv, endi-starti, GL_INDEX_TYPE, shaderstate.sourcevbo->indicies + starti); - } + } /* if (qglUnlockArraysEXT) qglUnlockArraysEXT(); @@ -2008,10 +2037,8 @@ static void DrawPass(const shaderpass_t *pass) if (i == lastpass) return; - checkerror(); BE_SendPassBlendAndDepth(pass[i].shaderbits); GenerateColourMods(pass+i); - checkerror(); tmu = 0; for (; i < lastpass; i++) { @@ -2023,10 +2050,8 @@ static void DrawPass(const shaderpass_t *pass) continue; GL_MBind(tmu, Shader_TextureForPass(pass+i)); - checkerror(); BE_GeneratePassTC(pass, i); - checkerror(); if (tmu >= shaderstate.lastpasstmus) { qglEnable(GL_TEXTURE_2D); @@ -2058,10 +2083,8 @@ static void DrawPass(const shaderpass_t *pass) GL_TexEnv(GL_MODULATE); break; } - checkerror(); tmu++; } - checkerror(); for (i = tmu; i < shaderstate.lastpasstmus; i++) { @@ -2073,62 +2096,72 @@ static void DrawPass(const shaderpass_t *pass) GL_ApplyVertexPointer(); BE_SubmitMeshChain(); - - checkerror(); } -static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pass) +extern avec3_t shadevector, shadelight, ambientlight; +static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned int perm) { - const shader_t *s = shader; - int i; vec3_t param3; - float m16[16]; int r, g, b; - int perm; - - perm = 0; - if (TEXVALID(shaderstate.curtexnums->bump) && s->programhandle[perm|PERMUTATION_BUMPMAP].glsl) - perm |= PERMUTATION_BUMPMAP; - if (TEXVALID(shaderstate.curtexnums->specular) && s->programhandle[perm|PERMUTATION_SPECULAR].glsl) - perm |= PERMUTATION_SPECULAR; - if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && s->programhandle[perm|PERMUTATION_OFFSET].glsl) - perm |= PERMUTATION_OFFSET; - - GLSlang_UseProgram(s->programhandle[perm].glsl); - - BE_SendPassBlendAndDepth(pass->shaderbits); - GenerateColourMods(pass); - - for ( i = 0; i < pass->numMergedPasses; i++) + switch(p->type) { - GL_MBind(i, Shader_TextureForPass(pass+i)); - if (i >= shaderstate.lastpasstmus) + case SP_ATTR_VERTEX: + /*we still do vertex transforms for billboards and shadows and such*/ + GL_SelectVBO(shaderstate.pendingvertexvbo); + qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vecV_t), shaderstate.pendingvertexpointer); + return 1u<handle[perm]; + case SP_ATTR_COLOUR: + if (shaderstate.sourcevbo->colours4f) { - qglEnable(GL_TEXTURE_2D); - qglEnableClientState(GL_TEXTURE_COORD_ARRAY); + GL_SelectVBO(shaderstate.curvertexvbo); + qglVertexAttribPointer(p->handle[perm], 4, GL_FLOAT, GL_FALSE, sizeof(vec4_t), shaderstate.sourcevbo->colours4f); + return 1u<handle[perm]; } - BE_GeneratePassTC(pass, i); - } - for (; i < shaderstate.lastpasstmus; i++) - { - GL_SelectTexture(i); - qglDisableClientState(GL_TEXTURE_COORD_ARRAY); - qglDisable(GL_TEXTURE_2D); - } - shaderstate.lastpasstmus = pass->numMergedPasses; - - for (i = 0; i < s->numprogparams; i++) - { - if (s->progparm[i].handle[perm] == -1) - continue; /*not in this permutation*/ - - switch(s->progparm[i].type) + else if (shaderstate.sourcevbo->colours4ub) { - case SP_TIME: - qglUniform1fARB(s->progparm[i].handle[perm], shaderstate.curtime); - break; - case SP_ENTMATRIX: + GL_SelectVBO(shaderstate.curvertexvbo); + qglVertexAttribPointer(p->handle[perm], 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(byte_vec4_t), shaderstate.sourcevbo->colours4ub); + return 1u<handle[perm]; + } + break; + case SP_ATTR_TEXCOORD: + GL_SelectVBO(shaderstate.sourcevbo->vbotexcoord); + qglVertexAttribPointer(p->handle[perm], 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->texcoord); + return 1u<handle[perm]; + case SP_ATTR_LMCOORD: + GL_SelectVBO(shaderstate.sourcevbo->vbolmcoord); + qglVertexAttribPointer(p->handle[perm], 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord); + return 1u<handle[perm]; + case SP_ATTR_NORMALS: + GL_SelectVBO(shaderstate.sourcevbo->vbonormals); + qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->normals); + return 1u<handle[perm]; + case SP_ATTR_SNORMALS: + GL_SelectVBO(shaderstate.sourcevbo->vbosvector); + qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->svector); + return 1u<handle[perm]; + case SP_ATTR_TNORMALS: + GL_SelectVBO(shaderstate.sourcevbo->vbotvector); + qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->tvector); + return 1u<handle[perm]; + + case SP_VIEWMATRIX: + qglUniformMatrix4fvARB(p->handle[perm], 1, false, r_refdef.m_view); + break; + case SP_PROJECTIONMATRIX: + qglUniformMatrix4fvARB(p->handle[perm], 1, false, r_refdef.m_projection); + break; + case SP_MODELVIEWMATRIX: + qglUniformMatrix4fvARB(p->handle[perm], 1, false, shaderstate.modelviewmatrix); + break; + case SP_MODELVIEWPROJECTIONMATRIX: +// qglUniformMatrix4fvARB(p->handle[perm], 1, false, r_refdef.); + break; + case SP_MODELMATRIX: + case SP_ENTMATRIX: + { + float m16[16]; Matrix4_ModelMatrixFromAxis(m16, shaderstate.curentity->axis[0], shaderstate.curentity->axis[1], shaderstate.curentity->axis[2], shaderstate.curentity->origin); /* VectorCopy(shaderstate.curentity->axis[0], m16+0); m16[3] = 0; @@ -2138,118 +2171,208 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas m16[11] = 0; VectorCopy(shaderstate.curentity->origin, m16+3); m16[15] = 1; - */ - qglUniformMatrix4fvARB(s->progparm[i].handle[perm], 1, false, m16); - break; - case SP_ENTCOLOURS: - qglUniform4fvARB(s->progparm[i].handle[perm], 1, (GLfloat*)shaderstate.curentity->shaderRGBAf); - break; - case SP_TOPCOLOURS: - R_FetchTopColour(&r, &g, &b); - param3[0] = r/255.0f; - param3[1] = g/255.0f; - param3[2] = b/255.0f; - qglUniform3fvARB(s->progparm[i].handle[perm], 1, param3); - break; - case SP_BOTTOMCOLOURS: - R_FetchBottomColour(&r, &g, &b); - param3[0] = r/255.0f; - param3[1] = g/255.0f; - param3[2] = b/255.0f; - qglUniform3fvARB(s->progparm[i].handle[perm], 1, param3); - break; - - case SP_RENDERTEXTURESCALE: - if (gl_config.arb_texture_non_power_of_two) - { - param3[0] = 1; - param3[1] = 1; - } - else - { - r = 1; - g = 1; - while (r < vid.pixelwidth) - r *= 2; - while (g < vid.pixelheight) - g *= 2; - param3[0] = vid.pixelwidth/(float)r; - param3[1] = vid.pixelheight/(float)g; - } - param3[2] = 1; - qglUniform3fvARB(s->progparm[i].handle[perm], 1, param3); - break; - - case SP_LIGHTRADIUS: - qglUniform1fARB(s->progparm[i].handle[perm], shaderstate.lightradius); - break; - case SP_LIGHTCOLOUR: - qglUniform3fvARB(s->progparm[i].handle[perm], 1, shaderstate.lightcolours); - break; - case SP_EYEPOS: - { -#pragma message("is this correct?") -// vec3_t t1; - vec3_t t2; - Matrix4_ModelMatrixFromAxis(m16, shaderstate.curentity->axis[0], shaderstate.curentity->axis[1], shaderstate.curentity->axis[2], shaderstate.curentity->origin); - Matrix4_Transform3(m16, r_origin, t2); -// VectorSubtract(r_origin, shaderstate.curentity->origin, t1); -// Matrix3_Multiply_Vec3(shaderstate.curentity->axis, t1, t2); - qglUniform3fvARB(s->progparm[i].handle[perm], 1, t2); - } - break; - case SP_LIGHTPOSITION: - { -#pragma message("is this correct?") - float inv[16]; -// vec3_t t1; - vec3_t t2; - qboolean Matrix4_Invert(const float *m, float *out); - - Matrix4_ModelMatrixFromAxis(m16, shaderstate.curentity->axis[0], shaderstate.curentity->axis[1], shaderstate.curentity->axis[2], shaderstate.curentity->origin); - Matrix4_Invert(m16, inv); - Matrix4_Transform3(inv, shaderstate.lightorg, t2); -// VectorSubtract(shaderstate.lightorg, shaderstate.curentity->origin, t1); -// Matrix3_Multiply_Vec3(shaderstate.curentity->axis, t1, t2); - qglUniform3fvARB(s->progparm[i].handle[perm], 1, t2); - } - break; - - case SP_CONSTI: - case SP_TEXTURE: - qglUniform1iARB(s->progparm[i].handle[perm], s->progparm[i].ival); - break; - case SP_CONSTF: - qglUniform1fARB(s->progparm[i].handle[perm], s->progparm[i].fval); - break; - case SP_CVARI: - qglUniform1iARB(s->progparm[i].handle[perm], ((cvar_t*)s->progparm[i].pval)->ival); - break; - case SP_CVARF: - qglUniform1fARB(s->progparm[i].handle[perm], ((cvar_t*)s->progparm[i].pval)->value); - break; - case SP_CVAR3F: - { - cvar_t *var = (cvar_t*)s->progparm[i].pval; - char *vs = var->string; - vs = COM_Parse(vs); - param3[0] = atof(com_token); - vs = COM_Parse(vs); - param3[1] = atof(com_token); - vs = COM_Parse(vs); - param3[2] = atof(com_token); - qglUniform3fvARB(s->progparm[i].handle[perm], 1, param3); - } - break; - - default: - Host_EndGame("Bad shader program parameter type (%i)", s->progparm[i].type); - break; +*/ + qglUniformMatrix4fvARB(p->handle[perm], 1, false, m16); } + break; + + + case SP_ENTCOLOURS: + qglUniform4fvARB(p->handle[perm], 1, (GLfloat*)shaderstate.curentity->shaderRGBAf); + break; + case SP_TOPCOLOURS: + R_FetchTopColour(&r, &g, &b); + param3[0] = r/255.0f; + param3[1] = g/255.0f; + param3[2] = b/255.0f; + qglUniform3fvARB(p->handle[perm], 1, param3); + break; + case SP_BOTTOMCOLOURS: + R_FetchBottomColour(&r, &g, &b); + param3[0] = r/255.0f; + param3[1] = g/255.0f; + param3[2] = b/255.0f; + qglUniform3fvARB(p->handle[perm], 1, param3); + break; + + case SP_RENDERTEXTURESCALE: + if (gl_config.arb_texture_non_power_of_two) + { + param3[0] = 1; + param3[1] = 1; + } + else + { + r = 1; + g = 1; + while (r < vid.pixelwidth) + r *= 2; + while (g < vid.pixelheight) + g *= 2; + param3[0] = vid.pixelwidth/(float)r; + param3[1] = vid.pixelheight/(float)g; + } + param3[2] = 1; + qglUniform3fvARB(p->handle[perm], 1, param3); + break; + + case SP_LIGHTRADIUS: + qglUniform1fARB(p->handle[perm], shaderstate.lightradius); + break; + case SP_LIGHTCOLOUR: + qglUniform3fvARB(p->handle[perm], 1, shaderstate.lightcolours); + break; + case SP_EYEPOS: + { + float m16[16]; +#pragma message("is this correct?") +// vec3_t t1; + vec3_t t2; + Matrix4_ModelMatrixFromAxis(m16, shaderstate.curentity->axis[0], shaderstate.curentity->axis[1], shaderstate.curentity->axis[2], shaderstate.curentity->origin); + Matrix4_Transform3(m16, r_origin, t2); +// VectorSubtract(r_origin, shaderstate.curentity->origin, t1); +// Matrix3_Multiply_Vec3(shaderstate.curentity->axis, t1, t2); + qglUniform3fvARB(p->handle[perm], 1, t2); + } + break; + case SP_LIGHTPOSITION: + { +#pragma message("is this correct?") + float inv[16]; + float m16[16]; +// vec3_t t1; + vec3_t t2; + qboolean Matrix4_Invert(const float *m, float *out); + + Matrix4_ModelMatrixFromAxis(m16, shaderstate.curentity->axis[0], shaderstate.curentity->axis[1], shaderstate.curentity->axis[2], shaderstate.curentity->origin); + Matrix4_Invert(m16, inv); + Matrix4_Transform3(inv, shaderstate.lightorg, t2); +// VectorSubtract(shaderstate.lightorg, shaderstate.curentity->origin, t1); +// Matrix3_Multiply_Vec3(shaderstate.curentity->axis, t1, t2); + qglUniform3fvARB(p->handle[perm], 1, t2); + } + break; + case SP_TIME: + qglUniform1fARB(p->handle[perm], shaderstate.curtime); + break; + case SP_CONSTI: + case SP_TEXTURE: + qglUniform1iARB(p->handle[perm], p->ival); + break; + case SP_CONSTF: + qglUniform1fARB(p->handle[perm], p->fval); + break; + case SP_CVARI: + qglUniform1iARB(p->handle[perm], ((cvar_t*)p->pval)->ival); + break; + case SP_CVARF: + qglUniform1fARB(p->handle[perm], ((cvar_t*)p->pval)->value); + break; + case SP_CVAR3F: + { + cvar_t *var = (cvar_t*)p->pval; + char *vs = var->string; + vs = COM_Parse(vs); + param3[0] = atof(com_token); + vs = COM_Parse(vs); + param3[1] = atof(com_token); + vs = COM_Parse(vs); + param3[2] = atof(com_token); + qglUniform3fvARB(p->handle[perm], 1, param3); + } + break; + case SP_E_L_DIR: + qglUniform3fvARB(p->handle[perm], 1, shadevector); + break; + case SP_E_L_MUL: + qglUniform3fvARB(p->handle[perm], 1, shadelight); + break; + case SP_E_L_AMBIENT: + VectorMA(ambientlight, 1, shadelight, param3); + qglUniform3fvARB(p->handle[perm], 1, param3); + break; + + default: + Host_EndGame("Bad shader program parameter type (%i)", p->type); + break; } - GL_ApplyVertexPointer(); + return 0; +} + +static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pass) +{ + const shader_t *s = shader; + int i; + unsigned int attr = 0; + + int perm; + + perm = 0; +/* if (TEXVALID(shaderstate.curtexnums->bump) && s->programhandle[perm|PERMUTATION_BUMPMAP].glsl) + perm |= PERMUTATION_BUMPMAP; + if (TEXVALID(shaderstate.curtexnums->specular) && s->programhandle[perm|PERMUTATION_SPECULAR].glsl) + perm |= PERMUTATION_SPECULAR; + if (TEXVALID(shaderstate.curtexnums->fullbright) && s->programhandle[perm|PERMUTATION_FULLBRIGHT].glsl) + perm |= PERMUTATION_FULLBRIGHT; + if (TEXVALID(shaderstate.curtexnums->loweroverlay) && s->programhandle[perm|PERMUTATION_LOWER].glsl) + perm |= PERMUTATION_LOWER; + if (TEXVALID(shaderstate.curtexnums->upperoverlay) && s->programhandle[perm|PERMUTATION_UPPER].glsl) + perm |= PERMUTATION_UPPER; + if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && s->programhandle[perm|PERMUTATION_OFFSET].glsl) + perm |= PERMUTATION_OFFSET;*/ + GL_SelectProgram(s->programhandle[perm].glsl); + + BE_SendPassBlendAndDepth(pass->shaderbits); + + for (i = 0; i < s->numprogparams; i++) + { + if (s->progparm[i].handle[perm] == -1) + continue; /*not in this permutation*/ + attr |= BE_Program_Set_Attribute(&s->progparm[i], perm); + } + if (s->flags & SHADER_NOBUILTINATTR) + { + qglDisableClientState(GL_COLOR_ARRAY); + qglDisableClientState(GL_VERTEX_ARRAY); + for (i = 0; i < pass->numMergedPasses; i++) + { + GL_MBind(i, Shader_TextureForPass(pass+i)); + } + for (i = 0; i < shaderstate.lastpasstmus; i++) + { + GL_SelectTexture(i); + qglDisableClientState(GL_TEXTURE_COORD_ARRAY); + qglDisable(GL_TEXTURE_2D); + } + shaderstate.lastpasstmus = 0; + } + else + { + GenerateColourMods(pass); + for (i = 0; i < pass->numMergedPasses; i++) + { + GL_MBind(i, Shader_TextureForPass(pass+i)); + if (i >= shaderstate.lastpasstmus) + { + qglEnable(GL_TEXTURE_2D); + qglEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + BE_GeneratePassTC(pass, i); + } + for (; i < shaderstate.lastpasstmus; i++) + { + GL_SelectTexture(i); + qglDisableClientState(GL_TEXTURE_COORD_ARRAY); + qglDisable(GL_TEXTURE_2D); + } + shaderstate.lastpasstmus = pass->numMergedPasses; + GL_ApplyVertexPointer(); + } + + BE_EnableShaderAttributes(attr); BE_SubmitMeshChain(); - GLSlang_UseProgram(0); + + qglEnableClientState(GL_VERTEX_ARRAY); } #ifdef RTLIGHTS @@ -2372,12 +2495,14 @@ void GLBE_SelectMode(backendmode_t mode, unsigned int flags) void GLBE_SelectEntity(entity_t *ent) { - if (shaderstate.curentity && shaderstate.curentity->flags & Q2RF_DEPTHHACK) + if (shaderstate.curentity && shaderstate.curentity->flags & Q2RF_DEPTHHACK && qglDepthRange) qglDepthRange (gldepthmin, gldepthmax); shaderstate.curentity = ent; currententity = ent; - R_RotateForEntity(shaderstate.curentity, shaderstate.curentity->model); - if (shaderstate.curentity->flags & Q2RF_DEPTHHACK) + R_RotateForEntity(shaderstate.modelviewmatrix, shaderstate.curentity, shaderstate.curentity->model); + if (qglLoadMatrixf) + qglLoadMatrixf(shaderstate.modelviewmatrix); + if (shaderstate.curentity->flags & Q2RF_DEPTHHACK && qglDepthRange) qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin)); } @@ -2497,7 +2622,6 @@ static void DrawMeshes(void) #endif { shaderstate.curcull = (shaderstate.curshader->flags & (SHADER_CULL_FRONT|SHADER_CULL_BACK)); - if (shaderstate.curcull & SHADER_CULL_FRONT) { qglEnable(GL_CULL_FACE); @@ -2515,7 +2639,6 @@ static void DrawMeshes(void) } BE_PolyOffset(shaderstate.flags & BEF_PUSHDEPTH); - switch(shaderstate.mode) { case BEM_STENCIL: @@ -2533,6 +2656,7 @@ static void DrawMeshes(void) break; #endif case BEM_DEPTHONLY: + GL_DeSelectProgram(); #pragma message("fixme: support alpha test") GL_ApplyVertexPointer(); BE_SubmitMeshChain(); @@ -2541,6 +2665,7 @@ static void DrawMeshes(void) case BEM_DEPTHDARK: if (shaderstate.curshader->flags & SHADER_HASLIGHTMAP) { + GL_DeSelectProgram(); qglColor3f(0,0,0); qglDisableClientState(GL_COLOR_ARRAY); while(shaderstate.lastpasstmus>0) @@ -2560,9 +2685,14 @@ static void DrawMeshes(void) case BEM_STANDARD: default: if (shaderstate.curshader->programhandle[0].glsl) + { BE_RenderMeshProgram(shaderstate.curshader, shaderstate.curshader->passes); + } + else if (gl_config.nofixedfunc) + break; else { + GL_DeSelectProgram(); while (passno < shaderstate.curshader->numpasses) { p = &shaderstate.curshader->passes[passno]; @@ -2604,6 +2734,7 @@ void GLBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_ shaderstate.dummyvbo.svector = m->snormals_array; shaderstate.dummyvbo.tvector = m->tnormals_array; shaderstate.dummyvbo.colours4f = m->colors4f_array; + shaderstate.dummyvbo.colours4ub = m->colors4b_array; shaderstate.meshcount = 1; shaderstate.meshes = &m; @@ -2787,7 +2918,6 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist) if (batch->shader->flags & SHADER_NODLIGHT) if (shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_SMAPLIGHT) continue; - if (batch->shader->flags & SHADER_SKY) { if (shaderstate.mode == BEM_STANDARD) @@ -2815,8 +2945,6 @@ void GLBE_SubmitMeshes (qboolean drawworld, batch_t **blist) } BE_SubmitMeshesSortList(blist[i]); } - - checkerror(); } static void BE_UpdateLightmaps(void) @@ -2832,6 +2960,7 @@ static void BE_UpdateLightmaps(void) lightmap[lm]->modified = false; theRect = &lightmap[lm]->rectchange; GL_Bind(lightmap_textures[lm]); + checkglerror(); switch (lightmap_bytes) { case 4: @@ -2854,7 +2983,7 @@ static void BE_UpdateLightmaps(void) theRect->t = LMBLOCK_HEIGHT; theRect->h = 0; theRect->w = 0; - checkerror(); + checkglerror(); if (lightmap[lm]->deluxmodified) { @@ -2868,7 +2997,7 @@ static void BE_UpdateLightmaps(void) theRect->t = LMBLOCK_HEIGHT; theRect->h = 0; theRect->w = 0; - checkerror(); + checkglerror(); } } } @@ -2961,7 +3090,6 @@ void GLBE_DrawWorld (qbyte *vis) shaderstate.wbatch = 0; } BE_GenModelBatches(batches); - shaderstate.curentity = NULL; shaderstate.updatetime = cl.servertime; @@ -2973,7 +3101,6 @@ void GLBE_DrawWorld (qbyte *vis) #endif BE_UpdateLightmaps(); - //make sure the world draws correctly r_worldentity.shaderRGBAf[0] = 1; r_worldentity.shaderRGBAf[1] = 1; @@ -2995,8 +3122,6 @@ void GLBE_DrawWorld (qbyte *vis) else BE_SelectMode(BEM_STANDARD, 0); - checkerror(); - RSpeedRemark(); GLBE_SubmitMeshes(true, batches); RSpeedEnd(RSPEED_WORLD); @@ -3007,7 +3132,6 @@ void GLBE_DrawWorld (qbyte *vis) Sh_DrawLights(vis); RSpeedEnd(RSPEED_STENCILSHADOWS); #endif - checkerror(); BE_DrawPolys(false); diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 869cf14ba..23631804d 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -788,17 +788,21 @@ Setup as if the screen was 320*200 void GL_Set2D (void) { GL_SetShaderState2D(true); + Matrix4_Orthographic(r_refdef.m_projection, 0, vid.width, vid.height, 0, -99999, 99999); + Matrix4_Identity(r_refdef.m_view); + r_refdef.time = realtime; + /*flush that gl state*/ qglViewport (0, 0, vid.pixelwidth, vid.pixelheight); - qglMatrixMode(GL_PROJECTION); - qglLoadIdentity (); - qglOrtho (0, vid.width, vid.height, 0, -99999, 99999); + if (qglLoadMatrixf) + { + qglMatrixMode(GL_PROJECTION); + qglLoadMatrixf(r_refdef.m_projection); - qglMatrixMode(GL_MODELVIEW); - qglLoadIdentity (); - - r_refdef.time = realtime; + qglMatrixMode(GL_MODELVIEW); + qglLoadMatrixf(r_refdef.m_view); + } } diff --git a/engine/gl/gl_font.c b/engine/gl/gl_font.c index 1c22c4baa..e4bd7ef69 100644 --- a/engine/gl/gl_font.c +++ b/engine/gl/gl_font.c @@ -210,10 +210,14 @@ static fontplanes_t fontplanes; static index_t font_indicies[FONT_CHAR_BUFFER*6]; static vecV_t font_coord[FONT_CHAR_BUFFER*4]; static vec2_t font_texcoord[FONT_CHAR_BUFFER*4]; -static vbo_t font_buffer; -static mesh_t font_mesh; +static byte_vec4_t font_forecoloura[FONT_CHAR_BUFFER*4]; +static byte_vec4_t font_backcoloura[FONT_CHAR_BUFFER*4]; +static mesh_t font_foremesh; +static mesh_t font_backmesh; static texid_t font_texture; static int font_colourmask; +static byte_vec4_t font_forecolour; +static byte_vec4_t font_backcolour; static struct font_s *curfont; @@ -223,13 +227,15 @@ void Font_Init(void) int i; fontplanes.defaultfont = r_nulltex; - font_buffer.indicies = font_indicies; - font_buffer.coord = font_coord; - font_buffer.texcoord = font_texcoord; + font_foremesh.indexes = font_indicies; + font_foremesh.xyz_array = font_coord; + font_foremesh.st_array = font_texcoord; + font_foremesh.colors4b_array = font_forecoloura; - font_mesh.indexes = font_buffer.indicies; - font_mesh.xyz_array = font_buffer.coord; - font_mesh.st_array = font_buffer.texcoord; + font_backmesh.indexes = font_indicies; + font_backmesh.xyz_array = font_coord; + font_backmesh.st_array = font_texcoord; + font_backmesh.colors4b_array = font_backcoloura; for (i = 0; i < FONT_CHAR_BUFFER; i++) { @@ -248,11 +254,12 @@ void Font_Init(void) fontplanes.shader = R_RegisterShader("ftefont", "{\n" +// "program default2d\n" "nomipmaps\n" "{\n" "map $diffuse\n" - "rgbgen const\n" - "alphagen const\n" + "rgbgen vertex\n" + "alphagen vertex\n" "blendfunc blend\n" "}\n" "}\n" @@ -263,8 +270,8 @@ void Font_Init(void) "nomipmaps\n" "{\n" "map $whiteimage\n" - "rgbgen const\n" - "alphagen const\n" + "rgbgen vertex\n" + "alphagen vertex\n" "blendfunc blend\n" "}\n" "}\n" @@ -276,48 +283,43 @@ void Font_Init(void) //flush the font buffer, by drawing it to the screen static void Font_Flush(void) { - if (!font_mesh.numindexes) + if (!font_foremesh.numindexes) return; - if (fontplanes.planechanged) { R_Upload(fontplanes.texnum[fontplanes.activeplane], NULL, TF_RGBA32, (void*)fontplanes.plane, NULL, PLANEWIDTH, PLANEHEIGHT, IF_NOPICMIP|IF_NOMIPMAP|IF_NOGAMMA); fontplanes.planechanged = false; } - font_mesh.istrifan = (font_mesh.numvertexes == 4); + font_foremesh.istrifan = (font_foremesh.numvertexes == 4); if (font_colourmask & CON_NONCLEARBG) { - fontplanes.backshader->defaulttextures.base = r_nulltex; - BE_DrawMesh_Single(fontplanes.backshader, &font_mesh, NULL, &fontplanes.backshader->defaulttextures); + font_backmesh.numindexes = font_foremesh.numindexes; + font_backmesh.numvertexes = font_foremesh.numvertexes; + font_backmesh.istrifan = font_foremesh.istrifan; - fontplanes.shader->defaulttextures.base = font_texture; - BE_DrawMesh_Single(fontplanes.shader, &font_mesh, NULL, &fontplanes.shader->defaulttextures); + BE_DrawMesh_Single(fontplanes.backshader, &font_backmesh, NULL, &fontplanes.backshader->defaulttextures); } - else - { - fontplanes.shader->defaulttextures.base = font_texture; - BE_DrawMesh_Single(fontplanes.shader, &font_mesh, NULL, &fontplanes.shader->defaulttextures); - } - - font_mesh.numindexes = 0; - font_mesh.numvertexes = 0; + fontplanes.shader->defaulttextures.base = font_texture; + BE_DrawMesh_Single(fontplanes.shader, &font_foremesh, NULL, &fontplanes.shader->defaulttextures); + font_foremesh.numindexes = 0; + font_foremesh.numvertexes = 0; } static int Font_BeginChar(texid_t tex) { int fvert; - if (font_mesh.numindexes == FONT_CHAR_BUFFER*6 || memcmp(&font_texture,&tex, sizeof(texid_t))) + if (font_foremesh.numindexes == FONT_CHAR_BUFFER*6 || memcmp(&font_texture,&tex, sizeof(texid_t))) { Font_Flush(); font_texture = tex; } - fvert = font_mesh.numvertexes; + fvert = font_foremesh.numvertexes; - font_mesh.numindexes += 6; - font_mesh.numvertexes += 4; + font_foremesh.numindexes += 6; + font_foremesh.numvertexes += 4; return fvert; } @@ -1077,17 +1079,16 @@ void Font_LineDraw(int x, int y, conchar_t *start, conchar_t *end) correct usage of this function thus requires calling this with 1111 before Font_EndString*/ void Font_ForceColour(float r, float g, float b, float a) { - Font_Flush(); + if (font_colourmask & CON_NONCLEARBG) + Font_Flush(); font_colourmask = CON_WHITEMASK; - /*force the colour to the requested one*/ - fontplanes.shader->passes[0].rgbgen_func.args[0] = r; - fontplanes.shader->passes[0].rgbgen_func.args[1] = g; - fontplanes.shader->passes[0].rgbgen_func.args[2] = b; - fontplanes.shader->passes[0].alphagen_func.args[0] = a; + font_forecolour[0] = r*255; + font_forecolour[1] = g*255; + font_forecolour[2] = b*255; + font_forecolour[3] = a*255; - /*no background*/ - fontplanes.backshader->passes[0].alphagen_func.args[0] = 0; + font_backcolour[3] = 0; /*Any drawchars that are now drawn will get the forced colour*/ } @@ -1134,20 +1135,21 @@ int Font_DrawChar(int px, int py, unsigned int charcode) col = charcode & (CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA); if (col != font_colourmask) { - Font_Flush(); + if ((col ^ font_colourmask) & CON_NONCLEARBG) + Font_Flush(); font_colourmask = col; col = (charcode&CON_FGMASK)>>CON_FGSHIFT; - fontplanes.shader->passes[0].rgbgen_func.args[0] = consolecolours[col].fr; - fontplanes.shader->passes[0].rgbgen_func.args[1] = consolecolours[col].fg; - fontplanes.shader->passes[0].rgbgen_func.args[2] = consolecolours[col].fb; - fontplanes.shader->passes[0].alphagen_func.args[0] = (charcode & CON_HALFALPHA)?0.5:1; + font_forecolour[0] = consolecolours[col].fr*255; + font_forecolour[1] = consolecolours[col].fg*255; + font_forecolour[2] = consolecolours[col].fb*255; + font_forecolour[3] = (charcode & CON_HALFALPHA)?127:255; col = (charcode&CON_BGMASK)>>CON_BGSHIFT; - fontplanes.backshader->passes[0].rgbgen_func.args[0] = consolecolours[col].fr; - fontplanes.backshader->passes[0].rgbgen_func.args[1] = consolecolours[col].fg; - fontplanes.backshader->passes[0].rgbgen_func.args[2] = consolecolours[col].fb; - fontplanes.backshader->passes[0].alphagen_func.args[0] = (charcode & CON_NONCLEARBG)?0.5:0; + font_backcolour[0] = consolecolours[col].fr*255; + font_backcolour[1] = consolecolours[col].fg*255; + font_backcolour[2] = consolecolours[col].fb*255; + font_backcolour[3] = (charcode & CON_NONCLEARBG)?127:0; } s0 = (float)c->bmx/PLANEWIDTH; @@ -1194,6 +1196,15 @@ int Font_DrawChar(int px, int py, unsigned int charcode) font_coord[v+3][0] = sx; font_coord[v+3][1] = sy+sh; + *(int*)font_forecoloura[v+0] = *(int*)font_forecolour; + *(int*)font_forecoloura[v+1] = *(int*)font_forecolour; + *(int*)font_forecoloura[v+2] = *(int*)font_forecolour; + *(int*)font_forecoloura[v+3] = *(int*)font_forecolour; + *(int*)font_backcoloura[v+0] = *(int*)font_backcolour; + *(int*)font_backcoloura[v+1] = *(int*)font_backcolour; + *(int*)font_backcoloura[v+2] = *(int*)font_backcolour; + *(int*)font_backcoloura[v+3] = *(int*)font_backcolour; + return nextx; } @@ -1236,20 +1247,21 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch col = charcode & (CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA); if (col != font_colourmask) { - Font_Flush(); + if ((col ^ font_colourmask) & CON_NONCLEARBG) + Font_Flush(); font_colourmask = col; col = (charcode&CON_FGMASK)>>CON_FGSHIFT; - fontplanes.shader->passes[0].rgbgen_func.args[0] = consolecolours[col].fr; - fontplanes.shader->passes[0].rgbgen_func.args[1] = consolecolours[col].fg; - fontplanes.shader->passes[0].rgbgen_func.args[2] = consolecolours[col].fb; - fontplanes.shader->passes[0].alphagen_func.args[0] = (charcode & CON_HALFALPHA)?0.5:1; + font_forecolour[0] = consolecolours[col].fr*255; + font_forecolour[1] = consolecolours[col].fg*255; + font_forecolour[2] = consolecolours[col].fb*255; + font_forecolour[3] = (charcode & CON_HALFALPHA)?127:255; col = (charcode&CON_BGMASK)>>CON_BGSHIFT; - fontplanes.backshader->passes[0].rgbgen_func.args[0] = consolecolours[col].fr; - fontplanes.backshader->passes[0].rgbgen_func.args[1] = consolecolours[col].fg; - fontplanes.backshader->passes[0].rgbgen_func.args[2] = consolecolours[col].fb; - fontplanes.backshader->passes[0].alphagen_func.args[0] = (charcode & CON_NONCLEARBG)?0.5:0; + font_backcolour[0] = consolecolours[col].fr*255; + font_backcolour[1] = consolecolours[col].fg*255; + font_backcolour[2] = consolecolours[col].fb*255; + font_backcolour[3] = (charcode & CON_NONCLEARBG)?127:0; } s0 = (float)c->bmx/PLANEWIDTH; @@ -1296,6 +1308,15 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch font_coord[v+3][0] = sx; font_coord[v+3][1] = sy+sh; + *(int*)font_forecoloura[v+0] = *(int*)font_forecolour; + *(int*)font_forecoloura[v+1] = *(int*)font_forecolour; + *(int*)font_forecoloura[v+2] = *(int*)font_forecolour; + *(int*)font_forecoloura[v+3] = *(int*)font_forecolour; + *(int*)font_backcoloura[v+0] = *(int*)font_backcolour; + *(int*)font_backcoloura[v+1] = *(int*)font_backcolour; + *(int*)font_backcoloura[v+2] = *(int*)font_backcolour; + *(int*)font_backcoloura[v+3] = *(int*)font_backcolour; + return nextx; } diff --git a/engine/gl/gl_hlmdl.c b/engine/gl/gl_hlmdl.c index ba0dd5626..9379206fb 100644 --- a/engine/gl/gl_hlmdl.c +++ b/engine/gl/gl_hlmdl.c @@ -570,6 +570,7 @@ void R_DrawHLModel(entity_t *curent) int b, m, v; short *skins; int bgroup, cbone, lastbone; + float mat[16]; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //general model @@ -613,7 +614,8 @@ void R_DrawHLModel(entity_t *curent) qglColor4f(difuse[0]/255+ambient[0]/255, difuse[1]/255+ambient[1]/255, difuse[2]/255+ambient[2]/255, curent->shaderRGBAf[3]); } - R_RotateForEntity (curent, curent->model); + R_RotateForEntity (mat, curent, curent->model); + qglLoadMatrixf(mat); cbone = 0; for (bgroup = 0; bgroup < FS_COUNT; bgroup++) diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index 59ea985bc..db3dc6817 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -233,6 +233,7 @@ typedef struct vbo_s int vbocolours; vec4_t *colours4f; + byte_vec4_t *colours4ub; } vbo_t; void GL_SelectVBO(int vbo); void GL_SelectEBO(int vbo); diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 21ce20174..450eb1333 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -27,12 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "shader.h" #include "gl_draw.h" -#ifdef _DEBUG -#define checkerror() if (qglGetError()) Con_Printf("Error detected at line %s:%i\n", __FILE__, __LINE__) -#else -#define checkerror() -#endif - void R_RenderBrushPoly (msurface_t *fa); #define PROJECTION_DISTANCE 200 @@ -389,7 +383,7 @@ void GL_SetupSceneProcessingTextures (void) GL_Bind(scenepp_texture_warp); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - qglTexImage2D(GL_TEXTURE_2D, 0, 3, PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, pp_warp_tex); + qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, pp_warp_tex); // TODO: init edge texture - this is ampscale * 2, with ampscale calculated // init warp texture - this specifies offset in @@ -436,9 +430,8 @@ void GL_SetupSceneProcessingTextures (void) qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, pp_edge_tex); } -void R_RotateForEntity (const entity_t *e, const model_t *mod) +void R_RotateForEntity (float *modelview, const entity_t *e, const model_t *mod) { - float mv[16]; float m[16]; m[0] = e->axis[0][0]; @@ -520,13 +513,11 @@ void R_RotateForEntity (const entity_t *e, const model_t *mod) /*FIXME: no bob*/ float simpleview[16]; Matrix4_ModelViewMatrix(simpleview, vec3_origin, vec3_origin); - Matrix4_Multiply(simpleview, m, mv); - qglLoadMatrixf(mv); + Matrix4_Multiply(simpleview, m, modelview); } else { - Matrix4_Multiply(r_refdef.m_view, m, mv); - qglLoadMatrixf(mv); + Matrix4_Multiply(r_refdef.m_view, m, modelview); } } @@ -1089,19 +1080,25 @@ void R_SetupGL (void) Matrix4_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_refdef.vieworg); } - qglMatrixMode(GL_PROJECTION); - qglLoadMatrixf(r_refdef.m_projection); - - qglMatrixMode(GL_MODELVIEW); - qglLoadMatrixf(r_refdef.m_view); - - if (gl_dither.ival) + if (qglLoadMatrixf) { - qglEnable(GL_DITHER); + qglMatrixMode(GL_PROJECTION); + qglLoadMatrixf(r_refdef.m_projection); + + qglMatrixMode(GL_MODELVIEW); + qglLoadMatrixf(r_refdef.m_view); } - else + + if (!gl_config.gles) { - qglDisable(GL_DITHER); + if (gl_dither.ival) + { + qglEnable(GL_DITHER); + } + else + { + qglDisable(GL_DITHER); + } } } @@ -1418,7 +1415,8 @@ void R_Clear (void) gldepthmax = 1; gldepthfunc=GL_LEQUAL; } - qglDepthRange (gldepthmin, gldepthmax); + if (qglDepthRange) + qglDepthRange (gldepthmin, gldepthmax); } #if 0 diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index 445723567..65b123294 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -306,7 +306,7 @@ void GLBE_UploadAllLightmaps(void) lightmap[i]->lightmaps); break; case 3: - qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, + qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, LMBLOCK_WIDTH, LMBLOCK_WIDTH, 0, (lightmap_bgra?GL_BGR_EXT:GL_RGB), GL_UNSIGNED_BYTE, lightmap[i]->lightmaps); break; diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 5410aba63..b53a20e3f 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -708,23 +708,48 @@ static void Shader_EntityMergable ( shader_t *shader, shaderpass_t *pass, char * shader->flags |= SHADER_ENTITY_MERGABLE; } -static void Shader_LoadProgram(shader_t *shader, char *vert, char *frag, int qrtype) +/*program text is already loaded, this function parses the 'header' of it to see which permutations it provides, and how many times we need to recompile it*/ +static void Shader_LoadPermutations(union programhandle_u *handle, char *script, int qrtype) { - static char *permutationdefines[PERMUTATIONS] = { - "", + char *permutationdefines[PERMUTATIONS]; + static char *permutationname[] = + { "#define BUMP\n", "#define SPECULAR\n", - "#define SPECULAR\n#define BUMP\n", - "#define USEOFFSETMAPPING\n", - "#define USEOFFSETMAPPING\n#define BUMP\n", - "#define USEOFFSETMAPPING\n#define SPECULAR\n", - "#define USEOFFSETMAPPING\n#define SPECULAR\n#define BUMP\n" + "#define FULLBRIGHT\n", + "#define LOWER\n", + "#define UPPER\n", + "#define OFFSETMAPPING\n", + NULL }; - int p; + unsigned int nopermutation = ~0u; + int p, n, pn; + char *end; - if (!frag) - frag = vert; + for(;;) + { + while (*script == ' ' || *script == '\r' || *script == '\n' || *script == '\t') + script++; + if (!strncmp(script, "!!permu", 7)) + { + script += 7; + while (*script == ' ' || *script == '\r' || *script == '\n' || *script == '\t') + script++; + end = script; + while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_') + end++; + for (p = 0; permutationname[p]; p++) + { + if (!strncmp(permutationname[p]+8, script, end - script) && permutationname[p][8+end-script] == '\n') + nopermutation &= ~(1u<programhandle[p].glsl = GLSlang_CreateProgram(permutationdefines[p], (char *)vert, (char *)frag); + { + if (nopermutation & p) + { + continue; + } + pn = 0; + for (n = 0; permutationname[n]; n++) + { + if (p & (1u<next; + free(g); + } +} +static void Shader_LoadGeneric(union programhandle_u *shader, char *name, int qrtype) +{ + unsigned int i; + void *file; + sgeneric_t *g; + for (g = sgenerics; g; g = g->next) + { + if (!strcmp(name, g->name)) + { + memcpy(shader, g->handle, sizeof(g->handle)); + return; + } + } + + if (strlen(name) >= sizeof(g->name)) + return; /*name overflow*/ + g = malloc(sizeof(*g)); + strcpy(g->name, name); + g->next = sgenerics; + sgenerics = g; + + FS_LoadFile(name, &file); + if (file) + { + Shader_LoadPermutations(g->handle, file, qrtype); + FS_FreeFile(file); + } + else + { + memset(g->handle, 0, sizeof(g->handle)); + for (i = 0; *sbuiltins[i].name; i++) + { + if (sbuiltins[i].qrtype == qrenderer && !strcmp(sbuiltins[i].name, name)) + { +#ifdef GLQUAKE + if (gl_config.gles) + { + if (sbuiltins[i].apiver != 100) + continue; + } + else + { + if (sbuiltins[i].apiver == 100) + continue; + } +#endif + Shader_LoadPermutations(g->handle, sbuiltins[i].body, sbuiltins[i].qrtype); + break; + } + } + } + + memcpy(shader, g->handle, sizeof(g->handle)); +} + +static void Shader_ProgAutoFields(shader_t *shader) +{ + unsigned int i, p; + qboolean found; + int uniformloc; + static struct + { + char *name; + enum shaderprogparmtype_e ptype; + } u[] = + { + /*vertex attributes*/ + {"v_position", SP_ATTR_VERTEX}, + {"v_colour", SP_ATTR_COLOUR}, + {"v_texcoord", SP_ATTR_TEXCOORD}, + {"v_lmcoord", SP_ATTR_LMCOORD}, + {"v_normal", SP_ATTR_NORMALS}, + {"v_svector", SP_ATTR_SNORMALS}, + {"v_tvector", SP_ATTR_TNORMALS}, + + /*matricies*/ + {"m_model", SP_MODELMATRIX}, + {"m_view", SP_VIEWMATRIX}, + {"m_modelview", SP_MODELVIEWMATRIX}, + {"m_projection", SP_PROJECTIONMATRIX}, + {"m_modelviewprojection", SP_MODELVIEWPROJECTIONMATRIX}, + + /*ent properties*/ + {"e_time", SP_TIME}, + {"e_colour", SP_ENTCOLOURS}, + {"e_topcolour", SP_TOPCOLOURS}, + {"e_bottomcolour", SP_BOTTOMCOLOURS}, + {"e_light_dir", SP_E_L_DIR}, + {"e_light_mul", SP_E_L_MUL}, + {"e_light_ambient", SP_E_L_AMBIENT}, + {NULL} + }; + shader->numprogparams = 0; +#ifdef GLQUAKE + if (qrenderer == QR_OPENGL) + { + if (gl_config.nofixedfunc) + shader->flags |= SHADER_NOBUILTINATTR; + + for (p = 0; p < PERMUTATIONS; p++) + { + if (!shader->programhandle[p].glsl) + continue; + GLSlang_UseProgram(shader->programhandle[p].glsl); + for (i = 0; i < 8; i++) + { + uniformloc = qglGetUniformLocationARB(shader->programhandle[p].glsl, va("s_t%i", i)); + if (uniformloc != -1) + qglUniform1iARB(uniformloc, i); + } + } + for (i = 0; u[i].name; i++) + { + found = false; + for (p = 0; p < PERMUTATIONS; p++) + { + if (!shader->programhandle[p].glsl) + continue; + GLSlang_UseProgram(shader->programhandle[p].glsl); + if (u[i].ptype >= SP_FIRSTUNIFORM) + uniformloc = qglGetUniformLocationARB(shader->programhandle[p].glsl, u[i].name); + else + uniformloc = qglGetAttribLocationARB(shader->programhandle[p].glsl, u[i].name); + if (uniformloc != -1) + found = true; + shader->progparm[shader->numprogparams].handle[p] = uniformloc; + } + if (found) + { + shader->progparm[shader->numprogparams].type = u[i].ptype; + shader->numprogparams++; + + if (u[i].ptype < SP_FIRSTUNIFORM) + shader->flags |= SHADER_NOBUILTINATTR; + } + } + GLSlang_UseProgram(0); + } +#endif +} static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr, int qrtype) { @@ -746,78 +1280,55 @@ static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **p } where BLAH is both vertex+frag with #ifdefs or - program vert frag + program fname on one line. */ - void *vert, *frag; - char *token; + char *programbody; + char *start, *end; - token = *ptr; - while (*token == ' ' || *token == '\t' || *token == '\r') - token++; - if (*token == '\n') + end = *ptr; + while (*end == ' ' || *end == '\t' || *end == '\r') + end++; + if (*end == '\n') { int count; - token++; - while (*token == ' ' || *token == '\t') - token++; - if (*token != '{') + end++; + while (*end == ' ' || *end == '\t') + end++; + if (*end != '{') { Con_Printf("shader \"%s\" missing program string\n", shader->name); } else { - token++; - frag = token; - for (count = 1; *token; token++) + end++; + start = end; + for (count = 1; *end; end++) { - if (*token == '}') + if (*end == '}') { count--; if (!count) break; } - else if (*token == '{') + else if (*end == '{') count++; } - vert = BZ_Malloc(token - (char*)frag + 1); - memcpy(vert, frag, token-(char*)frag); - ((char*)vert)[token-(char*)frag] = 0; - frag = NULL; - *ptr = token+1; + programbody = BZ_Malloc(end - start + 1); + memcpy(programbody, start, end-start); + programbody[end-start] = 0; + *ptr = end+1;/*skip over it all*/ - Shader_LoadProgram(shader, vert, frag, qrtype); + Shader_LoadPermutations(shader->programhandle, programbody, qrtype); + Shader_ProgAutoFields(shader); - BZ_Free(vert); - - return; + BZ_Free(programbody); } - } - - vert = Shader_ParseString(ptr); - if (!strcmp(vert, "default")) - { - extern char *defaultglsl2program; - frag = Shader_ParseString(ptr); -#ifdef GLQUAKE - if (qrenderer == QR_OPENGL) - Shader_LoadProgram(shader, defaultglsl2program, defaultglsl2program, qrtype); -#endif return; } - FS_LoadFile(vert, &vert); - frag = Shader_ParseString(ptr); - if (!frag) - frag = NULL; - else - FS_LoadFile(frag, &frag); - - Shader_LoadProgram(shader, vert, frag, qrtype); - if (vert) - FS_FreeFile(vert); - if (frag) - FS_FreeFile(frag); + Shader_LoadGeneric(shader->programhandle, Shader_ParseString(ptr), qrtype); + Shader_ProgAutoFields(shader); } static void Shader_GLSLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr) @@ -838,6 +1349,7 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p enum shaderprogparmtype_e parmtype = SP_BAD; char *token; qboolean silent = false; + char *forcename = NULL; token = Shader_ParseString(ptr); if (!Q_stricmp(token, "opt")) @@ -910,7 +1422,10 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p else Con_Printf("shader %s: parameter type \"%s\" not known\n", shader->name, token); - token = Shader_ParseSensString(ptr); + if (forcename) + token = forcename; + else + token = Shader_ParseSensString(ptr); #ifdef GLQUAKE if (qrenderer == QR_OPENGL) @@ -933,7 +1448,10 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p if (!shader->programhandle[p].glsl) continue; GLSlang_UseProgram(shader->programhandle[p].glsl); - uniformloc = qglGetUniformLocationARB(shader->programhandle[p].glsl, token); + if (parmtype >= SP_FIRSTUNIFORM) + uniformloc = qglGetUniformLocationARB(shader->programhandle[p].glsl, token); + else + uniformloc = qglGetAttribLocationARB(shader->programhandle[p].glsl, token); shader->progparm[shader->numprogparams].handle[p] = uniformloc; if (uniformloc != -1) { @@ -964,7 +1482,7 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p } } if (!foundone && !silent) - Con_Printf("shader %s: param without uniform \"%s\"\n", shader->name, token); + Con_Printf("shader %s: param \"%s\" not found\n", shader->name, token); else shader->numprogparams++; @@ -1633,6 +2151,7 @@ qboolean Shader_Init (void) memset(shader_active_hash_mem, 0, Hash_BytesForBuckets(1024)); Hash_InitTable(&shader_active_hash, 1024, shader_active_hash_mem); + Shader_FlushGenerics(); shader_rescan_needed = true; Shader_NeedReload(); Shader_DoReload(); @@ -1773,7 +2292,7 @@ void Shader_Free (shader_t *shader) for (p = 0; p < PERMUTATIONS; p++) { if (shader->programhandle[p].glsl) - GLSlang_DeleteObject(shader->programhandle[p].glsl); + qglDeleteProgramObject_(shader->programhandle[p].glsl); } } #endif @@ -2517,24 +3036,22 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args) "}\n" "}\n" ); - -/* if (0&&!builtin && gl_config.arb_shader_objects) +#ifdef GLQUAKE + if (!builtin && gl_config.arb_shader_objects && gl_config.nofixedfunc) { builtin = ( "{\n" - "program default\n" - "param texture 0 tex_diffuse\n" + "program defaultwall\n" + /*"param texture 0 tex_diffuse\n" "param texture 1 tex_lightmap\n" "param texture 2 tex_normalmap\n" "param texture 3 tex_deluxmap\n" - "param texture 4 tex_fullbright\n" + "param texture 4 tex_fullbright\n"*/ "{\n" "map $diffuse\n" - "tcgen base\n" "}\n" "{\n" "map $lightmap\n" - "tcgen lightmap\n" "}\n" "{\n" "map $normalmap\n" @@ -2548,7 +3065,7 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args) "}\n" ); } -*/ +#endif if (!builtin) builtin = ( "{\n" @@ -2763,44 +3280,14 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args) { builtin = ( "{\n" - "sort blend\n" - "program\n" - "{\n" - "#ifdef VERTEX_SHADER\n" - "varying vec3 pos;\n" - "varying vec2 tc;\n" - - "void main (void)\n" - "{\n" - " tc = gl_MultiTexCoord0.st;\n" - " gl_Position = ftransform();\n" - "}\n" - "#endif\n" - - "#ifdef FRAGMENT_SHADER\n" - "uniform sampler2D watertexture;\n" - "uniform float time;\n" - "uniform float wateralpha;\n" - "varying vec2 tc;\n" - - "void main (void)\n" - "{\n" - " vec2 ntc;\n" - " ntc.s = tc.s + sin(tc.t+time)*0.125;\n" - " ntc.t = tc.t + sin(tc.s+time)*0.125;\n" - " vec3 ts = vec3(texture2D(watertexture, ntc));\n" - - " gl_FragColor = vec4(ts, wateralpha);\n" - "}\n" - "#endif\n" - "}\n" - "param time time\n" - "param texture 0 watertexture\n" + "sort blend\n" /*make sure it always has the same sort order, so switching on/off wateralpha doesn't break stuff*/ + "program defaultwarp\n" "if r_wateralpha != 1\n" "[\n" "param cvarf r_wateralpha wateralpha\n" "{\n" "map $diffuse\n" + "tcmod turb 0 0 3 0.1\n" "blendfunc gl_src_alpha gl_one_minus_src_alpha\n" "}\n" "]\n" @@ -2809,6 +3296,7 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args) "param constf 1 wateralpha\n" "{\n" "map $diffuse\n" + "tcmod turb 0 0 3 0.1\n" "}\n" "]\n" "surfaceparm nodlight\n" @@ -2883,50 +3371,8 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args) builtin = ( "{\n" "sort sky\n" - "program\n" - "{\n" - "#ifdef VERTEX_SHADER\n" - "varying vec3 pos;\n" - - "void main (void)\n" - "{\n" - " pos = gl_Vertex.xyz;\n" - " gl_Position = ftransform();\n" - "}\n" - "#endif\n" - - "#ifdef FRAGMENT_SHADER\n" - "uniform sampler2D solidt;\n" - "uniform sampler2D transt;\n" - - "uniform float time;\n" - "uniform vec3 eyepos;\n" - "varying vec3 pos;\n" - - "void main (void)\n" - "{\n" - " vec2 tccoord;\n" - - " vec3 dir = pos - eyepos;\n" - - " dir.z *= 3.0;\n" - " dir.xy /= 0.5*length(dir);\n" - - " tccoord = (dir.xy + time*0.03125);\n" - " vec3 solid = vec3(texture2D(solidt, tccoord));\n" - - " tccoord = (dir.xy + time*0.0625);\n" - " vec4 clouds = texture2D(transt, tccoord);\n" - - " gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb);\n" - // " gl_FragColor.rgb = solid.rgb;/*gl_FragColor.g = clouds.r;*/gl_FragColor.b = clouds.a;\n" - "}\n" - "#endif\n" - "}\n" - "param time time\n" + "program defaultsky\n" "param eyepos eyepos\n" - "param texture 0 solidt\n" - "param texture 1 transt\n" "surfaceparm nodlight\n" //"skyparms - 512 -\n" "{\n" @@ -3075,6 +3521,7 @@ void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args) { Shader_DefaultScript(shortname, s, "{\n" + "program defaultskin\n" "{\n" "map $diffuse\n" "rgbgen lightingDiffuse\n" @@ -3130,6 +3577,7 @@ void Shader_Default2D(char *shortname, shader_t *s, const void *genargs) { Shader_DefaultScript(shortname, s, "{\n" +// "program default2d\n" "nomipmaps\n" "{\n" "clampmap $diffuse\n" @@ -3291,13 +3739,47 @@ static int R_LoadShader ( char *name, shader_gen_t *defaultgen, const char *gena if (ruleset_allow_shaders.ival) { #ifdef GLQUAKE - if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects) + if (qrenderer == QR_OPENGL) { - if (Shader_ParseShader(va("%s_glsl", shortname), shortname, s)) + if (gl_config.gles && gl_config.glversion >= 2) { - s->generator = defaultgen; - s->genargs = genargs; - return f; + if (Shader_ParseShader(va("%s_gles2", shortname), shortname, s)) + { + s->generator = defaultgen; + s->genargs = genargs; + return f; + } + } + if (gl_config.glversion >= 3) + { + if (Shader_ParseShader(va("%s_glsl3", shortname), shortname, s)) + { + s->generator = defaultgen; + s->genargs = genargs; + return f; + } + } + if (gl_config.arb_shader_objects) + { + if (Shader_ParseShader(va("%s_glsl", shortname), shortname, s)) + { + s->generator = defaultgen; + s->genargs = genargs; + return f; + } + } + } +#endif +#ifdef D3DQUAKE + if (qrenderer == QR_DIRECT3D) + { + { + if (Shader_ParseShader(va("%s_hlsl", shortname), shortname, s)) + { + s->generator = defaultgen; + s->genargs = genargs; + return f; + } } } #endif diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index 3aee3a8df..2f76f8f33 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -10,12 +10,6 @@ #define nearplane (16) -#if 1//def _DEBUG -#define checkerror() if (qglGetError()) Con_Printf("Error detected at line %s:%i\n", __FILE__, __LINE__) -#else -#define checkerror() -#endif - static int shadow_fbo_id; static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour); @@ -1288,8 +1282,6 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float p // qglDepthRange(0, 1); - -checkerror(); if (l->fov) qglViewport (0, 0, smsize, smsize); else @@ -1335,8 +1327,6 @@ checkerror(); R_SetFrustum(proj, mvm); - checkerror(); - if (smesh) for (tno = 0; tno < smesh->numsurftextures; tno++) { @@ -1372,8 +1362,6 @@ checkerror(); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); } - - checkerror(); } void Sh_Shutdown(void) @@ -1396,20 +1384,14 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis) if (!TEXVALID(l->stexture)) { l->stexture = GL_AllocNewTexture(smsize, smsize); - - checkerror(); GL_Bind(l->stexture); - checkerror(); qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32_ARB, smsize, smsize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); // qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smsize, smsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - checkerror(); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - checkerror(); } smesh = SHM_BuildShadowVolumeMesh(l, lvis, NULL); @@ -1550,7 +1532,6 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis) t[13] = bp[7]; t[14] = bp[11]; t[15] = bp[15]; -checkerror(); bench.numlights++; @@ -1565,7 +1546,6 @@ checkerror(); GL_SelectTexture(0); - checkerror(); ve = 0; BE_SelectDLight(l, colour); @@ -1577,9 +1557,6 @@ checkerror(); qglMatrixMode(GL_TEXTURE); qglLoadIdentity(); qglMatrixMode(GL_MODELVIEW); - - - checkerror(); } @@ -1873,8 +1850,6 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis) } bench.numlights++; - checkerror(); - BE_SelectDLight(dl, colour); BE_SelectMode(BEM_STENCIL, 0); @@ -2008,8 +1983,6 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis) qglPopMatrix(); #endif - checkerror(); - PPL_RevertToKnownState(); BE_SelectMode(BEM_LIGHT, 0); @@ -2018,7 +1991,6 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis) qglDisable(GL_STENCIL_TEST); qglStencilFunc( GL_ALWAYS, 0, ~0 ); - checkerror(); return true; } diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 09f02cb61..9b1370d18 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -4,12 +4,6 @@ #include "gl_draw.h" #include "shader.h" -#ifdef _DEBUG -#define checkerror() if (qglGetError()) Con_Printf("Error detected at line %s:%i\n", __FILE__, __LINE__) -#else -#define checkerror() -#endif - //standard 1.1 opengl calls void (APIENTRY *qglAlphaFunc) (GLenum func, GLclampf ref); void (APIENTRY *qglBegin) (GLenum mode); @@ -138,17 +132,27 @@ PFNGLGENPROGRAMSARBPROC qglGenProgramsARB; FTEPFNGLLOCKARRAYSEXTPROC qglLockArraysEXT; FTEPFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT; -//glslang - arb_shader_objects +/*glslang - arb_shader_objects +gl core uses different names/distinctions from the extension +*/ FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB; -FTEPFNGLDELETEOBJECTARBPROC qglDeleteObjectARB; +FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_; +FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_; FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB; FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB; FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB; FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB; -FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetObjectParameterivARB; +FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_; +FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_; FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB; -FTEPFNGLGETINFOLOGARBPROC qglGetInfoLogARB; +FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_; +FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_; FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB; +FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB; +FTEPFNGLGETATTRIBLOCATIONARBPROC qglGetAttribLocationARB; +FTEPFNGLVERTEXATTRIBPOINTER qglVertexAttribPointer; +FTEPFNGLENABLEVERTEXATTRIBARRAY qglEnableVertexAttribArray; +FTEPFNGLDISABLEVERTEXATTRIBARRAY qglDisableVertexAttribArray; FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB; FTEPFNGLUNIFORMMATRIX4FVARBPROC qglUniformMatrix4fvARB; FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB; @@ -331,12 +335,22 @@ void APIENTRY GL_BindBufferARBStub(GLenum target, GLuint id) #define getglcore getglfunction #define getglext(name) getglfunction(name) -void GL_CheckExtensions (void *(*getglfunction) (char *name)) +void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver) { extern cvar_t gl_bump; memset(&gl_config, 0, sizeof(gl_config)); + gl_config.glversion = ver; + + if (!strncmp(gl_version, "OpenGL ES", 9)) + gl_config.gles = true; + else + gl_config.gles = false; + + gl_config.nofixedfunc = (gl_config.gles && gl_config.glversion >= 2) /*|| + (!gl_config.gles && gl_config.glversion >= 3 && noncompat)*/; + //multitexture gl_mtexable = false; gl_mtexarbable = 0; @@ -406,7 +420,14 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) // if (GL_CheckExtension("GL_SGIS_generate_mipmap")) //a suprising number of implementations have this broken. // gl_config.sgis_generate_mipmap = true; - if (GL_CheckExtension("GL_ARB_multitexture") && !COM_CheckParm("-noamtex")) + if (gl_config.gles) + { + qglActiveTextureARB = (void *) getglext("glActiveTexture"); + qglSelectTextureSGIS = qglActiveTextureARB; + mtexid0 = GL_TEXTURE0_ARB; + mtexid1 = GL_TEXTURE1_ARB; + } + else if (GL_CheckExtension("GL_ARB_multitexture") && !COM_CheckParm("-noamtex")) { //ARB multitexture is the popular choice. qglActiveTextureARB = (void *) getglext("glActiveTextureARB"); qglClientActiveTextureARB = (void *) getglext("glClientActiveTextureARB"); @@ -534,15 +555,23 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) { gl_config.arb_shader_objects = true; qglCreateProgramObjectARB = (void *)getglext("glCreateProgramObjectARB"); - qglDeleteObjectARB = (void *)getglext("glDeleteObjectARB"); + qglDeleteProgramObject_ = (void *)getglext("glDeleteObjectARB"); + qglDeleteShaderObject_ = (void *)getglext("glDeleteObjectARB"); qglUseProgramObjectARB = (void *)getglext("glUseProgramObjectARB"); qglCreateShaderObjectARB = (void *)getglext("glCreateShaderObjectARB"); qglShaderSourceARB = (void *)getglext("glShaderSourceARB"); qglCompileShaderARB = (void *)getglext("glCompileShaderARB"); - qglGetObjectParameterivARB = (void *)getglext("glGetObjectParameterivARB"); + qglGetProgramParameteriv_ = (void *)getglext("glGetObjectParameterivARB"); + qglGetShaderParameteriv_ = (void *)getglext("glGetObjectParameterivARB"); qglAttachObjectARB = (void *)getglext("glAttachObjectARB"); - qglGetInfoLogARB = (void *)getglext("glGetInfoLogARB"); + qglGetProgramInfoLog_ = (void *)getglext("glGetInfoLogARB"); + qglGetShaderInfoLog_ = (void *)getglext("glGetInfoLogARB"); qglLinkProgramARB = (void *)getglext("glLinkProgramARB"); + qglBindAttribLocationARB = (void *)getglext("glBindAttribLocationARB"); + qglGetAttribLocationARB = (void *)getglext("glGetAttribLocationARB"); + qglVertexAttribPointer = (void *)getglext("glVertexAttribPointerARB"); + qglEnableVertexAttribArray = (void *)getglext("glEnableVertexAttribArrayARB"); + qglDisableVertexAttribArray = (void *)getglext("glDisableVertexAttribArrayARB"); qglGetUniformLocationARB = (void *)getglext("glGetUniformLocationARB"); qglUniformMatrix4fvARB = (void *)getglext("glUniformMatrix4fvARB"); qglUniform4fARB = (void *)getglext("glUniform4fARB"); @@ -552,6 +581,36 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) qglUniform1iARB = (void *)getglext("glUniform1iARB"); qglUniform1fARB = (void *)getglext("glUniform1fARB"); } + else if (gl_config.gles && gl_config.glversion >= 2) + { + gl_config.arb_shader_objects = true; + qglCreateProgramObjectARB = (void *)getglext( "glCreateProgram"); + qglDeleteProgramObject_ = (void *)getglext( "glDeleteProgram"); + qglDeleteShaderObject_ = (void *)getglext( "glDeleteShader"); + qglUseProgramObjectARB = (void *)getglext( "glUseProgram"); + qglCreateShaderObjectARB = (void *)getglext( "glCreateShader"); + qglGetProgramParameteriv_ = (void *)getglext( "glGetProgramiv"); + qglGetShaderParameteriv_ = (void *)getglext( "glGetShaderiv"); + qglAttachObjectARB = (void *)getglext( "glAttachShader"); + qglGetProgramInfoLog_ = (void *)getglext( "glGetProgramInfoLog"); + qglGetShaderInfoLog_ = (void *)getglext( "glGetShaderInfoLog"); + qglShaderSourceARB = (void *)getglext("glShaderSource"); + qglCompileShaderARB = (void *)getglext("glCompileShader"); + qglLinkProgramARB = (void *)getglext("glLinkProgram"); + qglBindAttribLocationARB = (void *)getglext("glBindAttribLocation"); + qglGetAttribLocationARB = (void *)getglext("glGetAttribLocation"); + qglVertexAttribPointer = (void *)getglext("glVertexAttribPointer"); + qglEnableVertexAttribArray = (void *)getglext("glEnableVertexAttribArray"); + qglDisableVertexAttribArray = (void *)getglext("glDisableVertexAttribArray"); + qglGetUniformLocationARB = (void *)getglext("glGetUniformLocation"); + qglUniformMatrix4fvARB = (void *)getglext("glUniformMatrix4fv"); + qglUniform4fARB = (void *)getglext("glUniform4f"); + qglUniform4fvARB = (void *)getglext("glUniform4fv"); + qglUniform3fARB = (void *)getglext("glUniform3f"); + qglUniform3fvARB = (void *)getglext("glUniform3fv"); + qglUniform1iARB = (void *)getglext("glUniform1i"); + qglUniform1fARB = (void *)getglext("glUniform1f"); + } if (GL_CheckExtension("GL_EXT_framebuffer_object")) { @@ -586,41 +645,43 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) // glslang helper api function definitions // type should be GL_FRAGMENT_SHADER_ARB or GL_VERTEX_SHADER_ARB -GLhandleARB GLSlang_CreateShader (char *precompilerconstants, char *shadersource, GLenum shadertype) +GLhandleARB GLSlang_CreateShader (char **precompilerconstants, char *shadersource, GLenum shadertype) { GLhandleARB shader; GLint compiled; char str[1024]; int loglen; - char *prstrings[4]; + char *prstrings[3+16]; + int strings = 0; - prstrings[0] = "#define ENGINE_"DISTRIBUTION"\n"; + prstrings[strings++] = "#define ENGINE_"DISTRIBUTION"\n"; switch (shadertype) { case GL_FRAGMENT_SHADER_ARB: - prstrings[1] = "#define FRAGMENT_SHADER\n"; + prstrings[strings++] = "#define FRAGMENT_SHADER\n"; break; case GL_VERTEX_SHADER_ARB: - prstrings[1] = "#define VERTEX_SHADER\n"; + prstrings[strings++] = "#define VERTEX_SHADER\n"; break; default: - prstrings[1] = "#define UNKNOWN_SHADER\n"; + prstrings[strings++] = "#define UNKNOWN_SHADER\n"; break; } - prstrings[2] = precompilerconstants; - prstrings[3] = shadersource; + while(*precompilerconstants) + prstrings[strings++] = *precompilerconstants++; + prstrings[strings++] = shadersource; shader = qglCreateShaderObjectARB(shadertype); - qglShaderSourceARB(shader, 4, (const GLcharARB**)prstrings, NULL); + qglShaderSourceARB(shader, strings, (const GLcharARB**)prstrings, NULL); qglCompileShaderARB(shader); - qglGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled); + qglGetShaderParameteriv_(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled); if(!compiled) { Con_DPrintf("Shader source:\n%s%s%s\n", prstrings[0], prstrings[1], prstrings[2], prstrings[3]); - qglGetInfoLogARB(shader, sizeof(str), NULL, str); - qglDeleteObjectARB(shader); + qglGetShaderInfoLog_(shader, sizeof(str), NULL, str); + qglDeleteShaderObject_(shader); switch (shadertype) { case GL_FRAGMENT_SHADER_ARB: @@ -638,10 +699,10 @@ GLhandleARB GLSlang_CreateShader (char *precompilerconstants, char *shadersource if (developer.ival) { - qglGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &loglen); + qglGetShaderParameteriv_(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &loglen); if (loglen) { - qglGetInfoLogARB(shader, sizeof(str), NULL, str); + qglGetShaderInfoLog_(shader, sizeof(str), NULL, str); if (strstr(str, "WARNING")) { Con_Printf("Shader source:\n%s%s%s\n", prstrings[0], prstrings[1], prstrings[2], prstrings[3]); @@ -663,21 +724,25 @@ GLhandleARB GLSlang_CreateProgramObject (GLhandleARB vert, GLhandleARB frag) qglAttachObjectARB(program, vert); qglAttachObjectARB(program, frag); + qglBindAttribLocationARB(program, 0, "v_position"); + qglBindAttribLocationARB(program, 1, "v_colour"); + qglBindAttribLocationARB(program, 2, "v_texcoord"); + qglBindAttribLocationARB(program, 3, "v_lmcoord"); + qglBindAttribLocationARB(program, 4, "v_normal"); + qglBindAttribLocationARB(program, 5, "v_snormal"); + qglBindAttribLocationARB(program, 6, "v_tnormal"); + qglLinkProgramARB(program); - //flag the source objects for deletion, they'll only be deleted when they're no longer attached to anything - qglDeleteObjectARB(vert); - qglDeleteObjectARB(frag); - - qglGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linked); + qglGetProgramParameteriv_(program, GL_OBJECT_LINK_STATUS_ARB, &linked); if(!linked) { - qglGetInfoLogARB(program, sizeof(str), NULL, str); + qglGetProgramInfoLog_(program, sizeof(str), NULL, str); Con_Printf("Program link error: %s\n", str); + return (GLhandleARB)0; } - return program; } @@ -696,7 +761,7 @@ bucket_t *compiledshadersbuckets[64]; static hashtable_t compiledshaderstable; #endif -GLhandleARB GLSlang_CreateProgram(char *precompilerconstants, char *vert, char *frag) +GLhandleARB GLSlang_CreateProgram(char **precompilerconstants, char *vert, char *frag) { GLhandleARB handle; GLhandleARB vs; @@ -705,12 +770,13 @@ GLhandleARB GLSlang_CreateProgram(char *precompilerconstants, char *vert, char * unsigned int hashkey; struct compiledshaders_s *cs; #endif + char *nullconstants = NULL; if (!gl_config.arb_shader_objects) return 0; if (!precompilerconstants) - precompilerconstants = ""; + precompilerconstants = &nullconstants; #if HASHPROGRAMS hashkey = Hash_Key(precompilerconstants, ~0) ^ Hash_Key(frag, ~0); @@ -731,13 +797,14 @@ GLhandleARB GLSlang_CreateProgram(char *precompilerconstants, char *vert, char * vs = GLSlang_CreateShader(precompilerconstants, vert, GL_VERTEX_SHADER_ARB); fs = GLSlang_CreateShader(precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB); + if (!vs || !fs) handle = 0; else handle = GLSlang_CreateProgramObject(vs, fs); //delete ignores 0s. - qglDeleteObjectARB(vs); - qglDeleteObjectARB(fs); + qglDeleteShaderObject_(vs); + qglDeleteShaderObject_(fs); #if HASHPROGRAMS cs = Z_Malloc(sizeof(*cs) + strlen(precompilerconstants)+1+strlen(vert)+1+strlen(frag)+1); @@ -903,13 +970,16 @@ void GL_Init(void *(*getglfunction) (char *name)) qglGetIntegerv(GL_MINOR_VERSION, &gl_minor_version); if (qglGetError()) { - gl_config.glversion = atof(gl_version); - gl_major_version = 1; - gl_minor_version = 1; - } - else - { - gl_config.glversion = gl_major_version + (gl_minor_version/10.f); + /*GL_MAJOR_VERSION not supported? try and parse (es-aware)*/ + const char *s; + for (s = gl_version; *s && (*s < '0' || *s > '9'); s++) + ; + gl_major_version = atoi(s); + while(*s >= '0' && *s <= '9') + s++; + if (*s == '.') + s++; + gl_minor_version = atoi(s); } qglGetIntegerv(GL_NUM_EXTENSIONS, &gl_num_extensions); if (!qglGetError() && gl_num_extensions) @@ -917,14 +987,13 @@ void GL_Init(void *(*getglfunction) (char *name)) int i; if (developer.value) { - Con_Printf ("GL_EXTENSIONS:"); + Con_Printf ("GL_EXTENSIONS:\n"); for (i = 0; i < gl_num_extensions; i++) { Con_Printf (" %s", qglGetStringi(GL_EXTENSIONS, i)); - if ((i & 15) == 15) - Con_Printf("\n"); + Con_Printf("\n"); } - Con_Printf ("\n"); + Con_Printf ("end of list\n"); } else Con_Printf ("GL_EXTENSIONS: %i extensions\n", gl_num_extensions); @@ -940,20 +1009,35 @@ void GL_Init(void *(*getglfunction) (char *name)) Sys_Error("no extensions\n"); } - GL_CheckExtensions (getglfunction); + GL_CheckExtensions (getglfunction, gl_major_version + (gl_minor_version/10.f)); + + if (gl_config.gles && gl_config.glversion >= 2) + { + /*no matricies in gles, so don't try!*/ + qglLoadMatrixf = NULL; + qglPolygonMode = NULL; + qglShadeModel = NULL; + qglDepthRange = NULL; + + qglEnableClientState = NULL; + qglDisableClientState = NULL; + + qglDrawRangeElements = GL_DrawRangeElementsEmul; + } qglClearColor (0,0,0,0); //clear to black so that it looks a little nicer on start. qglClear(GL_COLOR_BUFFER_BIT); - qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); - qglShadeModel (GL_FLAT); + if (qglPolygonMode) + qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + if (qglShadeModel) + qglShadeModel (GL_FLAT); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - checkerror(); #ifdef DEBUG if (qglDebugMessageEnableAMD) qglDebugMessageEnableAMD(0, 0, 0, NULL, true); @@ -965,8 +1049,6 @@ void GL_Init(void *(*getglfunction) (char *name)) #if HASHPROGRAMS Hash_InitTable(&compiledshaderstable, sizeof(compiledshadersbuckets)/Hash_BytesForBuckets(1), compiledshadersbuckets); #endif - - checkerror(); } unsigned int d_8to24rgbtable[256]; @@ -1071,3 +1153,4 @@ rendererinfo_t openglrendererinfo = { }; #endif + diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index b9994a8da..ae8851e2b 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -152,12 +152,6 @@ void ClearAllStates (void); void VID_UpdateWindowStatus (HWND hWnd); void GL_Init(void *(*getglfunction) (char *name)); -#ifdef _DEBUG -#define checkerror() if (qglGetError()) Con_Printf("Error detected at line %s:%i\n", __FILE__, __LINE__) -#else -#define checkerror() -#endif - typedef void (APIENTRY *lp3DFXFUNC) (int, int, int, int, int, const void*); lp3DFXFUNC qglColorTableEXT; qboolean is8bit = false; @@ -946,10 +940,10 @@ qboolean VID_AttachGL (rendererstate_t *info) Con_SafePrintf(CON_ERROR "wglMakeCurrent failed\n"); //green to make it show. return false; } -/* + if (developer.ival) { - char *(WINAPI *wglGetExtensionsString)(void) = NULL; + char *(WINAPI *wglGetExtensionsString)(HDC hdc) = NULL; if (!wglGetExtensionsString) wglGetExtensionsString = getglfunc("wglGetExtensionsString"); if (!wglGetExtensionsString) @@ -957,9 +951,9 @@ qboolean VID_AttachGL (rendererstate_t *info) if (!wglGetExtensionsString) wglGetExtensionsString = getglfunc("wglGetExtensionsStringEXT"); if (wglGetExtensionsString) - Con_SafePrintf("WGL extensions: %s\n", wglGetExtensionsString()); + Con_SafePrintf("WGL extensions: %s\n", wglGetExtensionsString(maindc)); } -*/ + qwglCreateContextAttribsARB = getglfunc("wglCreateContextAttribsARB"); #ifdef _DEBUG //attempt to promote that to opengl3. @@ -969,18 +963,23 @@ qboolean VID_AttachGL (rendererstate_t *info) int attribs[9]; char *mv; int i = 0; + char *ver; - mv = vid_gl_context_version.string; + ver = vid_gl_context_version.string; + if (!*ver && vid_gl_context_es2.ival) + ver = "2.0"; + + mv = ver; while (*mv) { if (*mv++ == '.') break; } - if (*vid_gl_context_version.string) + if (*ver) { attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; - attribs[i++] = (int)vid_gl_context_version.value; + attribs[i++] = atoi(ver); } if (*mv) { @@ -1031,8 +1030,10 @@ qboolean VID_AttachGL (rendererstate_t *info) else { DWORD error = GetLastError(); - if (error == ERROR_INVALID_VERSION_ARB) + if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB)) Con_Printf("Unsupported OpenGL context version (%s).\n", vid_gl_context_version.string); + else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB)) + Con_Printf("Unsupported OpenGL profile (%s).\n", vid_gl_context_es2.ival?"gles":(vid_gl_context_compatibility.ival?"compat":"core")); else Con_Printf("Unknown error creating an OpenGL (%s) Context.\n", vid_gl_context_version.string); } @@ -1043,8 +1044,6 @@ qboolean VID_AttachGL (rendererstate_t *info) TRACE(("dbg: VID_AttachGL: GL_Init\n")); GL_Init(getglfunc); - checkerror(); - qwglChoosePixelFormatARB = getglfunc("wglChoosePixelFormatARB"); qwglSwapIntervalEXT = getglfunc("wglSwapIntervalEXT"); @@ -1061,8 +1060,6 @@ qboolean VID_AttachGL (rendererstate_t *info) if (!qGetDeviceGammaRamp) qGetDeviceGammaRamp = (void*)GetDeviceGammaRamp; if (!qSetDeviceGammaRamp) qSetDeviceGammaRamp = (void*)SetDeviceGammaRamp; - checkerror(); - return true; } diff --git a/engine/gl/gl_warp.c b/engine/gl/gl_warp.c index 81f02f186..57b0187f3 100644 --- a/engine/gl/gl_warp.c +++ b/engine/gl/gl_warp.c @@ -89,7 +89,7 @@ void R_DrawSkyChain (batch_t *batch) return; } #ifdef GLQUAKE - if (*r_fastsky.string) + if (*r_fastsky.string && qrenderer == QR_OPENGL) { R_CalcSkyChainBounds(batch); diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index f82fa98d0..2a685af75 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -88,6 +88,11 @@ typedef void (APIENTRYP FTEPFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB typedef void (APIENTRYP FTEPFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); typedef void (APIENTRYP FTEPFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); typedef void (APIENTRYP FTEPFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (APIENTRYP FTEPFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, GLcharARB *name); +typedef GLint (APIENTRYP FTEPFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); +typedef void (APIENTRYP FTEPFNGLVERTEXATTRIBPOINTER) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP FTEPFNGLENABLEVERTEXATTRIBARRAY) (GLuint index); +typedef void (APIENTRYP FTEPFNGLDISABLEVERTEXATTRIBARRAY) (GLuint index); typedef GLint (APIENTRYP FTEPFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); typedef void (APIENTRYP FTEPFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP FTEPFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat *value); @@ -113,6 +118,8 @@ qboolean GL_CheckExtension(char *extname); typedef struct { float glversion; + qboolean nofixedfunc; + qboolean gles; qboolean tex_env_combine; qboolean nv_tex_env_combine4; qboolean env_add; @@ -305,7 +312,7 @@ void GL_Set2D (void); // qboolean R_ShouldDraw(entity_t *e); #ifdef GLQUAKE -void R_RotateForEntity (const entity_t *e, const model_t *mod); +void R_RotateForEntity (float *modelviewmatrix, const entity_t *e, const model_t *mod); void GL_InitSceneProcessingShaders (void); void GL_SetupSceneProcessingTextures (void); @@ -752,15 +759,23 @@ extern PFNGLGENPROGRAMSARBPROC qglGenProgramsARB; //glslang - arb_shader_objects extern FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB; -extern FTEPFNGLDELETEOBJECTARBPROC qglDeleteObjectARB; +extern FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_; +extern FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_; extern FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB; extern FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB; extern FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB; extern FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB; -extern FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetObjectParameterivARB; +extern FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_; +extern FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_; extern FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB; -extern FTEPFNGLGETINFOLOGARBPROC qglGetInfoLogARB; +extern FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_; +extern FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_; extern FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB; +extern FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB; +extern FTEPFNGLGETATTRIBLOCATIONARBPROC qglGetAttribLocationARB; +extern FTEPFNGLVERTEXATTRIBPOINTER qglVertexAttribPointer; +extern FTEPFNGLENABLEVERTEXATTRIBARRAY qglEnableVertexAttribArray; +extern FTEPFNGLDISABLEVERTEXATTRIBARRAY qglDisableVertexAttribArray; extern FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB; extern FTEPFNGLUNIFORMMATRIX4FVARBPROC qglUniformMatrix4fvARB; extern FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB; @@ -771,12 +786,19 @@ extern FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB; extern FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB; //glslang helper api -GLhandleARB GLSlang_CreateProgram (char *precompilerconstants, char *vert, char *frag); +GLhandleARB GLSlang_CreateProgram (char **precompilerconstants, char *vert, char *frag); GLint GLSlang_GetUniformLocation (int prog, char *name); -#define GLSlang_UseProgram(prog) qglUseProgramObjectARB(prog); -#define GLSlang_SetUniform1i(uni, parm0) qglUniform1iARB(uni, parm0); -#define GLSlang_SetUniform1f(uni, parm0) qglUniform1fARB(uni, parm0); -#define GLSlang_DeleteObject(object) qglDeleteObjectARB(object); +void GL_SelectProgram(int program); +#define GLSlang_UseProgram(prog) GL_SelectProgram(prog) +#define GLSlang_SetUniform1i(uni, parm0) qglUniform1iARB(uni, parm0) +#define GLSlang_SetUniform1f(uni, parm0) qglUniform1fARB(uni, parm0) + + +#ifdef _DEBUG +#define checkglerror() do {int i=qglGetError(); if (i) Con_Printf("GL Error %i detected at line %s:%i\n", i, __FILE__, __LINE__);}while(0) +#else +#define checkglerror() +#endif extern FTEPFNGLLOCKARRAYSEXTPROC qglLockArraysEXT; diff --git a/engine/gl/gltod3d/gl_fakegl.cpp b/engine/gl/gltod3d/gl_fakegl.cpp index 538c936a8..481a42efd 100644 --- a/engine/gl/gltod3d/gl_fakegl.cpp +++ b/engine/gl/gltod3d/gl_fakegl.cpp @@ -4148,9 +4148,7 @@ rendererinfo_t d3dfglrendererinfo = { GLSCR_UpdateScreen, - /*backend*/ - NULL, - NULL, + /*backend*/ NULL, NULL, NULL, diff --git a/engine/gl/shader.h b/engine/gl/shader.h index d27ddb259..71efbe9f3 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -233,29 +233,48 @@ enum{ PERMUTATION_GENERIC = 0, PERMUTATION_BUMPMAP = 1, PERMUTATION_SPECULAR = 2, - PERMUTATION_BUMP_SPEC, - PERMUTATION_OFFSET = 4, - PERMUTATION_OFFSET_BUMP, - PERMUTATION_OFFSET_SPEC, - PERMUTATION_OFFSET_BUMP_SPEC, + PERMUTATION_FULLBRIGHT = 4, + PERMUTATION_LOWER = 8, + PERMUTATION_UPPER = 16, + PERMUTATION_OFFSET = 32, - PERMUTATIONS + PERMUTATIONS = 64 }; typedef struct { enum shaderprogparmtype_e { - SP_BAD, + SP_BAD, //never set (hopefully) + SP_ATTR_VERTEX, + SP_ATTR_COLOUR, + SP_ATTR_TEXCOORD, + SP_ATTR_LMCOORD, + SP_ATTR_NORMALS, + SP_ATTR_SNORMALS, + SP_ATTR_TNORMALS, + + SP_FIRSTUNIFORM, //never set + + /*entity properties*/ SP_ENTCOLOURS, SP_TOPCOLOURS, SP_BOTTOMCOLOURS, SP_TIME, + SP_E_L_DIR, /*these light values are non-dynamic light as in classic quake*/ + SP_E_L_MUL, + SP_E_L_AMBIENT, + SP_EYEPOS, SP_ENTMATRIX, + SP_VIEWMATRIX, + SP_MODELMATRIX, + SP_MODELVIEWMATRIX, + SP_PROJECTIONMATRIX, + SP_MODELVIEWPROJECTIONMATRIX, SP_RENDERTEXTURESCALE, /*multiplier for currentrender->texcoord*/ - SP_LIGHTRADIUS, + SP_LIGHTRADIUS, /*these light values are realtime lighting*/ SP_LIGHTCOLOUR, SP_LIGHTPOSITION, @@ -277,7 +296,10 @@ typedef struct { }; } shaderprogparm_t; - +union programhandle_u +{ + int glsl; +}; typedef struct { float factor; float unit; @@ -321,12 +343,11 @@ struct shader_s SHADER_NODLIGHT = 1 << 15, //from surfaceflags SHADER_HASLIGHTMAP = 1 << 16, - SHADER_HASTOPBOTTOM = 1 << 17 + SHADER_HASTOPBOTTOM = 1 << 17, + SHADER_NOBUILTINATTR = 1 << 18 /*using custom glsl attributes so don't feed it builtins*/ } flags; - union { - int glsl; - } programhandle[PERMUTATIONS]; + union programhandle_u programhandle[PERMUTATIONS]; int numprogparams; shaderprogparm_t progparm[SHADER_PROGPARMS_MAX];