1
0
Fork 0
forked from fte/fteqw

support for gl4 tesselation shaders. glsl code is available separately.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4786 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-11-05 05:39:24 +00:00
parent 98ec171f17
commit 5a33efb14e
11 changed files with 226 additions and 120 deletions

View file

@ -499,7 +499,7 @@ void M_Menu_Audio_f (void)
MB_SLIDER("Ambient Volume", ambient_level, 0, 1, 0.1, NULL),
MB_SLIDER("Ambient Fade", ambient_fade, 0, 1000, 1, NULL),
MB_CHECKBOXCVAR("Static Sounds", cl_staticsounds, 0),
MB_SLIDER("CD Music Volume", bgmvolume, 0, 1, 0.1, NULL),
MB_SLIDER("Music Volume", bgmvolume, 0, 1, 0.1, NULL),
// removed music buffer
// removed precache
// removed eax2

View file

@ -215,8 +215,8 @@ cvar_t vid_multisample = CVARF ("vid_multisample", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t vid_refreshrate = CVARF ("vid_displayfrequency", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t vid_srgb = CVARF ("vid_srgb", "0",
CVAR_ARCHIVE);
cvar_t vid_srgb = CVARFD ("vid_srgb", "0",
CVAR_ARCHIVE, "The framebuffer should use sRGB colourspace. This has the effect of brightening the screen");
cvar_t vid_wndalpha = CVAR ("vid_wndalpha", "1");
//more readable defaults to match conwidth/conheight.
cvar_t vid_width = CVARFD ("vid_width", "0",

View file

@ -895,11 +895,19 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
/*if you're sending sound, you should be prepared to accept others yelling at you to shut up*/
if (snd_voip_play.value <= 0)
voipsendenable = false;
/*don't send sound if its not supported. that'll break stuff*/
if (!(cls.fteprotocolextensions2 & PEXT2_VOICECHAT))
voipsendenable = false;
}
else
{
/*we're not sending it to a server. the above considerations don't matter*/
voipsendenable = snd_voip_test.ival;
}
/*don't send sound if mic volume won't send anything anyway*/
if (micamp <= 0)
voipsendenable = false;
if (rtpstream)
{
voipsendenable = true;

View file

@ -684,7 +684,7 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
(shader->defaulttextures.upperoverlay && (shader->defaulttextures.upperoverlay->status == TEX_LOADING || shader->defaulttextures.upperoverlay->status == TEX_LOADED)))
return shader;
}
if (shader->prog && shader->prog->permu[PERMUTATION_UPPERLOWER].handle.glsl && !h2playertranslations)
if (shader->prog && shader->prog->permu[PERMUTATION_UPPERLOWER].handle.glsl.handle && !h2playertranslations)
{ //this shader can do permutations. this means we can generate only a black image, with separate top+bottom textures.
tc = 0xfe000000;
bc = 0xfe000000;
@ -1402,7 +1402,7 @@ void R_GAlias_DrawBatch(batch_t *batch)
{
if (batch->surf_first == surfnum)
{
/*needrecolour =*/ Alias_GAliasBuildMesh(&mesh, &batch->vbo, inf, surfnum, e, batch->shader->prog && batch->shader->prog->permu[PERMUTATION_SKELETAL].handle.glsl);
/*needrecolour =*/ Alias_GAliasBuildMesh(&mesh, &batch->vbo, inf, surfnum, e, batch->shader->prog && batch->shader->prog->permu[PERMUTATION_SKELETAL].handle.glsl.handle);
batch->mesh = &meshl;
return;
}

View file

@ -81,7 +81,7 @@ struct {
const shader_t *crepopaqueshader;
const shader_t *depthonlyshader;
GLhandleARB allblackshader;
union programhandle_u allblackshader;
int allblack_mvp;
qboolean initeddepthnorm;
@ -99,6 +99,7 @@ struct {
texid_t tex_refractiondepth; /*the (culled) underwater view*/
texid_t tex_ripplemap; /*temp image for waves and things.*/
int curpatchverts;
qboolean force2d;
int currenttmu;
int blendmode[SHADER_TMU_MAX];
@ -209,6 +210,12 @@ static void BE_PolyOffset(qboolean pushdepth)
po.factor += r_polygonoffset_submodel_factor.value;
po.unit += r_polygonoffset_submodel_offset.value;
}
if (shaderstate.mode == BEM_DEPTHONLY)
{
extern cvar_t r_polygonoffset_shadowmap_offset, r_polygonoffset_shadowmap_factor;
po.factor += r_polygonoffset_shadowmap_factor.value;
po.unit += r_polygonoffset_shadowmap_offset.value;
}
#ifndef FORCESTATE
if (shaderstate.curpolyoffset.factor != po.factor || shaderstate.curpolyoffset.unit != po.unit)
@ -861,19 +868,19 @@ void GLBE_RenderShadowBuffer(unsigned int numverts, int vbo, vecV_t *verts, unsi
GLBE_PolyOffsetShadowMap(false);
if (shaderstate.allblackshader)
if (shaderstate.allblackshader.glsl.handle)
{
GL_SelectProgram(shaderstate.allblackshader);
GL_SelectProgram(shaderstate.allblackshader.glsl.handle);
BE_EnableShaderAttributes(gl_config_nofixedfunc?(1u<<VATTR_VERTEX1):(1u<<VATTR_LEG_VERTEX), 0);
if (shaderstate.allblackshader != shaderstate.lastuniform && shaderstate.allblack_mvp != -1)
if (shaderstate.allblackshader.glsl.handle != shaderstate.lastuniform && shaderstate.allblack_mvp != -1)
{
float m16[16];
Matrix4_Multiply(r_refdef.m_projection, shaderstate.modelviewmatrix, m16);
qglUniformMatrix4fvARB(shaderstate.allblack_mvp, 1, false, m16);
}
shaderstate.lastuniform = shaderstate.allblackshader;
shaderstate.lastuniform = shaderstate.allblackshader.glsl.handle;
GL_SelectEBO(ibo);
qglDrawRangeElements(GL_TRIANGLES, 0, numverts, numindicies, GL_INDEX_TYPE, indicies);
@ -2694,12 +2701,27 @@ static void BE_SendPassBlendDepthMask(unsigned int sbits)
#endif
}
static void BE_SubmitMeshChain(void)
#define GL_PATCHES_ARB 0xe
static void BE_SubmitMeshChain(qboolean usetesselation)
{
int startv, starti, endv, endi;
int m;
mesh_t *mesh;
int batchtype = (shaderstate.flags & BEF_LINES)?GL_LINES:GL_TRIANGLES;
int batchtype;
if (usetesselation)
{
m = (shaderstate.flags & BEF_LINES)?2:3;
if (shaderstate.curpatchverts != m)
{
shaderstate.curpatchverts = m;
#define GL_PATCH_VERTICES 0x8E72
qglPatchParameteriARB(GL_PATCH_VERTICES, m);
}
batchtype = GL_PATCHES_ARB;
}
else
batchtype = (shaderstate.flags & BEF_LINES)?GL_LINES:GL_TRIANGLES;
if (!shaderstate.streamvbo[0]) //only if we're not forcing vbos elsewhere.
{
@ -2866,7 +2888,7 @@ static void DrawPass(const shaderpass_t *pass)
/*push it*/
BE_EnableShaderAttributes(attr, 0);
BE_SubmitMeshChain();
BE_SubmitMeshChain(false);
tmu = 0;
/*bind the light texture*/
@ -2905,7 +2927,7 @@ static void DrawPass(const shaderpass_t *pass)
shaderstate.lastpasstmus = tmu;
BE_EnableShaderAttributes(attr, 0);
BE_SubmitMeshChain();
BE_SubmitMeshChain(false);
tmu = 0;
BE_SendPassBlendDepthMask(pass[i+1].shaderbits);
@ -2924,7 +2946,7 @@ static void DrawPass(const shaderpass_t *pass)
shaderstate.lastpasstmus = tmu;
BE_EnableShaderAttributes(attr, 0);
BE_SubmitMeshChain();
BE_SubmitMeshChain(false);
}
#endif
@ -3264,37 +3286,37 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
perm = 0;
if (shaderstate.sourcevbo->numbones)
{
if (p->permu[perm|PERMUTATION_SKELETAL].handle.glsl)
if (p->permu[perm|PERMUTATION_SKELETAL].handle.glsl.handle)
perm |= PERMUTATION_SKELETAL;
else
return;
}
if (p->permu[perm|PERMUTATION_FRAMEBLEND].handle.glsl && shaderstate.sourcevbo->coord2.gl.addr)
if (p->permu[perm|PERMUTATION_FRAMEBLEND].handle.glsl.handle && shaderstate.sourcevbo->coord2.gl.addr)
perm |= PERMUTATION_FRAMEBLEND;
if (TEXLOADED(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].handle.glsl)
if (TEXLOADED(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].handle.glsl.handle)
perm |= PERMUTATION_BUMPMAP;
if (TEXLOADED(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].handle.glsl)
if (TEXLOADED(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].handle.glsl.handle)
perm |= PERMUTATION_FULLBRIGHT;
if ((TEXLOADED(shaderstate.curtexnums->loweroverlay) || TEXLOADED(shaderstate.curtexnums->upperoverlay)) && p->permu[perm|PERMUTATION_UPPERLOWER].handle.glsl)
if ((TEXLOADED(shaderstate.curtexnums->loweroverlay) || TEXLOADED(shaderstate.curtexnums->upperoverlay)) && p->permu[perm|PERMUTATION_UPPERLOWER].handle.glsl.handle)
perm |= PERMUTATION_UPPERLOWER;
if (r_refdef.globalfog.density && p->permu[perm|PERMUTATION_FOG].handle.glsl)
if (r_refdef.globalfog.density && p->permu[perm|PERMUTATION_FOG].handle.glsl.handle)
perm |= PERMUTATION_FOG;
if (p->permu[perm|PERMUTATION_DELUXE].handle.glsl && TEXLOADED(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe)
if (p->permu[perm|PERMUTATION_DELUXE].handle.glsl.handle && TEXLOADED(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe)
perm |= PERMUTATION_DELUXE;
#if MAXRLIGHTMAPS > 1
if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].handle.glsl)
if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].handle.glsl.handle)
perm |= PERMUTATION_LIGHTSTYLES;
#endif
GL_SelectProgram(p->permu[perm].handle.glsl);
GL_SelectProgram(p->permu[perm].handle.glsl.handle);
#ifndef FORCESTATE
if (shaderstate.lastuniform == p->permu[perm].handle.glsl)
if (shaderstate.lastuniform == p->permu[perm].handle.glsl.handle)
i = true;
else
#endif
{
i = false;
shaderstate.lastuniform = p->permu[perm].handle.glsl;
shaderstate.lastuniform = p->permu[perm].handle.glsl.handle;
}
BE_Program_Set_Attributes(p, perm, i);
@ -3347,7 +3369,7 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
shaderstate.lastpasstmus = pass->numMergedPasses;
}
}
BE_SubmitMeshChain();
BE_SubmitMeshChain(p->permu[perm].handle.glsl.usetesselation);
}
qboolean GLBE_LightCullModel(vec3_t org, model_t *model)
@ -3408,11 +3430,11 @@ void GLBE_SelectMode(backendmode_t mode)
}
else
#endif
if (!shaderstate.allblackshader)
if (!shaderstate.allblackshader.glsl.handle)
{
const char *defs[] = {NULL};
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader, "m_modelviewprojection");
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", NULL, NULL, "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader.glsl.handle, "m_modelviewprojection");
}
/*BEM_DEPTHONLY does support mesh writing, but its not the only way its used... FIXME!*/
while(shaderstate.lastpasstmus>0)
@ -3433,11 +3455,11 @@ void GLBE_SelectMode(backendmode_t mode)
/*BEM_STENCIL doesn't support mesh writing*/
GLBE_PolyOffsetStencilShadow(false);
if (gl_config_nofixedfunc && !shaderstate.allblackshader)
if (gl_config_nofixedfunc && !shaderstate.allblackshader.glsl.handle)
{
const char *defs[] = {NULL};
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader, "m_modelviewprojection");
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", NULL, NULL, "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader.glsl.handle, "m_modelviewprojection");
}
//disable all tmus
@ -3784,7 +3806,7 @@ static void BE_LegacyLighting(void)
GL_DeSelectProgram();
BE_EnableShaderAttributes(attr, 0);
BE_SubmitMeshChain();
BE_SubmitMeshChain(false);
GL_LazyBind(1, 0, r_nulltex);
GL_LazyBind(2, 0, r_nulltex);
@ -3904,7 +3926,7 @@ static void DrawMeshes(void)
#pragma warningmsg("fixme: support alpha test")
#endif
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX), 0);
BE_SubmitMeshChain();
BE_SubmitMeshChain(false); //fixme: dangerous
}
break;
@ -3914,7 +3936,7 @@ static void DrawMeshes(void)
GenerateTCFog(0, NULL);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX), 0);
BE_SubmitMeshChain();
BE_SubmitMeshChain(false);
#endif
break;
@ -3943,32 +3965,32 @@ static void DrawMeshes(void)
BE_SendPassBlendDepthMask((shaderstate.curshader->passes[0].shaderbits & ~SBITS_BLEND_BITS) | SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | SBITS_MISC_NODEPTHTEST);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR), 0);
BE_SubmitMeshChain();
BE_SubmitMeshChain(false);
break;
case BEM_DEPTHDARK:
if ((shaderstate.curshader->flags & SHADER_HASLIGHTMAP) && !TEXVALID(shaderstate.curtexnums->fullbright))
{
if (gl_config.arb_shader_objects)
{
if (!shaderstate.allblackshader)
if (!shaderstate.allblackshader.glsl.handle)
{
const char *defs[] = {NULL};
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader, "m_modelviewprojection");
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", NULL, NULL, "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader.glsl.handle, "m_modelviewprojection");
}
GL_SelectProgram(shaderstate.allblackshader);
GL_SelectProgram(shaderstate.allblackshader.glsl.handle);
BE_SendPassBlendDepthMask(shaderstate.curshader->passes[0].shaderbits);
BE_EnableShaderAttributes(gl_config_nofixedfunc?(1u<<VATTR_VERTEX1):(1u<<VATTR_LEG_VERTEX), 0);
if (shaderstate.allblackshader != shaderstate.lastuniform && shaderstate.allblack_mvp != -1)
if (shaderstate.allblackshader.glsl.handle != shaderstate.lastuniform && shaderstate.allblack_mvp != -1)
{
float m16[16];
Matrix4_Multiply(r_refdef.m_projection, shaderstate.modelviewmatrix, m16);
qglUniformMatrix4fvARB(shaderstate.allblack_mvp, 1, false, m16);
}
BE_SubmitMeshChain();
BE_SubmitMeshChain(shaderstate.allblackshader.glsl.usetesselation);
shaderstate.lastuniform = shaderstate.allblackshader;
shaderstate.lastuniform = shaderstate.allblackshader.glsl.handle;
break;
}
#ifndef GLSLONLY
@ -3987,7 +4009,7 @@ static void DrawMeshes(void)
BE_SendPassBlendDepthMask(shaderstate.curshader->passes[0].shaderbits);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR), 0);
BE_SubmitMeshChain();
BE_SubmitMeshChain(false);
break;
}
#endif
@ -4039,7 +4061,7 @@ static void DrawMeshes(void)
GenerateTCFog(0, shaderstate.curbatch->fog);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR) | (1u<<VATTR_LEG_TMU0), 0);
BE_SubmitMeshChain();
BE_SubmitMeshChain(false);
}
break;
#endif

