1
0
Fork 0
forked from fte/fteqw

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
This commit is contained in:
Spoike 2011-01-23 03:44:49 +00:00
parent 562f549357
commit 8fc0df0f44
20 changed files with 1328 additions and 622 deletions

View file

@ -2552,7 +2552,12 @@ void Surf_BuildLightmaps (void)
case QR_OPENGL: case QR_OPENGL:
/*favour bgra if the gpu supports it, otherwise use rgb only if it'll be used*/ /*favour bgra if the gpu supports it, otherwise use rgb only if it'll be used*/
lightmap_bgra = false; 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*/ /*the more common case*/
lightmap_bytes = 4; lightmap_bytes = 4;

View file

@ -628,7 +628,7 @@ void GLV_CalcBlend (float *hw_blend)
} }
else else
{ {
if (/*j == CSHIFT_BONUS || j == CSHIFT_DAMAGE ||*/ gl_nohwblend.ival) if (j == CSHIFT_BONUS || j == CSHIFT_DAMAGE || gl_nohwblend.ival)
blend = sw_blend; blend = sw_blend;
else //powerup or contents? else //powerup or contents?
blend = hw_blend; blend = hw_blend;

View file

@ -1224,23 +1224,23 @@ void Matrix4_Projection2(float *proj, float fovx, float fovy, float neard)
proj[15] = 0; 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) float znear, float zfar)
{ {
proj[0] = 2/(xmax-xmin); proj[0] = 2/(xmax-xmin);
proj[4] = 0; proj[4] = 0;
proj[8] = 0; proj[8] = 0;
proj[12] = (xmax+xmin)/(xmax-xmin); proj[12] = -(xmax+xmin)/(xmax-xmin);
proj[1] = 0; proj[1] = 0;
proj[5] = 2/(ymax-ymin); proj[5] = 2/(ymax-ymin);
proj[9] = 0; proj[9] = 0;
proj[13] = (ymax+ymin)/(ymax-ymin); proj[13] = -(ymax+ymin)/(ymax-ymin);
proj[2] = 0; proj[2] = 0;
proj[6] = 0; proj[6] = 0;
proj[10] = -2/(zfar-znear); proj[10] = -2/(zfar-znear);
proj[14] = (zfar+znear)/(zfar-znear); proj[14] = -(zfar+znear)/(zfar-znear);
proj[3] = 0; proj[3] = 0;
proj[7] = 0; proj[7] = 0;

View file

@ -1231,6 +1231,19 @@ rendererinfo_t d3drendererinfo =
D3D9_SCR_UpdateScreen, 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" "no more"
}; };

View file

@ -251,7 +251,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\client;../libs/freetype2/include;../common;../server;../gl;../sw;../qclib;../libs;../d3d9;../libs/dxsdk9/include;../libs/dxsdk7/include" AdditionalIncludeDirectories="../libs/speex;..\client;../libs/freetype2/include;../common;../server;../gl;../sw;../qclib;../libs;../d3d9;../libs/dxsdk9/include;../libs/dxsdk7/include"
PreprocessorDefinitions="_DEBUG;D3DQUAKE;WIN32;_WINDOWS" PreprocessorDefinitions="_DEBUG;D3DQUAKE;WIN32;_WINDOWS"
RuntimeLibrary="1" RuntimeLibrary="1"
FloatingPointModel="2" FloatingPointModel="2"
@ -1478,7 +1478,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include" AdditionalIncludeDirectories="../libs/speex;..\client;../libs/freetype2/include;../common;../server;../gl;../sw;../qclib;../libs;../libs/dxsdk9/include;../libs/dxsdk7/include"
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;GLQUAKE;USE_D3D;D3DQUAKE" PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;GLQUAKE;USE_D3D;D3DQUAKE"
RuntimeLibrary="1" RuntimeLibrary="1"
FloatingPointModel="2" FloatingPointModel="2"
@ -10972,14 +10972,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release Dedicated Server|x64" Name="Release Dedicated Server|x64"
ExcludedFromBuild="true" ExcludedFromBuild="true"
@ -10990,6 +10982,14 @@
PreprocessorDefinitions="" PreprocessorDefinitions=""
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug Dedicated Server|x64" Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true" ExcludedFromBuild="true"
@ -14105,23 +14105,8 @@
<File <File
RelativePath="..\client\snd_al.c" RelativePath="..\client\snd_al.c"
> >
<FileConfiguration
Name="MinGLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration <FileConfiguration
Name="D3DDebug|Win32" Name="D3DDebug|Win32"
ExcludedFromBuild="true"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -14135,20 +14120,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration <FileConfiguration
Name="GLDebug|x64" Name="GLDebug|x64"
ExcludedFromBuild="true" ExcludedFromBuild="true"
@ -14207,7 +14178,6 @@
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="MDebug|Win32" Name="MDebug|Win32"
ExcludedFromBuild="true"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -14221,13 +14191,6 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath="..\client\snd_directx.c" RelativePath="..\client\snd_directx.c"

View file

