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];