View file

@ -78,19 +78,19 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int
{
vbo->indicies.gl.vbo = vbos[1];
vbo->indicies.gl.addr = (index_t*)((char*)vbo->indicies.gl.addr - (char*)edata);
vaostatic |= VATTR_LEG_ELEMENTS;
vaostatic |= 1u<<VATTR_LEG_ELEMENTS;
}
if (vbo->coord.gl.addr)
{
vbo->coord.gl.vbo = vbos[0];
vbo->coord.gl.addr = (vecV_t*)((char*)vbo->coord.gl.addr - (char*)vdata);
vaostatic |= VATTR_VERTEX1;
vaostatic |= 1u<<VATTR_VERTEX1;
}
if (vbo->texcoord.gl.addr)
{
vbo->texcoord.gl.vbo = vbos[0];
vbo->texcoord.gl.addr = (vec2_t*)((char*)vbo->texcoord.gl.addr - (char*)vdata);
vaostatic |= VATTR_TEXCOORD;
vaostatic |= 1u<<VATTR_TEXCOORD;
}
for (s = 0; s < MAXRLIGHTMAPS; s++)
{
@ -100,11 +100,11 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int
vbo->colours[s].gl.addr = (vec4_t*)((char*)vbo->colours[s].gl.addr - (char*)vdata);
switch(s)
{
default: vaostatic |= VATTR_COLOUR; break;
default: vaostatic |= 1u<<VATTR_COLOUR; break;
#if MAXRLIGHTMAPS > 1
case 1: vaostatic |= VATTR_COLOUR2; break;
case 2: vaostatic |= VATTR_COLOUR3; break;
case 3: vaostatic |= VATTR_COLOUR4; break;
case 1: vaostatic |= 1u<<VATTR_COLOUR2; break;
case 2: vaostatic |= 1u<<VATTR_COLOUR3; break;
case 3: vaostatic |= 1u<<VATTR_COLOUR4; break;
#endif
}
}
@ -114,11 +114,11 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int
vbo->lmcoord[s].gl.addr = (vec2_t*)((char*)vbo->lmcoord[s].gl.addr - (char*)vdata);
switch(s)
{
default: vaostatic |= VATTR_LMCOORD; break;
default: vaostatic |= 1u<<VATTR_LMCOORD; break;
#if MAXRLIGHTMAPS > 1
case 1: vaostatic |= VATTR_LMCOORD2; break;
case 2: vaostatic |= VATTR_LMCOORD3; break;
case 3: vaostatic |= VATTR_LMCOORD4; break;
case 1: vaostatic |= 1u<<VATTR_LMCOORD2; break;
case 2: vaostatic |= 1u<<VATTR_LMCOORD3; break;
case 3: vaostatic |= 1u<<VATTR_LMCOORD4; break;
#endif
}
}
@ -127,19 +127,19 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int
{
vbo->normals.gl.vbo = vbos[0];
vbo->normals.gl.addr = (vec3_t*)((char*)vbo->normals.gl.addr - (char*)vdata);
vaostatic |= VATTR_NORMALS;
vaostatic |= 1u<<VATTR_NORMALS;
}
if (vbo->svector.gl.addr)
{
vbo->svector.gl.vbo = vbos[0];
vbo->svector.gl.addr = (vec3_t*)((char*)vbo->svector.gl.addr - (char*)vdata);
vaostatic |= VATTR_SNORMALS;
vaostatic |= 1u<<VATTR_SNORMALS;
}
if (vbo->tvector.gl.addr)
{
vbo->tvector.gl.vbo = vbos[0];
vbo->tvector.gl.addr = (vec3_t*)((char*)vbo->tvector.gl.addr - (char*)vdata);
vaostatic |= VATTR_TNORMALS;
vaostatic |= 1u<<VATTR_TNORMALS;
}