@ -15,7 +15,7 @@
#define LIGHTPASS_GLSL_SHARED "\ #define LIGHTPASS_GLSL_SHARED "\
varying vec2 tcbase;\n\ varying vec2 tcbase;\n\
varying vec3 lightvector;\n\ varying vec3 lightvector;\n\
#if defined(SPECULAR) || defined(USEOFFSETMAPPING)\n\ #if defined(SPECULAR) || defined(OFFSETMAPPING)\n\
varying vec3 eyevector;\n\ varying vec3 eyevector;\n\
#endif\n\ #endif\n\
#ifdef PCF\n\ #ifdef PCF\n\
@ -29,7 +29,7 @@ uniform mat4 entmatrix;\n\
\ \
uniform vec3 lightposition;\n\ uniform vec3 lightposition;\n\
\ \
#if defined(SPECULAR) || defined(USEOFFSETMAPPING)\n\ #if defined(SPECULAR) || defined(OFFSETMAPPING)\n\
uniform vec3 eyeposition;\n\ uniform vec3 eyeposition;\n\
#endif\n\ #endif\n\
\ \
@ -44,7 +44,7 @@ void main (void)\n\
lightvector.y = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n\ lightvector.y = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n\
lightvector.z = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n\ lightvector.z = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n\
\ \
#if defined(SPECULAR)||defined(USEOFFSETMAPPING)\n\ #if defined(SPECULAR)||defined(OFFSETMAPPING)\n\
vec3 eyeminusvertex = eyeposition - gl_Vertex.xyz;\n\ vec3 eyeminusvertex = eyeposition - gl_Vertex.xyz;\n\
eyevector.x = dot(eyeminusvertex, gl_MultiTexCoord2.xyz);\n\ eyevector.x = dot(eyeminusvertex, gl_MultiTexCoord2.xyz);\n\
eyevector.y = -dot(eyeminusvertex, gl_MultiTexCoord3.xyz);\n\ eyevector.y = -dot(eyeminusvertex, gl_MultiTexCoord3.xyz);\n\
@ -127,7 +127,7 @@ void main (void)\n\
#define LIGHTPASS_GLSL_FRAGMENT "\ #define LIGHTPASS_GLSL_FRAGMENT "\
#ifdef FRAGMENT_SHADER\n\ #ifdef FRAGMENT_SHADER\n\
uniform sampler2D baset;\n\ uniform sampler2D baset;\n\
#if defined(BUMP) || defined(SPECULAR) || defined(USEOFFSETMAPPING)\n\ #if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING)\n\
uniform sampler2D bumpt;\n\ uniform sampler2D bumpt;\n\
#endif\n\ #endif\n\
#ifdef SPECULAR\n\ #ifdef SPECULAR\n\
@ -148,14 +148,14 @@ uniform sampler2DShadow shadowmap;\n\
uniform float lightradius;\n\ uniform float lightradius;\n\
uniform vec3 lightcolour;\n\ uniform vec3 lightcolour;\n\
\ \
#ifdef USEOFFSETMAPPING\n\ #ifdef OFFSETMAPPING\n\
uniform float offsetmapping_scale;\n\ uniform float offsetmapping_scale;\n\
#endif\n\ #endif\n\
\ \
\ \
void main (void)\n\ void main (void)\n\
{\n\ {\n\
#ifdef USEOFFSETMAPPING\n\ #ifdef OFFSETMAPPING\n\
vec2 OffsetVector = normalize(eyevector).xy * offsetmapping_scale * vec2(1, -1);\n\ vec2 OffsetVector = normalize(eyevector).xy * offsetmapping_scale * vec2(1, -1);\n\
vec2 foo = tcbase;\n\ vec2 foo = tcbase;\n\
#define tcbase foo\n\ #define tcbase foo\n\
@ -320,12 +320,6 @@ static const char PCFPASS_SHADER[] = "\
extern cvar_t r_glsl_offsetmapping, r_noportals; extern cvar_t r_glsl_offsetmapping, r_noportals;
#ifdef _DEBUG
#define checkerror() if (qglGetError()) Con_Printf("Error detected at line %s:%i\n", __FILE__, __LINE__)
#else
#define checkerror()
#endif
static void BE_SendPassBlendAndDepth(unsigned int sbits); static void BE_SendPassBlendAndDepth(unsigned int sbits);
void GLBE_SubmitBatch(batch_t *batch); void GLBE_SubmitBatch(batch_t *batch);
@ -354,6 +348,8 @@ struct {
texid_t curshadowmap; texid_t curshadowmap;
unsigned int shaderbits; unsigned int shaderbits;
unsigned int sha_attr;
int currentprogram;
vbo_t dummyvbo; vbo_t dummyvbo;
int currentvbo; int currentvbo;
@ -361,6 +357,7 @@ struct {
mesh_t **meshes; mesh_t **meshes;
unsigned int meshcount; unsigned int meshcount;
float modelviewmatrix[16];
int pendingvertexvbo; int pendingvertexvbo;
void *pendingvertexpointer; void *pendingvertexpointer;
@ -372,7 +369,7 @@ struct {
texid_t temptexture; texid_t temptexture;
}; };
//exterior state //exterior state (paramters)
struct { struct {
backendmode_t mode; backendmode_t mode;
unsigned int flags; unsigned int flags;
@ -516,6 +513,42 @@ void GL_BindType(int type, texid_t texnum)
bindTexFunc (type, texnum.num); bindTexFunc (type, texnum.num);
} }
static void BE_EnableShaderAttributes(unsigned int newm)
{
unsigned int i;
if (newm == shaderstate.sha_attr)
return;
for (i = 0; i < 8; i++)
if ((newm^shaderstate.sha_attr) & (1u<<i))
{
if (newm & (1u<<i))
qglEnableVertexAttribArray(i);
else
qglDisableVertexAttribArray(i);
}
shaderstate.sha_attr = newm;
}
void GL_SelectProgram(int program)
{
if (shaderstate.currentprogram != program)
{
qglUseProgramObjectARB(program);
shaderstate.currentprogram = program;
}
}
static void GL_DeSelectProgram(void)
{
if (shaderstate.currentprogram != 0)
{
qglUseProgramObjectARB(0);
shaderstate.currentprogram = 0;
/*if disabling a program, we need to kill off custom attributes*/
BE_EnableShaderAttributes(0);
}
}
void GL_CullFace(unsigned int sflags) void GL_CullFace(unsigned int sflags)
{ {
#ifndef FORCESTATE #ifndef FORCESTATE
@ -607,7 +640,6 @@ static void RevertToKnownState(void)
GL_SelectVBO(0); GL_SelectVBO(0);
GL_SelectEBO(0); GL_SelectEBO(0);
checkerror();
while(shaderstate.lastpasstmus>0) while(shaderstate.lastpasstmus>0)
{ {
GL_SelectTexture(--shaderstate.lastpasstmus); GL_SelectTexture(--shaderstate.lastpasstmus);
@ -617,7 +649,6 @@ static void RevertToKnownState(void)
GL_SelectTexture(0); GL_SelectTexture(0);
qglEnableClientState(GL_VERTEX_ARRAY); qglEnableClientState(GL_VERTEX_ARRAY);
checkerror();
GL_TexEnv(GL_REPLACE); GL_TexEnv(GL_REPLACE);
@ -845,8 +876,6 @@ void GLBE_Init(void)
int i; int i;
double t; double t;
checkerror();
be_maxpasses = gl_mtexarbable; be_maxpasses = gl_mtexarbable;
for (i = 0; i < FTABLE_SIZE; i++) for (i = 0; i < FTABLE_SIZE; i++)
@ -882,7 +911,9 @@ void GLBE_Init(void)
shaderstate.shaderbits = ~0; shaderstate.shaderbits = ~0;
BE_SendPassBlendAndDepth(0); BE_SendPassBlendAndDepth(0);
qglEnableClientState(GL_VERTEX_ARRAY);
if (qglEnableClientState)
qglEnableClientState(GL_VERTEX_ARRAY);
currententity = &r_worldentity; currententity = &r_worldentity;
} }
@ -1646,7 +1677,6 @@ static void GenerateColourMods(const shaderpass_t *pass)
qglDisableClientState(GL_COLOR_ARRAY); qglDisableClientState(GL_COLOR_ARRAY);
qglColor4fv(scol); qglColor4fv(scol);
qglShadeModel(GL_FLAT); qglShadeModel(GL_FLAT);
checkerror();
} }
else else
{ {
@ -1682,7 +1712,6 @@ static void GenerateColourMods(const shaderpass_t *pass)
ambientlight[2]*0.5+shadelight[2], ambientlight[2]*0.5+shadelight[2],
shaderstate.curentity->shaderRGBAf[3]); shaderstate.curentity->shaderRGBAf[3]);
qglShadeModel(GL_FLAT); qglShadeModel(GL_FLAT);
checkerror();
return; return;
} }
} }
@ -1982,7 +2011,7 @@ static void BE_SubmitMeshChain(void)
} }
qglDrawRangeElements(GL_TRIANGLES, startv, endv, endi-starti, GL_INDEX_TYPE, shaderstate.sourcevbo->indicies + starti); qglDrawRangeElements(GL_TRIANGLES, startv, endv, endi-starti, GL_INDEX_TYPE, shaderstate.sourcevbo->indicies + starti);
} }
/* /*
if (qglUnlockArraysEXT) if (qglUnlockArraysEXT)
qglUnlockArraysEXT(); qglUnlockArraysEXT();
@ -2008,10 +2037,8 @@ static void DrawPass(const shaderpass_t *pass)
if (i == lastpass) if (i == lastpass)
return; return;
checkerror();
BE_SendPassBlendAndDepth(pass[i].shaderbits); BE_SendPassBlendAndDepth(pass[i].shaderbits);
GenerateColourMods(pass+i); GenerateColourMods(pass+i);
checkerror();
tmu = 0; tmu = 0;
for (; i < lastpass; i++) for (; i < lastpass; i++)
{ {
@ -2023,10 +2050,8 @@ static void DrawPass(const shaderpass_t *pass)
continue; continue;
GL_MBind(tmu, Shader_TextureForPass(pass+i)); GL_MBind(tmu, Shader_TextureForPass(pass+i));
checkerror();
BE_GeneratePassTC(pass, i); BE_GeneratePassTC(pass, i);
checkerror();
if (tmu >= shaderstate.lastpasstmus) if (tmu >= shaderstate.lastpasstmus)
{ {
qglEnable(GL_TEXTURE_2D); qglEnable(GL_TEXTURE_2D);
@ -2058,10 +2083,8 @@ static void DrawPass(const shaderpass_t *pass)
GL_TexEnv(GL_MODULATE); GL_TexEnv(GL_MODULATE);
break; break;
} }
checkerror();
tmu++; tmu++;
} }
checkerror();
for (i = tmu; i < shaderstate.lastpasstmus; i++) for (i = tmu; i < shaderstate.lastpasstmus; i++)
{ {
@ -2073,62 +2096,72 @@ static void DrawPass(const shaderpass_t *pass)
GL_ApplyVertexPointer(); GL_ApplyVertexPointer();
BE_SubmitMeshChain(); 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; vec3_t param3;
float m16[16];
int r, g, b; int r, g, b;
int perm; switch(p->type)
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++)
{ {
GL_MBind(i, Shader_TextureForPass(pass+i)); case SP_ATTR_VERTEX:
if (i >= shaderstate.lastpasstmus) /*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<<p->handle[perm];
case SP_ATTR_COLOUR:
if (shaderstate.sourcevbo->colours4f)
{ {
qglEnable(GL_TEXTURE_2D); GL_SelectVBO(shaderstate.curvertexvbo);
qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglVertexAttribPointer(p->handle[perm], 4, GL_FLOAT, GL_FALSE, sizeof(vec4_t), shaderstate.sourcevbo->colours4f);
return 1u<<p->handle[perm];
} }
BE_GeneratePassTC(pass, i); else if (shaderstate.sourcevbo->colours4ub)
}
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)
{ {
case SP_TIME: GL_SelectVBO(shaderstate.curvertexvbo);
qglUniform1fARB(s->progparm[i].handle[perm], shaderstate.curtime); qglVertexAttribPointer(p->handle[perm], 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(byte_vec4_t), shaderstate.sourcevbo->colours4ub);
break; return 1u<<p->handle[perm];
case SP_ENTMATRIX: }
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<<p->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<<p->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<<p->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<<p->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<<p->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); 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); /* VectorCopy(shaderstate.curentity->axis[0], m16+0);
m16[3] = 0; m16[3] = 0;
@ -2138,118 +2171,208 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
m16[11] = 0; m16[11] = 0;
VectorCopy(shaderstate.curentity->origin, m16+3); VectorCopy(shaderstate.curentity->origin, m16+3);
m16[15] = 1; m16[15] = 1;
*/ */
qglUniformMatrix4fvARB(s->progparm[i].handle[perm], 1, false, m16); qglUniformMatrix4fvARB(p->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;
} }
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(); BE_SubmitMeshChain();
GLSlang_UseProgram(0);
qglEnableClientState(GL_VERTEX_ARRAY);
} }
#ifdef RTLIGHTS #ifdef RTLIGHTS
@ -2372,12 +2495,14 @@ void GLBE_SelectMode(backendmode_t mode, unsigned int flags)
void GLBE_SelectEntity(entity_t *ent) 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); qglDepthRange (gldepthmin, gldepthmax);
shaderstate.curentity = ent; shaderstate.curentity = ent;
currententity = ent; currententity = ent;
R_RotateForEntity(shaderstate.curentity, shaderstate.curentity->model); R_RotateForEntity(shaderstate.modelviewmatrix, shaderstate.curentity, shaderstate.curentity->model);
if (shaderstate.curentity->flags & Q2RF_DEPTHHACK) if (qglLoadMatrixf)
qglLoadMatrixf(shaderstate.modelviewmatrix);
if (shaderstate.curentity->flags & Q2RF_DEPTHHACK && qglDepthRange)
qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin)); qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
} }
@ -2497,7 +2622,6 @@ static void DrawMeshes(void)
#endif #endif
{ {
shaderstate.curcull = (shaderstate.curshader->flags & (SHADER_CULL_FRONT|SHADER_CULL_BACK)); shaderstate.curcull = (shaderstate.curshader->flags & (SHADER_CULL_FRONT|SHADER_CULL_BACK));
if (shaderstate.curcull & SHADER_CULL_FRONT) if (shaderstate.curcull & SHADER_CULL_FRONT)
{ {
qglEnable(GL_CULL_FACE); qglEnable(GL_CULL_FACE);
@ -2515,7 +2639,6 @@ static void DrawMeshes(void)
} }
BE_PolyOffset(shaderstate.flags & BEF_PUSHDEPTH); BE_PolyOffset(shaderstate.flags & BEF_PUSHDEPTH);
switch(shaderstate.mode) switch(shaderstate.mode)
{ {
case BEM_STENCIL: case BEM_STENCIL:
@ -2533,6 +2656,7 @@ static void DrawMeshes(void)
break; break;
#endif #endif
case BEM_DEPTHONLY: case BEM_DEPTHONLY:
GL_DeSelectProgram();
#pragma message("fixme: support alpha test") #pragma message("fixme: support alpha test")
GL_ApplyVertexPointer(); GL_ApplyVertexPointer();
BE_SubmitMeshChain(); BE_SubmitMeshChain();
@ -2541,6 +2665,7 @@ static void DrawMeshes(void)
case BEM_DEPTHDARK: case BEM_DEPTHDARK:
if (shaderstate.curshader->flags & SHADER_HASLIGHTMAP) if (shaderstate.curshader->flags & SHADER_HASLIGHTMAP)
{ {
GL_DeSelectProgram();
qglColor3f(0,0,0); qglColor3f(0,0,0);
qglDisableClientState(GL_COLOR_ARRAY); qglDisableClientState(GL_COLOR_ARRAY);
while(shaderstate.lastpasstmus>0) while(shaderstate.lastpasstmus>0)
@ -2560,9 +2685,14 @@ static void DrawMeshes(void)
case BEM_STANDARD: case BEM_STANDARD:
default: default:
if (shaderstate.curshader->programhandle[0].glsl) if (shaderstate.curshader->programhandle[0].glsl)
{
BE_RenderMeshProgram(shaderstate.curshader, shaderstate.curshader->passes); BE_RenderMeshProgram(shaderstate.curshader, shaderstate.curshader->passes);
}
else if (gl_config.nofixedfunc)
break;
else else
{ {
GL_DeSelectProgram();
while (passno < shaderstate.curshader->numpasses) while (passno < shaderstate.curshader->numpasses)
{ {
p = &shaderstate.curshader->passes[passno]; 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.svector = m->snormals_array;
shaderstate.dummyvbo.tvector = m->tnormals_array; shaderstate.dummyvbo.tvector = m->tnormals_array;
shaderstate.dummyvbo.colours4f = m->colors4f_array; shaderstate.dummyvbo.colours4f = m->colors4f_array;
shaderstate.dummyvbo.colours4ub = m->colors4b_array;
shaderstate.meshcount = 1; shaderstate.meshcount = 1;
shaderstate.meshes = &m; shaderstate.meshes = &m;
@ -2787,7 +2918,6 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist)
if (batch->shader->flags & SHADER_NODLIGHT) if (batch->shader->flags & SHADER_NODLIGHT)
if (shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_SMAPLIGHT) if (shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_SMAPLIGHT)
continue; continue;
if (batch->shader->flags & SHADER_SKY) if (batch->shader->flags & SHADER_SKY)
{ {
if (shaderstate.mode == BEM_STANDARD) if (shaderstate.mode == BEM_STANDARD)
@ -2815,8 +2945,6 @@ void GLBE_SubmitMeshes (qboolean drawworld, batch_t **blist)
} }
BE_SubmitMeshesSortList(blist[i]); BE_SubmitMeshesSortList(blist[i]);
} }
checkerror();
} }
static void BE_UpdateLightmaps(void) static void BE_UpdateLightmaps(void)
@ -2832,6 +2960,7 @@ static void BE_UpdateLightmaps(void)
lightmap[lm]->modified = false; lightmap[lm]->modified = false;
theRect = &lightmap[lm]->rectchange; theRect = &lightmap[lm]->rectchange;
GL_Bind(lightmap_textures[lm]); GL_Bind(lightmap_textures[lm]);
checkglerror();
switch (lightmap_bytes) switch (lightmap_bytes)
{ {
case 4: case 4:
@ -2854,7 +2983,7 @@ static void BE_UpdateLightmaps(void)
theRect->t = LMBLOCK_HEIGHT; theRect->t = LMBLOCK_HEIGHT;
theRect->h = 0; theRect->h = 0;
theRect->w = 0; theRect->w = 0;
checkerror(); checkglerror();
if (lightmap[lm]->deluxmodified) if (lightmap[lm]->deluxmodified)
{ {
@ -2868,7 +2997,7 @@ static void BE_UpdateLightmaps(void)
theRect->t = LMBLOCK_HEIGHT; theRect->t = LMBLOCK_HEIGHT;
theRect->h = 0; theRect->h = 0;
theRect->w = 0; theRect->w = 0;
checkerror(); checkglerror();
} }
} }
} }
@ -2961,7 +3090,6 @@ void GLBE_DrawWorld (qbyte *vis)
shaderstate.wbatch = 0; shaderstate.wbatch = 0;
} }
BE_GenModelBatches(batches); BE_GenModelBatches(batches);
shaderstate.curentity = NULL; shaderstate.curentity = NULL;
shaderstate.updatetime = cl.servertime; shaderstate.updatetime = cl.servertime;
@ -2973,7 +3101,6 @@ void GLBE_DrawWorld (qbyte *vis)
#endif #endif
BE_UpdateLightmaps(); BE_UpdateLightmaps();
//make sure the world draws correctly //make sure the world draws correctly
r_worldentity.shaderRGBAf[0] = 1; r_worldentity.shaderRGBAf[0] = 1;
r_worldentity.shaderRGBAf[1] = 1; r_worldentity.shaderRGBAf[1] = 1;
@ -2995,8 +3122,6 @@ void GLBE_DrawWorld (qbyte *vis)
else else
BE_SelectMode(BEM_STANDARD, 0); BE_SelectMode(BEM_STANDARD, 0);
checkerror();
RSpeedRemark(); RSpeedRemark();
GLBE_SubmitMeshes(true, batches); GLBE_SubmitMeshes(true, batches);
RSpeedEnd(RSPEED_WORLD); RSpeedEnd(RSPEED_WORLD);
@ -3007,7 +3132,6 @@ void GLBE_DrawWorld (qbyte *vis)
Sh_DrawLights(vis); Sh_DrawLights(vis);
RSpeedEnd(RSPEED_STENCILSHADOWS); RSpeedEnd(RSPEED_STENCILSHADOWS);
#endif #endif
checkerror();
BE_DrawPolys(false); BE_DrawPolys(false);

View file

@ -788,17 +788,21 @@ Setup as if the screen was 320*200
void GL_Set2D (void) void GL_Set2D (void)
{ {
GL_SetShaderState2D(true); 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); qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
qglMatrixMode(GL_PROJECTION); if (qglLoadMatrixf)
qglLoadIdentity (); {
qglOrtho (0, vid.width, vid.height, 0, -99999, 99999); qglMatrixMode(GL_PROJECTION);
qglLoadMatrixf(r_refdef.m_projection);
qglMatrixMode(GL_MODELVIEW); qglMatrixMode(GL_MODELVIEW);
qglLoadIdentity (); qglLoadMatrixf(r_refdef.m_view);
}
r_refdef.time = realtime;
} }

View file

@ -210,10 +210,14 @@ static fontplanes_t fontplanes;
static index_t font_indicies[FONT_CHAR_BUFFER*6]; static index_t font_indicies[FONT_CHAR_BUFFER*6];
static vecV_t font_coord[FONT_CHAR_BUFFER*4]; static vecV_t font_coord[FONT_CHAR_BUFFER*4];
static vec2_t font_texcoord[FONT_CHAR_BUFFER*4]; static vec2_t font_texcoord[FONT_CHAR_BUFFER*4];
static vbo_t font_buffer; static byte_vec4_t font_forecoloura[FONT_CHAR_BUFFER*4];
static mesh_t font_mesh; 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 texid_t font_texture;
static int font_colourmask; static int font_colourmask;
static byte_vec4_t font_forecolour;
static byte_vec4_t font_backcolour;
static struct font_s *curfont; static struct font_s *curfont;
@ -223,13 +227,15 @@ void Font_Init(void)
int i; int i;
fontplanes.defaultfont = r_nulltex; fontplanes.defaultfont = r_nulltex;
font_buffer.indicies = font_indicies; font_foremesh.indexes = font_indicies;
font_buffer.coord = font_coord; font_foremesh.xyz_array = font_coord;
font_buffer.texcoord = font_texcoord; font_foremesh.st_array = font_texcoord;
font_foremesh.colors4b_array = font_forecoloura;
font_mesh.indexes = font_buffer.indicies; font_backmesh.indexes = font_indicies;
font_mesh.xyz_array = font_buffer.coord; font_backmesh.xyz_array = font_coord;
font_mesh.st_array = font_buffer.texcoord; font_backmesh.st_array = font_texcoord;
font_backmesh.colors4b_array = font_backcoloura;
for (i = 0; i < FONT_CHAR_BUFFER; i++) for (i = 0; i < FONT_CHAR_BUFFER; i++)
{ {
@ -248,11 +254,12 @@ void Font_Init(void)
fontplanes.shader = R_RegisterShader("ftefont", fontplanes.shader = R_RegisterShader("ftefont",
"{\n" "{\n"
// "program default2d\n"
"nomipmaps\n" "nomipmaps\n"
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"rgbgen const\n" "rgbgen vertex\n"
"alphagen const\n" "alphagen vertex\n"
"blendfunc blend\n" "blendfunc blend\n"
"}\n" "}\n"
"}\n" "}\n"
@ -263,8 +270,8 @@ void Font_Init(void)
"nomipmaps\n" "nomipmaps\n"
"{\n" "{\n"
"map $whiteimage\n" "map $whiteimage\n"
"rgbgen const\n" "rgbgen vertex\n"
"alphagen const\n" "alphagen vertex\n"
"blendfunc blend\n" "blendfunc blend\n"
"}\n" "}\n"
"}\n" "}\n"
@ -276,48 +283,43 @@ void Font_Init(void)
//flush the font buffer, by drawing it to the screen //flush the font buffer, by drawing it to the screen
static void Font_Flush(void) static void Font_Flush(void)
{ {
if (!font_mesh.numindexes) if (!font_foremesh.numindexes)
return; return;
if (fontplanes.planechanged) if (fontplanes.planechanged)
{ {
R_Upload(fontplanes.texnum[fontplanes.activeplane], NULL, TF_RGBA32, (void*)fontplanes.plane, NULL, PLANEWIDTH, PLANEHEIGHT, IF_NOPICMIP|IF_NOMIPMAP|IF_NOGAMMA); R_Upload(fontplanes.texnum[fontplanes.activeplane], NULL, TF_RGBA32, (void*)fontplanes.plane, NULL, PLANEWIDTH, PLANEHEIGHT, IF_NOPICMIP|IF_NOMIPMAP|IF_NOGAMMA);
fontplanes.planechanged = false; fontplanes.planechanged = false;
} }
font_mesh.istrifan = (font_mesh.numvertexes == 4); font_foremesh.istrifan = (font_foremesh.numvertexes == 4);
if (font_colourmask & CON_NONCLEARBG) if (font_colourmask & CON_NONCLEARBG)
{ {
fontplanes.backshader->defaulttextures.base = r_nulltex; font_backmesh.numindexes = font_foremesh.numindexes;
BE_DrawMesh_Single(fontplanes.backshader, &font_mesh, NULL, &fontplanes.backshader->defaulttextures); font_backmesh.numvertexes = font_foremesh.numvertexes;
font_backmesh.istrifan = font_foremesh.istrifan;
fontplanes.shader->defaulttextures.base = font_texture; BE_DrawMesh_Single(fontplanes.backshader, &font_backmesh, NULL, &fontplanes.backshader->defaulttextures);
BE_DrawMesh_Single(fontplanes.shader, &font_mesh, NULL, &fontplanes.shader->defaulttextures);
} }
else fontplanes.shader->defaulttextures.base = font_texture;
{ BE_DrawMesh_Single(fontplanes.shader, &font_foremesh, NULL, &fontplanes.shader->defaulttextures);
fontplanes.shader->defaulttextures.base = font_texture; font_foremesh.numindexes = 0;
BE_DrawMesh_Single(fontplanes.shader, &font_mesh, NULL, &fontplanes.shader->defaulttextures); font_foremesh.numvertexes = 0;
}
font_mesh.numindexes = 0;
font_mesh.numvertexes = 0;
} }
static int Font_BeginChar(texid_t tex) static int Font_BeginChar(texid_t tex)
{ {
int fvert; 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_Flush();
font_texture = tex; font_texture = tex;
} }
fvert = font_mesh.numvertexes; fvert = font_foremesh.numvertexes;
font_mesh.numindexes += 6; font_foremesh.numindexes += 6;
font_mesh.numvertexes += 4; font_foremesh.numvertexes += 4;
return fvert; 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*/ 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) void Font_ForceColour(float r, float g, float b, float a)
{ {
Font_Flush(); if (font_colourmask & CON_NONCLEARBG)
Font_Flush();
font_colourmask = CON_WHITEMASK; font_colourmask = CON_WHITEMASK;
/*force the colour to the requested one*/ font_forecolour[0] = r*255;
fontplanes.shader->passes[0].rgbgen_func.args[0] = r; font_forecolour[1] = g*255;
fontplanes.shader->passes[0].rgbgen_func.args[1] = g; font_forecolour[2] = b*255;
fontplanes.shader->passes[0].rgbgen_func.args[2] = b; font_forecolour[3] = a*255;
fontplanes.shader->passes[0].alphagen_func.args[0] = a;
/*no background*/ font_backcolour[3] = 0;
fontplanes.backshader->passes[0].alphagen_func.args[0] = 0;
/*Any drawchars that are now drawn will get the forced colour*/ /*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); col = charcode & (CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA);
if (col != font_colourmask) if (col != font_colourmask)
{ {
Font_Flush(); if ((col ^ font_colourmask) & CON_NONCLEARBG)
Font_Flush();
font_colourmask = col; font_colourmask = col;
col = (charcode&CON_FGMASK)>>CON_FGSHIFT; col = (charcode&CON_FGMASK)>>CON_FGSHIFT;
fontplanes.shader->passes[0].rgbgen_func.args[0] = consolecolours[col].fr; font_forecolour[0] = consolecolours[col].fr*255;
fontplanes.shader->passes[0].rgbgen_func.args[1] = consolecolours[col].fg; font_forecolour[1] = consolecolours[col].fg*255;
fontplanes.shader->passes[0].rgbgen_func.args[2] = consolecolours[col].fb; font_forecolour[2] = consolecolours[col].fb*255;
fontplanes.shader->passes[0].alphagen_func.args[0] = (charcode & CON_HALFALPHA)?0.5:1; font_forecolour[3] = (charcode & CON_HALFALPHA)?127:255;
col = (charcode&CON_BGMASK)>>CON_BGSHIFT; col = (charcode&CON_BGMASK)>>CON_BGSHIFT;
fontplanes.backshader->passes[0].rgbgen_func.args[0] = consolecolours[col].fr; font_backcolour[0] = consolecolours[col].fr*255;
fontplanes.backshader->passes[0].rgbgen_func.args[1] = consolecolours[col].fg; font_backcolour[1] = consolecolours[col].fg*255;
fontplanes.backshader->passes[0].rgbgen_func.args[2] = consolecolours[col].fb; font_backcolour[2] = consolecolours[col].fb*255;
fontplanes.backshader->passes[0].alphagen_func.args[0] = (charcode & CON_NONCLEARBG)?0.5:0; font_backcolour[3] = (charcode & CON_NONCLEARBG)?127:0;
} }
s0 = (float)c->bmx/PLANEWIDTH; 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][0] = sx;
font_coord[v+3][1] = sy+sh; 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; 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); col = charcode & (CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA);
if (col != font_colourmask) if (col != font_colourmask)
{ {
Font_Flush(); if ((col ^ font_colourmask) & CON_NONCLEARBG)
Font_Flush();
font_colourmask = col; font_colourmask = col;
col = (charcode&CON_FGMASK)>>CON_FGSHIFT; col = (charcode&CON_FGMASK)>>CON_FGSHIFT;
fontplanes.shader->passes[0].rgbgen_func.args[0] = consolecolours[col].fr; font_forecolour[0] = consolecolours[col].fr*255;
fontplanes.shader->passes[0].rgbgen_func.args[1] = consolecolours[col].fg; font_forecolour[1] = consolecolours[col].fg*255;
fontplanes.shader->passes[0].rgbgen_func.args[2] = consolecolours[col].fb; font_forecolour[2] = consolecolours[col].fb*255;
fontplanes.shader->passes[0].alphagen_func.args[0] = (charcode & CON_HALFALPHA)?0.5:1; font_forecolour[3] = (charcode & CON_HALFALPHA)?127:255;
col = (charcode&CON_BGMASK)>>CON_BGSHIFT; col = (charcode&CON_BGMASK)>>CON_BGSHIFT;
fontplanes.backshader->passes[0].rgbgen_func.args[0] = consolecolours[col].fr; font_backcolour[0] = consolecolours[col].fr*255;
fontplanes.backshader->passes[0].rgbgen_func.args[1] = consolecolours[col].fg; font_backcolour[1] = consolecolours[col].fg*255;
fontplanes.backshader->passes[0].rgbgen_func.args[2] = consolecolours[col].fb; font_backcolour[2] = consolecolours[col].fb*255;
fontplanes.backshader->passes[0].alphagen_func.args[0] = (charcode & CON_NONCLEARBG)?0.5:0; font_backcolour[3] = (charcode & CON_NONCLEARBG)?127:0;
} }
s0 = (float)c->bmx/PLANEWIDTH; 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][0] = sx;
font_coord[v+3][1] = sy+sh; 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; return nextx;
} }

View file

@ -570,6 +570,7 @@ void R_DrawHLModel(entity_t *curent)
int b, m, v; int b, m, v;
short *skins; short *skins;
int bgroup, cbone, lastbone; int bgroup, cbone, lastbone;
float mat[16];
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//general model //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]); 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; cbone = 0;
for (bgroup = 0; bgroup < FS_COUNT; bgroup++) for (bgroup = 0; bgroup < FS_COUNT; bgroup++)

View file

@ -233,6 +233,7 @@ typedef struct vbo_s
int vbocolours; int vbocolours;
vec4_t *colours4f; vec4_t *colours4f;
byte_vec4_t *colours4ub;
} vbo_t; } vbo_t;
void GL_SelectVBO(int vbo); void GL_SelectVBO(int vbo);
void GL_SelectEBO(int vbo); void GL_SelectEBO(int vbo);

View file

@ -27,12 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "shader.h" #include "shader.h"
#include "gl_draw.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); void R_RenderBrushPoly (msurface_t *fa);
#define PROJECTION_DISTANCE 200 #define PROJECTION_DISTANCE 200
@ -389,7 +383,7 @@ void GL_SetupSceneProcessingTextures (void)
GL_Bind(scenepp_texture_warp); GL_Bind(scenepp_texture_warp);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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 // TODO: init edge texture - this is ampscale * 2, with ampscale calculated
// init warp texture - this specifies offset in // 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); 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]; float m[16];
m[0] = e->axis[0][0]; m[0] = e->axis[0][0];
@ -520,13 +513,11 @@ void R_RotateForEntity (const entity_t *e, const model_t *mod)
/*FIXME: no bob*/ /*FIXME: no bob*/
float simpleview[16]; float simpleview[16];
Matrix4_ModelViewMatrix(simpleview, vec3_origin, vec3_origin); Matrix4_ModelViewMatrix(simpleview, vec3_origin, vec3_origin);
Matrix4_Multiply(simpleview, m, mv); Matrix4_Multiply(simpleview, m, modelview);
qglLoadMatrixf(mv);
} }
else else
{ {
Matrix4_Multiply(r_refdef.m_view, m, mv); Matrix4_Multiply(r_refdef.m_view, m, modelview);
qglLoadMatrixf(mv);
} }
} }
@ -1089,19 +1080,25 @@ void R_SetupGL (void)
Matrix4_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_refdef.vieworg); Matrix4_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_refdef.vieworg);
} }
qglMatrixMode(GL_PROJECTION); if (qglLoadMatrixf)
qglLoadMatrixf(r_refdef.m_projection);
qglMatrixMode(GL_MODELVIEW);
qglLoadMatrixf(r_refdef.m_view);
if (gl_dither.ival)
{ {
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; gldepthmax = 1;
gldepthfunc=GL_LEQUAL; gldepthfunc=GL_LEQUAL;
} }
qglDepthRange (gldepthmin, gldepthmax); if (qglDepthRange)
qglDepthRange (gldepthmin, gldepthmax);
} }
#if 0 #if 0