View file

@ -1783,11 +1783,11 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
prog->parm[prog->numparams].type = parmtype;
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->permu[p].handle.glsl)
if (!prog->permu[p].handle.glsl.handle)
continue;
GLSlang_UseProgram(prog->permu[p].handle.glsl);
GLSlang_UseProgram(prog->permu[p].handle.glsl.handle);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl, token);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, token);
prog->permu[p].parm[prog->numparams] = uniformloc;
if (uniformloc != -1)

View file

@ -220,6 +220,8 @@ int mtexid0;
FTEPFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
FTEPFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
void (APIENTRY *qglPatchParameteriARB)(GLenum pname, GLint value); //core in gl4
//stencil shadowing
FTEPFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT;
@ -742,6 +744,13 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglPNTrianglesfATI = (void *)getglext("glPNTrianglesfATI");
qglPNTrianglesiATI = (void *)getglext("glPNTrianglesiATI");
}
if (!gl_config.gles && gl_config.glversion >= 4.0)
qglPatchParameteriARB = getglext("glPatchParameteri");
else if (GL_CheckExtension("GL_ARB_tessellation_shader"))
qglPatchParameteriARB = getglext("glPatchParameteriARB");
else
qglPatchParameteriARB = NULL;
#ifndef GL_STATIC
if (GL_CheckExtension("GL_EXT_texture_object"))
@ -1207,9 +1216,12 @@ static const char *glsl_hdrs[] =
"uniform float cvar_r_glsl_offsetmapping_scale;\n"
"vec2 offsetmap(sampler2D normtex, vec2 base, vec3 eyevector)\n"
"{\n"
"#if !defined(OFFSETMAPPING_SCALE)\n"
"#define OFFSETMAPPING_SCALE 1.0\n"
"#endif\n"
"#if defined(RELIEFMAPPING) && !defined(GL_ES)\n"
"float i, f;\n"
"vec3 OffsetVector = vec3(normalize(eyevector.xyz).xy * cvar_r_glsl_offsetmapping_scale * vec2(-1.0, 1.0), -1.0);\n"
"vec3 OffsetVector = vec3(normalize(eyevector.xyz).xy * cvar_r_glsl_offsetmapping_scale * OFFSETMAPPING_SCALE * vec2(-1.0, 1.0), -1.0);\n"
"vec3 RT = vec3(vec2(base.xy"/* - OffsetVector.xy*OffsetMapping_Bias*/"), 1.0);\n"
"OffsetVector /= 10.0;\n"
"for(i = 1.0; i < 10.0; ++i)\n"
@ -1218,7 +1230,7 @@ static const char *glsl_hdrs[] =
"RT += OffsetVector * (step(texture2D(normtex, RT.xy).a, RT.z) * f - 0.5 * f);\n"
"return RT.xy;\n"
"#elif defined(OFFSETMAPPING)\n"
"vec2 OffsetVector = normalize(eyevector).xy * cvar_r_glsl_offsetmapping_scale * vec2(-1.0, 1.0);\n"
"vec2 OffsetVector = normalize(eyevector).xy * cvar_r_glsl_offsetmapping_scale * OFFSETMAPPING_SCALE * vec2(-1.0, 1.0);\n"
"vec2 tc = base;\n"
"tc += OffsetVector;\n"
"OffsetVector *= 0.333;\n"
@ -1426,6 +1438,9 @@ static GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char *
int strings = 0;
char verline[64];
if (!shadersource)
return 0;
if (ver)
{
/*required version not supported, don't even try*/
@ -1471,6 +1486,16 @@ static GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char *
strings++;
}
break;
case GL_TESS_CONTROL_SHADER_ARB:
prstrings[strings] = "#define TESS_CONTROL_SHADER\n";
length[strings] = strlen(prstrings[strings]);
strings++;
break;
case GL_TESS_EVALUATION_SHADER_ARB:
prstrings[strings] = "#define TESS_EVALUATION_SHADER\n";
length[strings] = strlen(prstrings[strings]);
strings++;
break;
case GL_VERTEX_SHADER_ARB:
prstrings[strings] = "#define VERTEX_SHADER\n";
length[strings] = strlen(prstrings[strings]);
@ -1487,12 +1512,28 @@ static GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char *
length[strings] = strlen(prstrings[strings]);
strings++;
}
if (gl_config.nofixedfunc)
if (ver < 140)
{
prstrings[strings] =
"attribute vec3 v_position1;\n"
"#define in attribute\n"
"#define out varying\n"
;
}
else
{
prstrings[strings] =
"#define attribute in\n"
"#define varying out\n"
;
length[strings] = strlen(prstrings[strings]);
strings++;
}
if (gl_config.nofixedfunc || ver >= 140)
{
prstrings[strings] =
"in vec3 v_position1;\n"
"#ifdef FRAMEBLEND\n"
"attribute vec3 v_position2;\n"
"in vec3 v_position2;\n"
"uniform vec2 e_vblend;\n"
"#define v_position ((v_position1*e_vblend.x)+(v_position2*e_vblend.y))\n"
"#else\n"
@ -1509,7 +1550,7 @@ static GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char *
{
prstrings[strings] =
"#ifdef FRAMEBLEND\n"
"attribute vec3 v_position2;\n"
"in vec3 v_position2;\n"
"uniform vec2 e_vblend;\n"
"#define v_position (gl_Vertex.xyz*e_vblend.x+v_position2*e_vblend.y)\n"
"uniform mat4 m_modelviewprojection;\n"
@ -1593,6 +1634,12 @@ static GLhandleARB GLSlang_FinishShader(GLhandleARB shader, const char *name, GL
case GL_VERTEX_SHADER_ARB:
typedesc = "Vertex";
break;
case GL_TESS_CONTROL_SHADER_ARB:
typedesc = "Tesselation Control";
break;
case GL_TESS_EVALUATION_SHADER_ARB:
typedesc = "Tesselation Evaluation";
break;
default:
typedesc = "???";
break;
@ -1633,13 +1680,15 @@ static GLhandleARB GLSlang_FinishShader(GLhandleARB shader, const char *name, GL
return shader;
}
GLhandleARB GLSlang_CreateProgramObject (const char *name, GLhandleARB vert, GLhandleARB frag, qboolean silent)
GLhandleARB GLSlang_CreateProgramObject (const char *name, GLhandleARB vert, GLhandleARB cont, GLhandleARB eval, GLhandleARB frag, qboolean silent)
{
GLhandleARB program;
program = qglCreateProgramObjectARB();
qglAttachObjectARB(program, vert);
qglAttachObjectARB(program, frag);
if (vert) qglAttachObjectARB(program, vert);
if (cont) qglAttachObjectARB(program, cont);
if (eval) qglAttachObjectARB(program, eval);
if (frag) qglAttachObjectARB(program, frag);
qglBindAttribLocationARB(program, VATTR_VERTEX1, "v_position1");
qglBindAttribLocationARB(program, VATTR_COLOUR, "v_colour");
@ -1666,108 +1715,124 @@ GLhandleARB GLSlang_CreateProgramObject (const char *name, GLhandleARB vert, GLh
return program;
}
GLhandleARB GLSlang_ValidateProgram(GLhandleARB program, const char *name, qboolean silent, vfsfile_t *blobfile)
qboolean GLSlang_ValidateProgram(union programhandle_u *h, const char *name, qboolean silent, vfsfile_t *blobfile)
{
char str[2048];
char *nullconstants = NULL;
GLint linked;
if (!program)
return (GLhandleARB)0;
qglGetProgramParameteriv_(program, GL_OBJECT_LINK_STATUS_ARB, &linked);
if (!h->glsl.handle)
return false;
qglGetProgramParameteriv_(h->glsl.handle, GL_OBJECT_LINK_STATUS_ARB, &linked);
if(!linked)
{
if (!silent)
{
qglGetProgramInfoLog_(program, sizeof(str), NULL, str);
qglGetProgramInfoLog_(h->glsl.handle, sizeof(str), NULL, str);
Con_Printf("Program link error on glsl program %s:\n%s\n", name, str);
}
qglDeleteProgramObject_(program);
qglDeleteProgramObject_(h->glsl.handle);
h->glsl.handle = 0;
return (GLhandleARB)0;
}
if (program && blobfile && qglGetProgramBinary)
if (h->glsl.handle && blobfile && qglGetProgramBinary)
{
GLuint ui;
GLenum e;
unsigned int len, fmt;
void *blobdata;
qglGetProgramParameteriv_(program, GL_PROGRAM_BINARY_LENGTH, &ui);
qglGetProgramParameteriv_(h->glsl.handle, GL_PROGRAM_BINARY_LENGTH, &ui);
len = ui;
blobdata = BZ_Malloc(len);
qglGetProgramBinary(program, len, NULL, &e, blobdata);
qglGetProgramBinary(h->glsl.handle, len, NULL, &e, blobdata);
fmt = e;
VFS_WRITE(blobfile, &fmt, sizeof(fmt));
VFS_WRITE(blobfile, &len, sizeof(len));
VFS_WRITE(blobfile, blobdata, len);
VFS_WRITE(blobfile, &h->glsl.usetesselation, sizeof(h->glsl.usetesselation));
BZ_Free(blobdata);
}
return program;
return true;
}
GLhandleARB GLSlang_CreateProgram(const char *name, int ver, const char **precompilerconstants, const char *vert, const char *frag, qboolean silent, vfsfile_t *blobfile)
union programhandle_u GLSlang_CreateProgram(const char *name, int ver, const char **precompilerconstants, const char *vert, const char *cont, const char *eval, const char *frag, qboolean silent, vfsfile_t *blobfile)
{
GLhandleARB handle;
union programhandle_u ret;
GLhandleARB vs;
GLhandleARB fs;
GLhandleARB cs;
GLhandleARB es;
const char *nullconstants = NULL;
memset(&ret, 0, sizeof(ret));
if (!gl_config.arb_shader_objects)
return 0;
return ret;
if ((cont || frag) && !qglPatchParameteriARB)
return ret;
if (!precompilerconstants)
precompilerconstants = &nullconstants;
fs = GLSlang_CreateShader(name, ver, precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB, silent);
vs = GLSlang_CreateShader(name, ver, precompilerconstants, vert, GL_VERTEX_SHADER_ARB, silent);
cs = GLSlang_CreateShader(name, ver, precompilerconstants, cont, GL_TESS_CONTROL_SHADER_ARB, silent);
es = GLSlang_CreateShader(name, ver, precompilerconstants, eval, GL_TESS_EVALUATION_SHADER_ARB, silent);
fs = GLSlang_FinishShader(fs, name, GL_FRAGMENT_SHADER_ARB, silent);
vs = GLSlang_FinishShader(vs, name, GL_VERTEX_SHADER_ARB, silent);
cs = GLSlang_FinishShader(cs, name, GL_TESS_CONTROL_SHADER_ARB, silent);
es = GLSlang_FinishShader(es, name, GL_TESS_EVALUATION_SHADER_ARB, silent);
if (!vs || !fs)
handle = 0;
ret.glsl.handle = 0;
else
handle = GLSlang_CreateProgramObject(name, vs, fs, silent);
ret.glsl.handle = GLSlang_CreateProgramObject(name, vs, cs, es, fs, silent);
//delete ignores 0s.
qglDeleteShaderObject_(vs);
qglDeleteShaderObject_(fs);
if (vs) qglDeleteShaderObject_(vs);
if (fs) qglDeleteShaderObject_(fs);
if (cs) qglDeleteShaderObject_(cs);
if (es) qglDeleteShaderObject_(es);
checkglerror();
if (handle && blobfile && qglGetProgramBinary)
if (ret.glsl.handle && blobfile && qglGetProgramBinary)
{
GLuint ui;
GLenum e;
unsigned int len, fmt;
void *blobdata;
qglGetProgramParameteriv_(handle, GL_PROGRAM_BINARY_LENGTH, &ui);
qglGetProgramParameteriv_(ret.glsl.handle, GL_PROGRAM_BINARY_LENGTH, &ui);
len = ui;
blobdata = BZ_Malloc(len);
qglGetProgramBinary(handle, len, NULL, &e, blobdata);
qglGetProgramBinary(ret.glsl.handle, len, NULL, &e, blobdata);
fmt = e;
VFS_WRITE(blobfile, &fmt, sizeof(fmt));
VFS_WRITE(blobfile, &len, sizeof(len));
VFS_WRITE(blobfile, blobdata, len);
VFS_WRITE(blobfile, &ret.glsl.usetesselation, sizeof(ret.glsl.usetesselation));
BZ_Free(blobdata);
}
return handle;
ret.glsl.usetesselation = (cont || eval);
return ret;
}
qboolean GLSlang_ValidateProgramPermu(program_t *prog, const char *name, unsigned int permu, qboolean noerrors, vfsfile_t *blobfile)
{
prog->permu[permu].handle.glsl = GLSlang_ValidateProgram(prog->permu[permu].handle.glsl, name, noerrors, blobfile);
return !!prog->permu[permu].handle.glsl;
return GLSlang_ValidateProgram(&prog->permu[permu].handle, name, noerrors, blobfile);
}
qboolean GLSlang_CreateProgramPermu(program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *frag, qboolean noerrors, vfsfile_t *blobfile)
{
@ -1777,8 +1842,8 @@ qboolean GLSlang_CreateProgramPermu(program_t *prog, const char *name, unsigned
if (permu & PERMUTATION_SKELETAL)
ver = 120;
}
prog->permu[permu].handle.glsl = GLSlang_CreateProgram(name, ver, precompilerconstants, vert, frag, noerrors, blobfile);
if (prog->permu[permu].handle.glsl)
prog->permu[permu].handle = GLSlang_CreateProgram(name, ver, precompilerconstants, vert, tcs, tes, frag, noerrors, blobfile);
if (prog->permu[permu].handle.glsl.handle)
return true;
return false;
}
@ -1805,26 +1870,27 @@ static qboolean GLSlang_LoadBlob(program_t *prog, const char *name, unsigned int
VFS_READ(blobfile, &length, sizeof(length));
binary = BZ_Malloc(length);
VFS_READ(blobfile, binary, length);
VFS_READ(blobfile, &prog->permu[permu].handle.glsl.usetesselation, sizeof(prog->permu[permu].handle.glsl.usetesselation));
prog->permu[permu].handle.glsl = qglCreateProgramObjectARB();
qglProgramBinary(prog->permu[permu].handle.glsl, fmt, binary, length);
prog->permu[permu].handle.glsl.handle = qglCreateProgramObjectARB();
qglProgramBinary(prog->permu[permu].handle.glsl.handle, fmt, binary, length);
BZ_Free(binary);
qglGetProgramParameteriv_(prog->permu[permu].handle.glsl, GL_OBJECT_LINK_STATUS_ARB, &success);
qglGetProgramParameteriv_(prog->permu[permu].handle.glsl.handle, GL_OBJECT_LINK_STATUS_ARB, &success);
if (!success)
{
qglDeleteProgramObject_(prog->permu[permu].handle.glsl);
prog->permu[permu].handle.glsl = 0;
qglDeleteProgramObject_(prog->permu[permu].handle.glsl.handle);
memset(&prog->permu[permu].handle, 0, sizeof(prog->permu[permu].handle));
}
return !!success;
}
static void GLSlang_DeleteProg(program_t *prog, unsigned int permu)
{
if (prog->permu[permu].handle.glsl)
if (prog->permu[permu].handle.glsl.handle)
{
qglDeleteProgramObject_(prog->permu[permu].handle.glsl);
prog->permu[permu].handle.glsl = 0;
qglDeleteProgramObject_(prog->permu[permu].handle.glsl.handle);
prog->permu[permu].handle.glsl.handle = 0;
}
}
@ -1841,12 +1907,12 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
//figure out visible attributes
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->permu[p].handle.glsl)
if (!prog->permu[p].handle.glsl.handle)
continue;
GLSlang_UseProgram(prog->permu[p].handle.glsl);
GLSlang_UseProgram(prog->permu[p].handle.glsl.handle);
for (i = 0; shader_attr_names[i].name; i++)
{
uniformloc = qglGetAttribLocationARB(prog->permu[p].handle.glsl, shader_attr_names[i].name);
uniformloc = qglGetAttribLocationARB(prog->permu[p].handle.glsl.handle, shader_attr_names[i].name);
if (uniformloc != -1)
{
if (shader_attr_names[i].ptype != uniformloc)
@ -1863,11 +1929,11 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
found = false;
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->permu[p].handle.glsl)
if (!prog->permu[p].handle.glsl.handle)
continue;
GLSlang_UseProgram(prog->permu[p].handle.glsl);
GLSlang_UseProgram(prog->permu[p].handle.glsl.handle);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl, shader_unif_names[i].name);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, shader_unif_names[i].name);
if (uniformloc != -1)
found = true;
@ -1911,11 +1977,11 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
for (p = 0; p < PERMUTATIONS; p++)
{
char uniformname[64];
if (!prog->permu[p].handle.glsl)
if (!prog->permu[p].handle.glsl.handle)
continue;
GL_SelectProgram(prog->permu[p].handle.glsl);
GL_SelectProgram(prog->permu[p].handle.glsl.handle);
Q_snprintfz(uniformname, sizeof(uniformname), "cvar_%s", tmpname);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl, uniformname);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, uniformname);
if (uniformloc != -1)
{
//qglUniform1fARB(uniformloc, cvar->value);
@ -1929,15 +1995,15 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
/*set texture uniforms*/
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->permu[p].handle.glsl)
if (!prog->permu[p].handle.glsl.handle)
continue;
if (!(prog->permu[p].attrmask & (1u<<VATTR_VERTEX1))) //a shader kinda has to use one of these...
prog->permu[p].attrmask |= (1u<<VATTR_LEG_VERTEX);
GLSlang_UseProgram(prog->permu[p].handle.glsl);
GLSlang_UseProgram(prog->permu[p].handle.glsl.handle);
for (i = 0; i < 8; i++)
{
Q_snprintfz(tmpname, sizeof(tmpname), "s_t%i", i);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl, tmpname);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, tmpname);
if (uniformloc != -1)
qglUniform1iARB(uniformloc, i);
}
@ -1948,7 +2014,7 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
void GL_Init(void *(*getglfunction) (char *name))
{
#ifndef GL_STATIC
qglBindTexture = (void *)getglcore("glBindTexture"); //for compleateness
qglBindTexture = (void *)getglcore("glBindTexture"); //for compleateness. core in 1.1. needed by fte.
qglBlendFunc = (void *)getglcore("glBlendFunc");
qglClear = (void *)getglcore("glClear");
qglClearColor = (void *)getglcore("glClearColor");

View file

@ -198,6 +198,7 @@ extern FTEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB;
extern FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB;
extern FTEPFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
extern FTEPFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
extern void (APIENTRY *qglPatchParameteriARB)(GLenum pname, GLint value); //core in gl4
qboolean GL_CheckExtension(char *extname);
@ -1061,7 +1062,7 @@ extern void (APIENTRY *qglBindVertexArray)(GLuint vaoarray);
//glslang helper api
GLhandleARB GLSlang_CreateProgram(const char *name, int ver, const char **precompilerconstants, const char *vert, const char *frag, qboolean silent, vfsfile_t *blobfile);
union programhandle_u GLSlang_CreateProgram(const char *name, int ver, const char **precompilerconstants, const char *vert, const char *cont, const char *eval, const char *frag, qboolean silent, vfsfile_t *blobfile);
GLint GLSlang_GetUniformLocation (int prog, char *name);
void GL_SelectProgram(int program);
#define GLSlang_UseProgram(prog) GL_SelectProgram(prog)

View file

@ -579,6 +579,11 @@ typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei
#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
#endif
#ifndef GL_ARB_vertex_shader
#define GL_TESS_EVALUATION_SHADER_ARB 0x8E87
#define GL_TESS_CONTROL_SHADER_ARB 0x8E88
#endif
#ifndef GL_ARB_fragment_shader
#define GL_FRAGMENT_SHADER_ARB 0x8B30
#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49

View file

@ -422,7 +422,11 @@ typedef struct {
union programhandle_u
{
int glsl;
struct
{
int handle;
qboolean usetesselation;
} glsl;
#ifdef D3DQUAKE
struct
{