View file

@ -306,7 +306,7 @@ void GLBE_UploadAllLightmaps(void)
lightmap[i]->lightmaps); lightmap[i]->lightmaps);
break; break;
case 3: 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, LMBLOCK_WIDTH, LMBLOCK_WIDTH, 0, (lightmap_bgra?GL_BGR_EXT:GL_RGB), GL_UNSIGNED_BYTE,
lightmap[i]->lightmaps); lightmap[i]->lightmaps);
break; break;

View file

@ -708,23 +708,48 @@ static void Shader_EntityMergable ( shader_t *shader, shaderpass_t *pass, char *
shader->flags |= SHADER_ENTITY_MERGABLE; 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 BUMP\n",
"#define SPECULAR\n", "#define SPECULAR\n",
"#define SPECULAR\n#define BUMP\n", "#define FULLBRIGHT\n",
"#define USEOFFSETMAPPING\n", "#define LOWER\n",
"#define USEOFFSETMAPPING\n#define BUMP\n", "#define UPPER\n",
"#define USEOFFSETMAPPING\n#define SPECULAR\n", "#define OFFSETMAPPING\n",
"#define USEOFFSETMAPPING\n#define SPECULAR\n#define BUMP\n" NULL
}; };
int p; unsigned int nopermutation = ~0u;
int p, n, pn;
char *end;
if (!frag) for(;;)
frag = vert; {
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<<p);
}
script = end;
}
else
break;
};
memset(handle, 0, sizeof(*handle)*PERMUTATIONS);
for (p = 0; p < PERMUTATIONS; p++) for (p = 0; p < PERMUTATIONS; p++)
{ {
if (qrenderer != qrtype) if (qrenderer != qrtype)
@ -732,10 +757,519 @@ static void Shader_LoadProgram(shader_t *shader, char *vert, char *frag, int qrt
} }
#ifdef GLQUAKE #ifdef GLQUAKE
else if (qrenderer == QR_OPENGL) else if (qrenderer == QR_OPENGL)
shader->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<<n))
permutationdefines[pn++] = permutationname[n];
}
permutationdefines[pn++] = NULL;
handle[p].glsl = GLSlang_CreateProgram(permutationdefines, script, script);
}
#endif #endif
} }
} }
typedef struct sgeneric_s
{
struct sgeneric_s *next;
char name[MAX_QPATH];
union programhandle_u handle[PERMUTATIONS];
} sgeneric_t;
static sgeneric_t *sgenerics;
struct sbuiltin_s
{
int qrtype;
int apiver;
char name[MAX_QPATH];
char *body;
} sbuiltins[] =
{
{QR_OPENGL/*ES*/, 100, "default2d",
"#version 100\n"
"#ifdef VERTEX_SHADER\n"
"uniform mat4 m_view;\n"
"uniform mat4 m_projection;\n"
"attribute vec3 v_position;\n"
"attribute vec2 v_texcoord;\n"
"attribute vec4 v_colour;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"void main (void)\n"
"{\n"
" tc = v_texcoord;\n"
" vc = v_colour;\n"
" gl_Position = m_projection * m_view * vec4(v_position, 1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"in vec2 tc;\n"
"varying vec4 vc;\n"
"void main (void)\n"
"{\n"
" gl_FragColor = texture2D(s_t0, tc) * vc;\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "default2d",
"#version 110\n"
"#ifdef VERTEX_SHADER\n"
"uniform mat4 m_view;\n"
"uniform mat4 m_projection;\n"
"attribute vec3 v_position;\n"
"attribute vec2 v_texcoord;\n"
"attribute vec4 v_colour;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"void main (void)\n"
"{\n"
" tc = v_texcoord;\n"
" vc = v_colour;\n"
" gl_Position = m_projection * m_view * vec4(v_position, 1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"in vec2 tc;\n"
"varying vec4 vc;\n"
"void main (void)\n"
"{\n"
" gl_FragColor = texture2D(s_t0, tc) * vc;\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 130, "defaultwall",
"#version 130\n"
"#ifdef VERTEX_SHADER\n"
"uniform mat4 m_modelview;\n"
"uniform mat4 m_projection;\n"
"in vec3 v_position;\n"
"in vec2 v_texcoord;\n"
"in vec2 v_lmcoord;\n"
"out vec2 tc, lm;\n"
"void main (void)\n"
"{\n"
" tc = v_texcoord;\n"
" lm = v_lmcoord;\n"
" gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n" /*tex_diffuse*/
"uniform sampler2D s_t1;\n" /*tex_lightmap*/
//"uniform sampler2D s_t2;\n" /*tex_normalmap*/
//"uniform sampler2D s_t3;\n" /*tex_deluxmap*/
//"uniform sampler2D s_t4;\n" /*tex_fullbright*/
"in vec2 tc, lm;\n"
"void main (void)\n"
"{\n"
" gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL/*ES*/, 100, "defaultwall",
"!!permu FULLBRIGHT\n"
"#version 100\n"
"#ifdef VERTEX_SHADER\n"
"uniform mat4 m_modelview;\n"
"uniform mat4 m_projection;\n"
"attribute vec3 v_position;\n"
"attribute vec2 v_texcoord;\n"
"attribute vec2 v_lmcoord;\n"
"varying vec2 tc, lm;\n"
"void main (void)\n"
"{\n"
" tc = v_texcoord;\n"
" lm = v_lmcoord;\n"
" gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n" /*tex_diffuse*/
"uniform sampler2D s_t1;\n" /*tex_lightmap*/
//"uniform sampler2D s_t2;\n" /*tex_normalmap*/
//"uniform sampler2D s_t3;\n" /*tex_deluxmap*/
"#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t4;\n" /*tex_fullbright*/
"#endif\n"
"varying vec2 tc, lm;\n"
"void main (void)\n"
"{\n"
" gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm);\n"
"#ifdef FULLBRIGHT\n"
" gl_FragColor += texture2D(s_t4, tc);\n"
"#endif\n"
"}\n"
"#endif\n"
},
{QR_OPENGL/*ES*/, 100, "defaultwarp",
"#version 100\n"
"varying vec2 tc;\n"
"#ifdef VERTEX_SHADER\n"
"uniform mat4 m_modelview;\n"
"uniform mat4 m_projection;\n"
"attribute vec3 v_position;\n"
"attribute vec2 v_texcoord;\n"
"void main (void)\n"
"{\n"
" tc = v_texcoord;\n"
" gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D watertexture;\n"
"uniform float e_time;\n"
"uniform float wateralpha;\n"
"void main (void)\n"
"{\n"
" vec2 ntc;\n"
" ntc.s = tc.s + sin(tc.t+e_time)*0.125;\n"
" ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
" vec3 ts = vec3(texture2D(watertexture, ntc));\n"
" gl_FragColor = vec4(ts, wateralpha);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "defaultwarp",
"#version 110\n"
"varying vec2 tc;\n"
"#ifdef VERTEX_SHADER\n"
"void main (void)\n"
"{\n"
" tc = gl_MultiTexCoord0.st;\n"
" gl_Position = ftransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform float e_time;\n"
"uniform float wateralpha;\n"
"void main (void)\n"
"{\n"
" vec2 ntc;\n"
" ntc.s = tc.s + sin(tc.t+e_time)*0.125;\n"
" ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
" vec3 ts = vec3(texture2D(s_t0, ntc));\n"
" gl_FragColor = vec4(ts, wateralpha);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL/*ES*/, 100, "defaultsky",
"#version 100\n"
"#ifdef VERTEX_SHADER\n"
"uniform mat4 m_modelview;\n"
"uniform mat4 m_projection;\n"
"attribute vec3 v_position;\n"
"varying vec3 pos;\n"
"void main (void)\n"
"{\n"
" pos = v_position.xyz;\n"
" gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform sampler2D s_t1;\n"
"uniform float e_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 + e_time*0.03125);\n"
" vec3 solid = vec3(texture2D(s_t0, tccoord));\n"
" tccoord = (dir.xy + e_time*0.0625);\n"
" vec4 clouds = texture2D(s_t1, 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"
},
{QR_OPENGL, 110, "defaultsky",
"#version 110\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 float e_time;\n"
"uniform vec3 eyepos;\n"
"varying vec3 pos;\n"
"uniform sampler2D s_t0;\n"
"uniform sampler2D s_t1;\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 + e_time*0.03125);\n"
" vec3 solid = vec3(texture2D(s_t0, tccoord));\n"
" tccoord = (dir.xy + e_time*0.0625);\n"
" vec4 clouds = texture2D(s_t1, 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"
},
{QR_OPENGL/*ES*/, 100, "defaultskin",
"!!permu FULLBRIGHT\n"
"!!permu LOWER\n"
"!!permu UPPER\n"
"#version 100\n"
"#ifdef VERTEX_SHADER\n"
"uniform mat4 m_modelview;\n"
"uniform mat4 m_projection;\n"
"attribute vec3 v_position;\n"
"attribute vec2 v_texcoord;\n"
"varying vec2 tc;\n"
"attribute vec3 v_normal;\n"
"uniform vec3 e_light_dir;\n"
"uniform vec3 e_light_mul;\n"
"uniform vec3 e_light_ambient;\n"
"varying vec3 light;\n"
"void main (void)\n"
"{\n"
" light = e_light_ambient + (dot(v_normal,e_light_dir)*e_light_mul);\n"
" tc = v_texcoord;\n"
" gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n" /*tex_diffuse*/
"#ifdef LOWER\n"
"uniform sampler2D s_t1;\n" /*tex_lower*/
"uniform vec3 e_lowercolour;\n"
"#endif\n"
"#ifdef UPPER\n"
"uniform sampler2D s_t2;\n" /*tex_upper*/
"uniform vec3 e_uppercolour;\n"
"#endif\n"
"#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t3;\n" /*tex_fullbright*/
"#endif\n"
"varying vec2 tc;\n"
"varying vec3 light;\n"
"void main (void)\n"
"{\n"
" gl_FragColor = texture2D(s_t0, tc);\n"
"#ifdef UPPER\n"
" gl_FragColor.rgb += texture2D(s_t2, tc).rgb*e_uppercolour;\n"
"#endif\n"
"#ifdef LOWER\n"
" gl_FragColor.rgb += texture2D(s_t1, tc).rgb*e_lowercolour;\n"
"#endif\n"
" gl_FragColor.rgb *= light;\n"
"#ifdef FULLBRIGHT\n"
" gl_FragColor += texture2D(s_t3, tc);\n"
"#endif\n"
"}\n"
"#endif\n"
},
{QR_NONE}
};
static sgeneric_t *sgenerics;
static void Shader_FlushGenerics(void)
{
sgeneric_t *g;
while (sgenerics)
{
g = sgenerics;
sgenerics = g->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) 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 where BLAH is both vertex+frag with #ifdefs
or or
program vert frag program fname
on one line. on one line.
*/ */
void *vert, *frag; char *programbody;
char *token; char *start, *end;
token = *ptr; end = *ptr;
while (*token == ' ' || *token == '\t' || *token == '\r') while (*end == ' ' || *end == '\t' || *end == '\r')
token++; end++;
if (*token == '\n') if (*end == '\n')
{ {
int count; int count;
token++; end++;
while (*token == ' ' || *token == '\t') while (*end == ' ' || *end == '\t')
token++; end++;
if (*token != '{') if (*end != '{')
{ {
Con_Printf("shader \"%s\" missing program string\n", shader->name); Con_Printf("shader \"%s\" missing program string\n", shader->name);
} }
else else
{ {
token++; end++;
frag = token; start = end;
for (count = 1; *token; token++) for (count = 1; *end; end++)
{ {
if (*token == '}') if (*end == '}')
{ {
count--; count--;
if (!count) if (!count)
break; break;
} }
else if (*token == '{') else if (*end == '{')
count++; count++;
} }
vert = BZ_Malloc(token - (char*)frag + 1); programbody = BZ_Malloc(end - start + 1);
memcpy(vert, frag, token-(char*)frag); memcpy(programbody, start, end-start);
((char*)vert)[token-(char*)frag] = 0; programbody[end-start] = 0;
frag = NULL; *ptr = end+1;/*skip over it all*/
*ptr = token+1;
Shader_LoadProgram(shader, vert, frag, qrtype); Shader_LoadPermutations(shader->programhandle, programbody, qrtype);
Shader_ProgAutoFields(shader);
BZ_Free(vert); BZ_Free(programbody);
return;
} }
}
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; return;
} }
FS_LoadFile(vert, &vert);
frag = Shader_ParseString(ptr); Shader_LoadGeneric(shader->programhandle, Shader_ParseString(ptr), qrtype);
if (!frag) Shader_ProgAutoFields(shader);
frag = NULL;
else
FS_LoadFile(frag, &frag);
Shader_LoadProgram(shader, vert, frag, qrtype);
if (vert)
FS_FreeFile(vert);
if (frag)
FS_FreeFile(frag);
} }
static void Shader_GLSLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr) 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; enum shaderprogparmtype_e parmtype = SP_BAD;
char *token; char *token;
qboolean silent = false; qboolean silent = false;
char *forcename = NULL;
token = Shader_ParseString(ptr); token = Shader_ParseString(ptr);
if (!Q_stricmp(token, "opt")) if (!Q_stricmp(token, "opt"))
@ -910,7 +1422,10 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
else else
Con_Printf("shader %s: parameter type \"%s\" not known\n", shader->name, token); 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 #ifdef GLQUAKE
if (qrenderer == QR_OPENGL) 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) if (!shader->programhandle[p].glsl)
continue; continue;
GLSlang_UseProgram(shader->programhandle[p].glsl); 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; shader->progparm[shader->numprogparams].handle[p] = uniformloc;
if (uniformloc != -1) if (uniformloc != -1)
{ {
@ -964,7 +1482,7 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
} }
} }
if (!foundone && !silent) 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 else
shader->numprogparams++; shader->numprogparams++;
@ -1633,6 +2151,7 @@ qboolean Shader_Init (void)
memset(shader_active_hash_mem, 0, Hash_BytesForBuckets(1024)); memset(shader_active_hash_mem, 0, Hash_BytesForBuckets(1024));
Hash_InitTable(&shader_active_hash, 1024, shader_active_hash_mem); Hash_InitTable(&shader_active_hash, 1024, shader_active_hash_mem);
Shader_FlushGenerics();
shader_rescan_needed = true; shader_rescan_needed = true;
Shader_NeedReload(); Shader_NeedReload();
Shader_DoReload(); Shader_DoReload();
@ -1773,7 +2292,7 @@ void Shader_Free (shader_t *shader)
for (p = 0; p < PERMUTATIONS; p++) for (p = 0; p < PERMUTATIONS; p++)
{ {
if (shader->programhandle[p].glsl) if (shader->programhandle[p].glsl)
GLSlang_DeleteObject(shader->programhandle[p].glsl); qglDeleteProgramObject_(shader->programhandle[p].glsl);
} }
} }
#endif #endif
@ -2517,24 +3036,22 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
"}\n" "}\n"
"}\n" "}\n"
); );
#ifdef GLQUAKE
/* if (0&&!builtin && gl_config.arb_shader_objects) if (!builtin && gl_config.arb_shader_objects && gl_config.nofixedfunc)
{ {
builtin = ( builtin = (
"{\n" "{\n"
"program default\n" "program defaultwall\n"
"param texture 0 tex_diffuse\n" /*"param texture 0 tex_diffuse\n"
"param texture 1 tex_lightmap\n" "param texture 1 tex_lightmap\n"
"param texture 2 tex_normalmap\n" "param texture 2 tex_normalmap\n"
"param texture 3 tex_deluxmap\n" "param texture 3 tex_deluxmap\n"
"param texture 4 tex_fullbright\n" "param texture 4 tex_fullbright\n"*/
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"tcgen base\n"
"}\n" "}\n"
"{\n" "{\n"
"map $lightmap\n" "map $lightmap\n"
"tcgen lightmap\n"
"}\n" "}\n"
"{\n" "{\n"
"map $normalmap\n" "map $normalmap\n"
@ -2548,7 +3065,7 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
"}\n" "}\n"
); );
} }
*/ #endif
if (!builtin) if (!builtin)
builtin = ( builtin = (
"{\n" "{\n"
@ -2763,44 +3280,14 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
{ {
builtin = ( builtin = (
"{\n" "{\n"
"sort blend\n" "sort blend\n" /*make sure it always has the same sort order, so switching on/off wateralpha doesn't break stuff*/
"program\n" "program defaultwarp\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"
"if r_wateralpha != 1\n" "if r_wateralpha != 1\n"
"[\n" "[\n"
"param cvarf r_wateralpha wateralpha\n" "param cvarf r_wateralpha wateralpha\n"
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"tcmod turb 0 0 3 0.1\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n" "blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"}\n" "}\n"
"]\n" "]\n"
@ -2809,6 +3296,7 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
"param constf 1 wateralpha\n" "param constf 1 wateralpha\n"
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"tcmod turb 0 0 3 0.1\n"
"}\n" "}\n"
"]\n" "]\n"
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
@ -2883,50 +3371,8 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
builtin = ( builtin = (
"{\n" "{\n"
"sort sky\n" "sort sky\n"
"program\n" "program defaultsky\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"
"param eyepos eyepos\n" "param eyepos eyepos\n"
"param texture 0 solidt\n"
"param texture 1 transt\n"
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
//"skyparms - 512 -\n" //"skyparms - 512 -\n"
"{\n" "{\n"
@ -3075,6 +3521,7 @@ void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args)
{ {
Shader_DefaultScript(shortname, s, Shader_DefaultScript(shortname, s,
"{\n" "{\n"
"program defaultskin\n"
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"rgbgen lightingDiffuse\n" "rgbgen lightingDiffuse\n"
@ -3130,6 +3577,7 @@ void Shader_Default2D(char *shortname, shader_t *s, const void *genargs)
{ {
Shader_DefaultScript(shortname, s, Shader_DefaultScript(shortname, s,
"{\n" "{\n"
// "program default2d\n"
"nomipmaps\n" "nomipmaps\n"
"{\n" "{\n"
"clampmap $diffuse\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) if (ruleset_allow_shaders.ival)
{ {
#ifdef GLQUAKE #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; if (Shader_ParseShader(va("%s_gles2", shortname), shortname, s))
s->genargs = genargs; {
return f; 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 #endif

View file

@ -10,12 +10,6 @@
#define nearplane (16) #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 int shadow_fbo_id;
static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour); 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); // qglDepthRange(0, 1);
checkerror();
if (l->fov) if (l->fov)
qglViewport (0, 0, smsize, smsize); qglViewport (0, 0, smsize, smsize);
else else
@ -1335,8 +1327,6 @@ checkerror();
R_SetFrustum(proj, mvm); R_SetFrustum(proj, mvm);
checkerror();
if (smesh) if (smesh)
for (tno = 0; tno < smesh->numsurftextures; tno++) 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_S, GL_CLAMP);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
} }
checkerror();
} }
void Sh_Shutdown(void) void Sh_Shutdown(void)
@ -1396,20 +1384,14 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
if (!TEXVALID(l->stexture)) if (!TEXVALID(l->stexture))
{ {
l->stexture = GL_AllocNewTexture(smsize, smsize); l->stexture = GL_AllocNewTexture(smsize, smsize);
checkerror();
GL_Bind(l->stexture); 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_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); // 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_MAG_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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_S, GL_CLAMP);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
checkerror();
} }
smesh = SHM_BuildShadowVolumeMesh(l, lvis, NULL); 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[13] = bp[7];
t[14] = bp[11]; t[14] = bp[11];
t[15] = bp[15]; t[15] = bp[15];
checkerror();
bench.numlights++; bench.numlights++;
@ -1565,7 +1546,6 @@ checkerror();
GL_SelectTexture(0); GL_SelectTexture(0);
checkerror();
ve = 0; ve = 0;
BE_SelectDLight(l, colour); BE_SelectDLight(l, colour);
@ -1577,9 +1557,6 @@ checkerror();
qglMatrixMode(GL_TEXTURE); qglMatrixMode(GL_TEXTURE);
qglLoadIdentity(); qglLoadIdentity();
qglMatrixMode(GL_MODELVIEW); qglMatrixMode(GL_MODELVIEW);
checkerror();
} }
@ -1873,8 +1850,6 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
} }
bench.numlights++; bench.numlights++;
checkerror();
BE_SelectDLight(dl, colour); BE_SelectDLight(dl, colour);
BE_SelectMode(BEM_STENCIL, 0); BE_SelectMode(BEM_STENCIL, 0);
@ -2008,8 +1983,6 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
qglPopMatrix(); qglPopMatrix();
#endif #endif
checkerror();
PPL_RevertToKnownState(); PPL_RevertToKnownState();
BE_SelectMode(BEM_LIGHT, 0); 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); qglDisable(GL_STENCIL_TEST);
qglStencilFunc( GL_ALWAYS, 0, ~0 ); qglStencilFunc( GL_ALWAYS, 0, ~0 );
checkerror();
return true; return true;
} }

View file

@ -4,12 +4,6 @@
#include "gl_draw.h" #include "gl_draw.h"
#include "shader.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 //standard 1.1 opengl calls
void (APIENTRY *qglAlphaFunc) (GLenum func, GLclampf ref); void (APIENTRY *qglAlphaFunc) (GLenum func, GLclampf ref);
void (APIENTRY *qglBegin) (GLenum mode); void (APIENTRY *qglBegin) (GLenum mode);
@ -138,17 +132,27 @@ PFNGLGENPROGRAMSARBPROC qglGenProgramsARB;
FTEPFNGLLOCKARRAYSEXTPROC qglLockArraysEXT; FTEPFNGLLOCKARRAYSEXTPROC qglLockArraysEXT;
FTEPFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT; FTEPFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT;
//glslang - arb_shader_objects /*glslang - arb_shader_objects
gl core uses different names/distinctions from the extension
*/
FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB; FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB;
FTEPFNGLDELETEOBJECTARBPROC qglDeleteObjectARB; FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_;
FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_;
FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB; FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB;
FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB; FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB;
FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB; FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB;
FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB; FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB;
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetObjectParameterivARB; FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_;
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_;
FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB; FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB;
FTEPFNGLGETINFOLOGARBPROC qglGetInfoLogARB; FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_;
FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_;
FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB; FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB;
FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB;
FTEPFNGLGETATTRIBLOCATIONARBPROC qglGetAttribLocationARB;
FTEPFNGLVERTEXATTRIBPOINTER qglVertexAttribPointer;
FTEPFNGLENABLEVERTEXATTRIBARRAY qglEnableVertexAttribArray;
FTEPFNGLDISABLEVERTEXATTRIBARRAY qglDisableVertexAttribArray;
FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB; FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB;
FTEPFNGLUNIFORMMATRIX4FVARBPROC qglUniformMatrix4fvARB; FTEPFNGLUNIFORMMATRIX4FVARBPROC qglUniformMatrix4fvARB;
FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB; FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB;
@ -331,12 +335,22 @@ void APIENTRY GL_BindBufferARBStub(GLenum target, GLuint id)
#define getglcore getglfunction #define getglcore getglfunction
#define getglext(name) getglfunction(name) #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; extern cvar_t gl_bump;
memset(&gl_config, 0, sizeof(gl_config)); 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 //multitexture
gl_mtexable = false; gl_mtexable = false;
gl_mtexarbable = 0; 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. // if (GL_CheckExtension("GL_SGIS_generate_mipmap")) //a suprising number of implementations have this broken.
// gl_config.sgis_generate_mipmap = true; // 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. { //ARB multitexture is the popular choice.
qglActiveTextureARB = (void *) getglext("glActiveTextureARB"); qglActiveTextureARB = (void *) getglext("glActiveTextureARB");
qglClientActiveTextureARB = (void *) getglext("glClientActiveTextureARB"); qglClientActiveTextureARB = (void *) getglext("glClientActiveTextureARB");
@ -534,15 +555,23 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
{ {
gl_config.arb_shader_objects = true; gl_config.arb_shader_objects = true;
qglCreateProgramObjectARB = (void *)getglext("glCreateProgramObjectARB"); qglCreateProgramObjectARB = (void *)getglext("glCreateProgramObjectARB");
qglDeleteObjectARB = (void *)getglext("glDeleteObjectARB"); qglDeleteProgramObject_ = (void *)getglext("glDeleteObjectARB");
qglDeleteShaderObject_ = (void *)getglext("glDeleteObjectARB");
qglUseProgramObjectARB = (void *)getglext("glUseProgramObjectARB"); qglUseProgramObjectARB = (void *)getglext("glUseProgramObjectARB");
qglCreateShaderObjectARB = (void *)getglext("glCreateShaderObjectARB"); qglCreateShaderObjectARB = (void *)getglext("glCreateShaderObjectARB");
qglShaderSourceARB = (void *)getglext("glShaderSourceARB"); qglShaderSourceARB = (void *)getglext("glShaderSourceARB");
qglCompileShaderARB = (void *)getglext("glCompileShaderARB"); qglCompileShaderARB = (void *)getglext("glCompileShaderARB");
qglGetObjectParameterivARB = (void *)getglext("glGetObjectParameterivARB"); qglGetProgramParameteriv_ = (void *)getglext("glGetObjectParameterivARB");
qglGetShaderParameteriv_ = (void *)getglext("glGetObjectParameterivARB");
qglAttachObjectARB = (void *)getglext("glAttachObjectARB"); qglAttachObjectARB = (void *)getglext("glAttachObjectARB");
qglGetInfoLogARB = (void *)getglext("glGetInfoLogARB"); qglGetProgramInfoLog_ = (void *)getglext("glGetInfoLogARB");
qglGetShaderInfoLog_ = (void *)getglext("glGetInfoLogARB");
qglLinkProgramARB = (void *)getglext("glLinkProgramARB"); 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"); qglGetUniformLocationARB = (void *)getglext("glGetUniformLocationARB");
qglUniformMatrix4fvARB = (void *)getglext("glUniformMatrix4fvARB"); qglUniformMatrix4fvARB = (void *)getglext("glUniformMatrix4fvARB");
qglUniform4fARB = (void *)getglext("glUniform4fARB"); qglUniform4fARB = (void *)getglext("glUniform4fARB");
@ -552,6 +581,36 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglUniform1iARB = (void *)getglext("glUniform1iARB"); qglUniform1iARB = (void *)getglext("glUniform1iARB");
qglUniform1fARB = (void *)getglext("glUniform1fARB"); 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")) if (GL_CheckExtension("GL_EXT_framebuffer_object"))
{ {
@ -586,41 +645,43 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
// glslang helper api function definitions // glslang helper api function definitions
// type should be GL_FRAGMENT_SHADER_ARB or GL_VERTEX_SHADER_ARB // 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; GLhandleARB shader;
GLint compiled; GLint compiled;
char str[1024]; char str[1024];
int loglen; 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) switch (shadertype)
{ {
case GL_FRAGMENT_SHADER_ARB: case GL_FRAGMENT_SHADER_ARB:
prstrings[1] = "#define FRAGMENT_SHADER\n"; prstrings[strings++] = "#define FRAGMENT_SHADER\n";
break; break;
case GL_VERTEX_SHADER_ARB: case GL_VERTEX_SHADER_ARB:
prstrings[1] = "#define VERTEX_SHADER\n"; prstrings[strings++] = "#define VERTEX_SHADER\n";
break; break;
default: default:
prstrings[1] = "#define UNKNOWN_SHADER\n"; prstrings[strings++] = "#define UNKNOWN_SHADER\n";
break; break;
} }
prstrings[2] = precompilerconstants; while(*precompilerconstants)
prstrings[3] = shadersource; prstrings[strings++] = *precompilerconstants++;
prstrings[strings++] = shadersource;
shader = qglCreateShaderObjectARB(shadertype); shader = qglCreateShaderObjectARB(shadertype);
qglShaderSourceARB(shader, 4, (const GLcharARB**)prstrings, NULL); qglShaderSourceARB(shader, strings, (const GLcharARB**)prstrings, NULL);
qglCompileShaderARB(shader); qglCompileShaderARB(shader);
qglGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled); qglGetShaderParameteriv_(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
if(!compiled) if(!compiled)
{ {
Con_DPrintf("Shader source:\n%s%s%s\n", prstrings[0], prstrings[1], prstrings[2], prstrings[3]); Con_DPrintf("Shader source:\n%s%s%s\n", prstrings[0], prstrings[1], prstrings[2], prstrings[3]);
qglGetInfoLogARB(shader, sizeof(str), NULL, str); qglGetShaderInfoLog_(shader, sizeof(str), NULL, str);
qglDeleteObjectARB(shader); qglDeleteShaderObject_(shader);
switch (shadertype) switch (shadertype)
{ {
case GL_FRAGMENT_SHADER_ARB: case GL_FRAGMENT_SHADER_ARB:
@ -638,10 +699,10 @@ GLhandleARB GLSlang_CreateShader (char *precompilerconstants, char *shadersource
if (developer.ival) if (developer.ival)
{ {
qglGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &loglen); qglGetShaderParameteriv_(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &loglen);
if (loglen) if (loglen)
{ {
qglGetInfoLogARB(shader, sizeof(str), NULL, str); qglGetShaderInfoLog_(shader, sizeof(str), NULL, str);
if (strstr(str, "WARNING")) if (strstr(str, "WARNING"))
{ {
Con_Printf("Shader source:\n%s%s%s\n", prstrings[0], prstrings[1], prstrings[2], prstrings[3]); 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, vert);
qglAttachObjectARB(program, frag); 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); qglLinkProgramARB(program);
//flag the source objects for deletion, they'll only be deleted when they're no longer attached to anything qglGetProgramParameteriv_(program, GL_OBJECT_LINK_STATUS_ARB, &linked);
qglDeleteObjectARB(vert);
qglDeleteObjectARB(frag);
qglGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linked);
if(!linked) if(!linked)
{ {
qglGetInfoLogARB(program, sizeof(str), NULL, str); qglGetProgramInfoLog_(program, sizeof(str), NULL, str);
Con_Printf("Program link error: %s\n", str); Con_Printf("Program link error: %s\n", str);
return (GLhandleARB)0; return (GLhandleARB)0;
} }
return program; return program;
} }
@ -696,7 +761,7 @@ bucket_t *compiledshadersbuckets[64];
static hashtable_t compiledshaderstable; static hashtable_t compiledshaderstable;
#endif #endif
GLhandleARB GLSlang_CreateProgram(char *precompilerconstants, char *vert, char *frag) GLhandleARB GLSlang_CreateProgram(char **precompilerconstants, char *vert, char *frag)
{ {
GLhandleARB handle; GLhandleARB handle;
GLhandleARB vs; GLhandleARB vs;
@ -705,12 +770,13 @@ GLhandleARB GLSlang_CreateProgram(char *precompilerconstants, char *vert, char *
unsigned int hashkey; unsigned int hashkey;
struct compiledshaders_s *cs; struct compiledshaders_s *cs;
#endif #endif
char *nullconstants = NULL;
if (!gl_config.arb_shader_objects) if (!gl_config.arb_shader_objects)
return 0; return 0;
if (!precompilerconstants) if (!precompilerconstants)
precompilerconstants = ""; precompilerconstants = &nullconstants;
#if HASHPROGRAMS #if HASHPROGRAMS
hashkey = Hash_Key(precompilerconstants, ~0) ^ Hash_Key(frag, ~0); 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); vs = GLSlang_CreateShader(precompilerconstants, vert, GL_VERTEX_SHADER_ARB);
fs = GLSlang_CreateShader(precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB); fs = GLSlang_CreateShader(precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB);
if (!vs || !fs) if (!vs || !fs)
handle = 0; handle = 0;
else else
handle = GLSlang_CreateProgramObject(vs, fs); handle = GLSlang_CreateProgramObject(vs, fs);
//delete ignores 0s. //delete ignores 0s.
qglDeleteObjectARB(vs); qglDeleteShaderObject_(vs);
qglDeleteObjectARB(fs); qglDeleteShaderObject_(fs);
#if HASHPROGRAMS #if HASHPROGRAMS
cs = Z_Malloc(sizeof(*cs) + strlen(precompilerconstants)+1+strlen(vert)+1+strlen(frag)+1); 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); qglGetIntegerv(GL_MINOR_VERSION, &gl_minor_version);
if (qglGetError()) if (qglGetError())
{ {
gl_config.glversion = atof(gl_version); /*GL_MAJOR_VERSION not supported? try and parse (es-aware)*/
gl_major_version = 1; const char *s;
gl_minor_version = 1; for (s = gl_version; *s && (*s < '0' || *s > '9'); s++)
} ;
else gl_major_version = atoi(s);
{ while(*s >= '0' && *s <= '9')
gl_config.glversion = gl_major_version + (gl_minor_version/10.f); s++;
if (*s == '.')
s++;
gl_minor_version = atoi(s);
} }
qglGetIntegerv(GL_NUM_EXTENSIONS, &gl_num_extensions); qglGetIntegerv(GL_NUM_EXTENSIONS, &gl_num_extensions);
if (!qglGetError() && gl_num_extensions) if (!qglGetError() && gl_num_extensions)
@ -917,14 +987,13 @@ void GL_Init(void *(*getglfunction) (char *name))
int i; int i;
if (developer.value) if (developer.value)
{ {
Con_Printf ("GL_EXTENSIONS:"); Con_Printf ("GL_EXTENSIONS:\n");
for (i = 0; i < gl_num_extensions; i++) for (i = 0; i < gl_num_extensions; i++)
{ {
Con_Printf (" %s", qglGetStringi(GL_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 else
Con_Printf ("GL_EXTENSIONS: %i extensions\n", gl_num_extensions); 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"); 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. qglClearColor (0,0,0,0); //clear to black so that it looks a little nicer on start.
qglClear(GL_COLOR_BUFFER_BIT); qglClear(GL_COLOR_BUFFER_BIT);
qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); if (qglPolygonMode)
qglShadeModel (GL_FLAT); 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_MIN_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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_S, GL_REPEAT);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
checkerror();
#ifdef DEBUG #ifdef DEBUG
if (qglDebugMessageEnableAMD) if (qglDebugMessageEnableAMD)
qglDebugMessageEnableAMD(0, 0, 0, NULL, true); qglDebugMessageEnableAMD(0, 0, 0, NULL, true);
@ -965,8 +1049,6 @@ void GL_Init(void *(*getglfunction) (char *name))
#if HASHPROGRAMS #if HASHPROGRAMS
Hash_InitTable(&compiledshaderstable, sizeof(compiledshadersbuckets)/Hash_BytesForBuckets(1), compiledshadersbuckets); Hash_InitTable(&compiledshaderstable, sizeof(compiledshadersbuckets)/Hash_BytesForBuckets(1), compiledshadersbuckets);
#endif #endif
checkerror();
} }
unsigned int d_8to24rgbtable[256]; unsigned int d_8to24rgbtable[256];
@ -1071,3 +1153,4 @@ rendererinfo_t openglrendererinfo = {
}; };
#endif #endif

View file

@ -152,12 +152,6 @@ void ClearAllStates (void);
void VID_UpdateWindowStatus (HWND hWnd); void VID_UpdateWindowStatus (HWND hWnd);
void GL_Init(void *(*getglfunction) (char *name)); 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*); typedef void (APIENTRY *lp3DFXFUNC) (int, int, int, int, int, const void*);
lp3DFXFUNC qglColorTableEXT; lp3DFXFUNC qglColorTableEXT;
qboolean is8bit = false; 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. Con_SafePrintf(CON_ERROR "wglMakeCurrent failed\n"); //green to make it show.
return false; return false;
} }
/*
if (developer.ival) if (developer.ival)
{ {
char *(WINAPI *wglGetExtensionsString)(void) = NULL; char *(WINAPI *wglGetExtensionsString)(HDC hdc) = NULL;
if (!wglGetExtensionsString) if (!wglGetExtensionsString)
wglGetExtensionsString = getglfunc("wglGetExtensionsString"); wglGetExtensionsString = getglfunc("wglGetExtensionsString");
if (!wglGetExtensionsString) if (!wglGetExtensionsString)
@ -957,9 +951,9 @@ qboolean VID_AttachGL (rendererstate_t *info)
if (!wglGetExtensionsString) if (!wglGetExtensionsString)
wglGetExtensionsString = getglfunc("wglGetExtensionsStringEXT"); wglGetExtensionsString = getglfunc("wglGetExtensionsStringEXT");
if (wglGetExtensionsString) if (wglGetExtensionsString)
Con_SafePrintf("WGL extensions: %s\n", wglGetExtensionsString()); Con_SafePrintf("WGL extensions: %s\n", wglGetExtensionsString(maindc));
} }
*/
qwglCreateContextAttribsARB = getglfunc("wglCreateContextAttribsARB"); qwglCreateContextAttribsARB = getglfunc("wglCreateContextAttribsARB");
#ifdef _DEBUG #ifdef _DEBUG
//attempt to promote that to opengl3. //attempt to promote that to opengl3.
@ -969,18 +963,23 @@ qboolean VID_AttachGL (rendererstate_t *info)
int attribs[9]; int attribs[9];
char *mv; char *mv;
int i = 0; 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) while (*mv)
{ {
if (*mv++ == '.') if (*mv++ == '.')
break; break;
} }
if (*vid_gl_context_version.string) if (*ver)
{ {
attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
attribs[i++] = (int)vid_gl_context_version.value; attribs[i++] = atoi(ver);
} }
if (*mv) if (*mv)
{ {
@ -1031,8 +1030,10 @@ qboolean VID_AttachGL (rendererstate_t *info)
else else
{ {
DWORD error = GetLastError(); 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); 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 else
Con_Printf("Unknown error creating an OpenGL (%s) Context.\n", vid_gl_context_version.string); 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")); TRACE(("dbg: VID_AttachGL: GL_Init\n"));
GL_Init(getglfunc); GL_Init(getglfunc);
checkerror();
qwglChoosePixelFormatARB = getglfunc("wglChoosePixelFormatARB"); qwglChoosePixelFormatARB = getglfunc("wglChoosePixelFormatARB");
qwglSwapIntervalEXT = getglfunc("wglSwapIntervalEXT"); qwglSwapIntervalEXT = getglfunc("wglSwapIntervalEXT");
@ -1061,8 +1060,6 @@ qboolean VID_AttachGL (rendererstate_t *info)
if (!qGetDeviceGammaRamp) qGetDeviceGammaRamp = (void*)GetDeviceGammaRamp; if (!qGetDeviceGammaRamp) qGetDeviceGammaRamp = (void*)GetDeviceGammaRamp;
if (!qSetDeviceGammaRamp) qSetDeviceGammaRamp = (void*)SetDeviceGammaRamp; if (!qSetDeviceGammaRamp) qSetDeviceGammaRamp = (void*)SetDeviceGammaRamp;
checkerror();
return true; return true;
} }

View file

@ -89,7 +89,7 @@ void R_DrawSkyChain (batch_t *batch)
return; return;
} }
#ifdef GLQUAKE #ifdef GLQUAKE
if (*r_fastsky.string) if (*r_fastsky.string && qrenderer == QR_OPENGL)
{ {
R_CalcSkyChainBounds(batch); R_CalcSkyChainBounds(batch);

View file

@ -88,6 +88,11 @@ typedef void (APIENTRYP FTEPFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB
typedef void (APIENTRYP FTEPFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); typedef void (APIENTRYP FTEPFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
typedef void (APIENTRYP FTEPFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); typedef void (APIENTRYP FTEPFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
typedef void (APIENTRYP FTEPFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); 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 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 FTEPFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
typedef void (APIENTRYP FTEPFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat *value); typedef void (APIENTRYP FTEPFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat *value);
@ -113,6 +118,8 @@ qboolean GL_CheckExtension(char *extname);
typedef struct { typedef struct {
float glversion; float glversion;
qboolean nofixedfunc;
qboolean gles;
qboolean tex_env_combine; qboolean tex_env_combine;
qboolean nv_tex_env_combine4; qboolean nv_tex_env_combine4;
qboolean env_add; qboolean env_add;
@ -305,7 +312,7 @@ void GL_Set2D (void);
// //
qboolean R_ShouldDraw(entity_t *e); qboolean R_ShouldDraw(entity_t *e);
#ifdef GLQUAKE #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_InitSceneProcessingShaders (void);
void GL_SetupSceneProcessingTextures (void); void GL_SetupSceneProcessingTextures (void);
@ -752,15 +759,23 @@ extern PFNGLGENPROGRAMSARBPROC qglGenProgramsARB;
//glslang - arb_shader_objects //glslang - arb_shader_objects
extern FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB; extern FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB;
extern FTEPFNGLDELETEOBJECTARBPROC qglDeleteObjectARB; extern FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_;
extern FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_;
extern FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB; extern FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB;
extern FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB; extern FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB;
extern FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB; extern FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB;
extern FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB; extern FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB;
extern FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetObjectParameterivARB; extern FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_;
extern FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_;
extern FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB; extern FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB;
extern FTEPFNGLGETINFOLOGARBPROC qglGetInfoLogARB; extern FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_;
extern FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_;
extern FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB; extern FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB;
extern FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB;
extern FTEPFNGLGETATTRIBLOCATIONARBPROC qglGetAttribLocationARB;
extern FTEPFNGLVERTEXATTRIBPOINTER qglVertexAttribPointer;
extern FTEPFNGLENABLEVERTEXATTRIBARRAY qglEnableVertexAttribArray;
extern FTEPFNGLDISABLEVERTEXATTRIBARRAY qglDisableVertexAttribArray;
extern FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB; extern FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB;
extern FTEPFNGLUNIFORMMATRIX4FVARBPROC qglUniformMatrix4fvARB; extern FTEPFNGLUNIFORMMATRIX4FVARBPROC qglUniformMatrix4fvARB;
extern FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB; extern FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB;
@ -771,12 +786,19 @@ extern FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB;
extern FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB; extern FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB;
//glslang helper api //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); GLint GLSlang_GetUniformLocation (int prog, char *name);
#define GLSlang_UseProgram(prog) qglUseProgramObjectARB(prog); void GL_SelectProgram(int program);
#define GLSlang_SetUniform1i(uni, parm0) qglUniform1iARB(uni, parm0); #define GLSlang_UseProgram(prog) GL_SelectProgram(prog)
#define GLSlang_SetUniform1f(uni, parm0) qglUniform1fARB(uni, parm0); #define GLSlang_SetUniform1i(uni, parm0) qglUniform1iARB(uni, parm0)
#define GLSlang_DeleteObject(object) qglDeleteObjectARB(object); #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; extern FTEPFNGLLOCKARRAYSEXTPROC qglLockArraysEXT;

View file

@ -4148,9 +4148,7 @@ rendererinfo_t d3dfglrendererinfo = {
GLSCR_UpdateScreen, GLSCR_UpdateScreen,
/*backend*/ /*backend*/
NULL,
NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,

View file

@ -233,29 +233,48 @@ enum{
PERMUTATION_GENERIC = 0, PERMUTATION_GENERIC = 0,
PERMUTATION_BUMPMAP = 1, PERMUTATION_BUMPMAP = 1,
PERMUTATION_SPECULAR = 2, PERMUTATION_SPECULAR = 2,
PERMUTATION_BUMP_SPEC, PERMUTATION_FULLBRIGHT = 4,
PERMUTATION_OFFSET = 4, PERMUTATION_LOWER = 8,
PERMUTATION_OFFSET_BUMP, PERMUTATION_UPPER = 16,
PERMUTATION_OFFSET_SPEC, PERMUTATION_OFFSET = 32,
PERMUTATION_OFFSET_BUMP_SPEC,
PERMUTATIONS PERMUTATIONS = 64
}; };
typedef struct { typedef struct {
enum shaderprogparmtype_e { 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_ENTCOLOURS,
SP_TOPCOLOURS, SP_TOPCOLOURS,
SP_BOTTOMCOLOURS, SP_BOTTOMCOLOURS,
SP_TIME, 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_EYEPOS,
SP_ENTMATRIX, SP_ENTMATRIX,
SP_VIEWMATRIX,
SP_MODELMATRIX,
SP_MODELVIEWMATRIX,
SP_PROJECTIONMATRIX,
SP_MODELVIEWPROJECTIONMATRIX,
SP_RENDERTEXTURESCALE, /*multiplier for currentrender->texcoord*/ SP_RENDERTEXTURESCALE, /*multiplier for currentrender->texcoord*/
SP_LIGHTRADIUS, SP_LIGHTRADIUS, /*these light values are realtime lighting*/
SP_LIGHTCOLOUR, SP_LIGHTCOLOUR,
SP_LIGHTPOSITION, SP_LIGHTPOSITION,
@ -277,7 +296,10 @@ typedef struct {
}; };
} shaderprogparm_t; } shaderprogparm_t;
union programhandle_u
{
int glsl;
};
typedef struct { typedef struct {
float factor; float factor;
float unit; float unit;
@ -321,12 +343,11 @@ struct shader_s
SHADER_NODLIGHT = 1 << 15, //from surfaceflags SHADER_NODLIGHT = 1 << 15, //from surfaceflags
SHADER_HASLIGHTMAP = 1 << 16, 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; } flags;
union { union programhandle_u programhandle[PERMUTATIONS];
int glsl;
} programhandle[PERMUTATIONS];
int numprogparams; int numprogparams;
shaderprogparm_t progparm[SHADER_PROGPARMS_MAX]; shaderprogparm_t progparm[SHADER_PROGPARMS_MAX];