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:
parent
98ec171f17
commit
5a33efb14e
11 changed files with 226 additions and 120 deletions
|
@ -499,7 +499,7 @@ void M_Menu_Audio_f (void)
|
||||||
MB_SLIDER("Ambient Volume", ambient_level, 0, 1, 0.1, NULL),
|
MB_SLIDER("Ambient Volume", ambient_level, 0, 1, 0.1, NULL),
|
||||||
MB_SLIDER("Ambient Fade", ambient_fade, 0, 1000, 1, NULL),
|
MB_SLIDER("Ambient Fade", ambient_fade, 0, 1000, 1, NULL),
|
||||||
MB_CHECKBOXCVAR("Static Sounds", cl_staticsounds, 0),
|
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 music buffer
|
||||||
// removed precache
|
// removed precache
|
||||||
// removed eax2
|
// removed eax2
|
||||||
|
|
|
@ -215,8 +215,8 @@ cvar_t vid_multisample = CVARF ("vid_multisample", "0",
|
||||||
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
|
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
|
||||||
cvar_t vid_refreshrate = CVARF ("vid_displayfrequency", "0",
|
cvar_t vid_refreshrate = CVARF ("vid_displayfrequency", "0",
|
||||||
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
|
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
|
||||||
cvar_t vid_srgb = CVARF ("vid_srgb", "0",
|
cvar_t vid_srgb = CVARFD ("vid_srgb", "0",
|
||||||
CVAR_ARCHIVE);
|
CVAR_ARCHIVE, "The framebuffer should use sRGB colourspace. This has the effect of brightening the screen");
|
||||||
cvar_t vid_wndalpha = CVAR ("vid_wndalpha", "1");
|
cvar_t vid_wndalpha = CVAR ("vid_wndalpha", "1");
|
||||||
//more readable defaults to match conwidth/conheight.
|
//more readable defaults to match conwidth/conheight.
|
||||||
cvar_t vid_width = CVARFD ("vid_width", "0",
|
cvar_t vid_width = CVARFD ("vid_width", "0",
|
||||||
|
|
|
@ -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 you're sending sound, you should be prepared to accept others yelling at you to shut up*/
|
||||||
if (snd_voip_play.value <= 0)
|
if (snd_voip_play.value <= 0)
|
||||||
voipsendenable = false;
|
voipsendenable = false;
|
||||||
|
/*don't send sound if its not supported. that'll break stuff*/
|
||||||
if (!(cls.fteprotocolextensions2 & PEXT2_VOICECHAT))
|
if (!(cls.fteprotocolextensions2 & PEXT2_VOICECHAT))
|
||||||
voipsendenable = false;
|
voipsendenable = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/*we're not sending it to a server. the above considerations don't matter*/
|
||||||
voipsendenable = snd_voip_test.ival;
|
voipsendenable = snd_voip_test.ival;
|
||||||
|
}
|
||||||
|
/*don't send sound if mic volume won't send anything anyway*/
|
||||||
|
if (micamp <= 0)
|
||||||
|
voipsendenable = false;
|
||||||
|
|
||||||
if (rtpstream)
|
if (rtpstream)
|
||||||
{
|
{
|
||||||
voipsendenable = true;
|
voipsendenable = true;
|
||||||
|
|
|
@ -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)))
|
(shader->defaulttextures.upperoverlay && (shader->defaulttextures.upperoverlay->status == TEX_LOADING || shader->defaulttextures.upperoverlay->status == TEX_LOADED)))
|
||||||
return shader;
|
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.
|
{ //this shader can do permutations. this means we can generate only a black image, with separate top+bottom textures.
|
||||||
tc = 0xfe000000;
|
tc = 0xfe000000;
|
||||||
bc = 0xfe000000;
|
bc = 0xfe000000;
|
||||||
|
@ -1402,7 +1402,7 @@ void R_GAlias_DrawBatch(batch_t *batch)
|
||||||
{
|
{
|
||||||
if (batch->surf_first == surfnum)
|
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;
|
batch->mesh = &meshl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ struct {
|
||||||
const shader_t *crepopaqueshader;
|
const shader_t *crepopaqueshader;
|
||||||
const shader_t *depthonlyshader;
|
const shader_t *depthonlyshader;
|
||||||
|
|
||||||
GLhandleARB allblackshader;
|
union programhandle_u allblackshader;
|
||||||
int allblack_mvp;
|
int allblack_mvp;
|
||||||
|
|
||||||
qboolean initeddepthnorm;
|
qboolean initeddepthnorm;
|
||||||
|
@ -99,6 +99,7 @@ struct {
|
||||||
texid_t tex_refractiondepth; /*the (culled) underwater view*/
|
texid_t tex_refractiondepth; /*the (culled) underwater view*/
|
||||||
texid_t tex_ripplemap; /*temp image for waves and things.*/
|
texid_t tex_ripplemap; /*temp image for waves and things.*/
|
||||||
|
|
||||||
|
int curpatchverts;
|
||||||
qboolean force2d;
|
qboolean force2d;
|
||||||
int currenttmu;
|
int currenttmu;
|
||||||
int blendmode[SHADER_TMU_MAX];
|
int blendmode[SHADER_TMU_MAX];
|
||||||
|
@ -209,6 +210,12 @@ static void BE_PolyOffset(qboolean pushdepth)
|
||||||
po.factor += r_polygonoffset_submodel_factor.value;
|
po.factor += r_polygonoffset_submodel_factor.value;
|
||||||
po.unit += r_polygonoffset_submodel_offset.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
|
#ifndef FORCESTATE
|
||||||
if (shaderstate.curpolyoffset.factor != po.factor || shaderstate.curpolyoffset.unit != po.unit)
|
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);
|
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);
|
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];
|
float m16[16];
|
||||||
Matrix4_Multiply(r_refdef.m_projection, shaderstate.modelviewmatrix, m16);
|
Matrix4_Multiply(r_refdef.m_projection, shaderstate.modelviewmatrix, m16);
|
||||||
qglUniformMatrix4fvARB(shaderstate.allblack_mvp, 1, false, m16);
|
qglUniformMatrix4fvARB(shaderstate.allblack_mvp, 1, false, m16);
|
||||||
}
|
}
|
||||||
shaderstate.lastuniform = shaderstate.allblackshader;
|
shaderstate.lastuniform = shaderstate.allblackshader.glsl.handle;
|
||||||
|
|
||||||
GL_SelectEBO(ibo);
|
GL_SelectEBO(ibo);
|
||||||
qglDrawRangeElements(GL_TRIANGLES, 0, numverts, numindicies, GL_INDEX_TYPE, indicies);
|
qglDrawRangeElements(GL_TRIANGLES, 0, numverts, numindicies, GL_INDEX_TYPE, indicies);
|
||||||
|
@ -2694,12 +2701,27 @@ static void BE_SendPassBlendDepthMask(unsigned int sbits)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BE_SubmitMeshChain(void)
|
#define GL_PATCHES_ARB 0xe
|
||||||
|
static void BE_SubmitMeshChain(qboolean usetesselation)
|
||||||
{
|
{
|
||||||
int startv, starti, endv, endi;
|
int startv, starti, endv, endi;
|
||||||
int m;
|
int m;
|
||||||
mesh_t *mesh;
|
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.
|
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*/
|
/*push it*/
|
||||||
BE_EnableShaderAttributes(attr, 0);
|
BE_EnableShaderAttributes(attr, 0);
|
||||||
BE_SubmitMeshChain();
|
BE_SubmitMeshChain(false);
|
||||||
tmu = 0;
|
tmu = 0;
|
||||||
|
|
||||||
/*bind the light texture*/
|
/*bind the light texture*/
|
||||||
|
@ -2905,7 +2927,7 @@ static void DrawPass(const shaderpass_t *pass)
|
||||||
shaderstate.lastpasstmus = tmu;
|
shaderstate.lastpasstmus = tmu;
|
||||||
BE_EnableShaderAttributes(attr, 0);
|
BE_EnableShaderAttributes(attr, 0);
|
||||||
|
|
||||||
BE_SubmitMeshChain();
|
BE_SubmitMeshChain(false);
|
||||||
tmu = 0;
|
tmu = 0;
|
||||||
|
|
||||||
BE_SendPassBlendDepthMask(pass[i+1].shaderbits);
|
BE_SendPassBlendDepthMask(pass[i+1].shaderbits);
|
||||||
|
@ -2924,7 +2946,7 @@ static void DrawPass(const shaderpass_t *pass)
|
||||||
shaderstate.lastpasstmus = tmu;
|
shaderstate.lastpasstmus = tmu;
|
||||||
BE_EnableShaderAttributes(attr, 0);
|
BE_EnableShaderAttributes(attr, 0);
|
||||||
|
|
||||||
BE_SubmitMeshChain();
|
BE_SubmitMeshChain(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3264,37 +3286,37 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
|
||||||
perm = 0;
|
perm = 0;
|
||||||
if (shaderstate.sourcevbo->numbones)
|
if (shaderstate.sourcevbo->numbones)
|
||||||
{
|
{
|
||||||
if (p->permu[perm|PERMUTATION_SKELETAL].handle.glsl)
|
if (p->permu[perm|PERMUTATION_SKELETAL].handle.glsl.handle)
|
||||||
perm |= PERMUTATION_SKELETAL;
|
perm |= PERMUTATION_SKELETAL;
|
||||||
else
|
else
|
||||||
return;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
perm |= PERMUTATION_DELUXE;
|
||||||
#if MAXRLIGHTMAPS > 1
|
#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;
|
perm |= PERMUTATION_LIGHTSTYLES;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GL_SelectProgram(p->permu[perm].handle.glsl);
|
GL_SelectProgram(p->permu[perm].handle.glsl.handle);
|
||||||
#ifndef FORCESTATE
|
#ifndef FORCESTATE
|
||||||
if (shaderstate.lastuniform == p->permu[perm].handle.glsl)
|
if (shaderstate.lastuniform == p->permu[perm].handle.glsl.handle)
|
||||||
i = true;
|
i = true;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
i = false;
|
i = false;
|
||||||
shaderstate.lastuniform = p->permu[perm].handle.glsl;
|
shaderstate.lastuniform = p->permu[perm].handle.glsl.handle;
|
||||||
}
|
}
|
||||||
BE_Program_Set_Attributes(p, perm, i);
|
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;
|
shaderstate.lastpasstmus = pass->numMergedPasses;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BE_SubmitMeshChain();
|
BE_SubmitMeshChain(p->permu[perm].handle.glsl.usetesselation);
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean GLBE_LightCullModel(vec3_t org, model_t *model)
|
qboolean GLBE_LightCullModel(vec3_t org, model_t *model)
|
||||||
|
@ -3408,11 +3430,11 @@ void GLBE_SelectMode(backendmode_t mode)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (!shaderstate.allblackshader)
|
if (!shaderstate.allblackshader.glsl.handle)
|
||||||
{
|
{
|
||||||
const char *defs[] = {NULL};
|
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.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, "m_modelviewprojection");
|
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!*/
|
/*BEM_DEPTHONLY does support mesh writing, but its not the only way its used... FIXME!*/
|
||||||
while(shaderstate.lastpasstmus>0)
|
while(shaderstate.lastpasstmus>0)
|
||||||
|
@ -3433,11 +3455,11 @@ void GLBE_SelectMode(backendmode_t mode)
|
||||||
/*BEM_STENCIL doesn't support mesh writing*/
|
/*BEM_STENCIL doesn't support mesh writing*/
|
||||||
GLBE_PolyOffsetStencilShadow(false);
|
GLBE_PolyOffsetStencilShadow(false);
|
||||||
|
|
||||||
if (gl_config_nofixedfunc && !shaderstate.allblackshader)
|
if (gl_config_nofixedfunc && !shaderstate.allblackshader.glsl.handle)
|
||||||
{
|
{
|
||||||
const char *defs[] = {NULL};
|
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.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, "m_modelviewprojection");
|
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader.glsl.handle, "m_modelviewprojection");
|
||||||
}
|
}
|
||||||
|
|
||||||
//disable all tmus
|
//disable all tmus
|
||||||
|
@ -3784,7 +3806,7 @@ static void BE_LegacyLighting(void)
|
||||||
GL_DeSelectProgram();
|
GL_DeSelectProgram();
|
||||||
BE_EnableShaderAttributes(attr, 0);
|
BE_EnableShaderAttributes(attr, 0);
|
||||||
|
|
||||||
BE_SubmitMeshChain();
|
BE_SubmitMeshChain(false);
|
||||||
|
|
||||||
GL_LazyBind(1, 0, r_nulltex);
|
GL_LazyBind(1, 0, r_nulltex);
|
||||||
GL_LazyBind(2, 0, r_nulltex);
|
GL_LazyBind(2, 0, r_nulltex);
|
||||||
|
@ -3904,7 +3926,7 @@ static void DrawMeshes(void)
|
||||||
#pragma warningmsg("fixme: support alpha test")
|
#pragma warningmsg("fixme: support alpha test")
|
||||||
#endif
|
#endif
|
||||||
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX), 0);
|
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX), 0);
|
||||||
BE_SubmitMeshChain();
|
BE_SubmitMeshChain(false); //fixme: dangerous
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3914,7 +3936,7 @@ static void DrawMeshes(void)
|
||||||
|
|
||||||
GenerateTCFog(0, NULL);
|
GenerateTCFog(0, NULL);
|
||||||
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX), 0);
|
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX), 0);
|
||||||
BE_SubmitMeshChain();
|
BE_SubmitMeshChain(false);
|
||||||
#endif
|
#endif
|
||||||
break;
|
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_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_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR), 0);
|
||||||
BE_SubmitMeshChain();
|
BE_SubmitMeshChain(false);
|
||||||
break;
|
break;
|
||||||
case BEM_DEPTHDARK:
|
case BEM_DEPTHDARK:
|
||||||
if ((shaderstate.curshader->flags & SHADER_HASLIGHTMAP) && !TEXVALID(shaderstate.curtexnums->fullbright))
|
if ((shaderstate.curshader->flags & SHADER_HASLIGHTMAP) && !TEXVALID(shaderstate.curtexnums->fullbright))
|
||||||
{
|
{
|
||||||
if (gl_config.arb_shader_objects)
|
if (gl_config.arb_shader_objects)
|
||||||
{
|
{
|
||||||
if (!shaderstate.allblackshader)
|
if (!shaderstate.allblackshader.glsl.handle)
|
||||||
{
|
{
|
||||||
const char *defs[] = {NULL};
|
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.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, "m_modelviewprojection");
|
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_SendPassBlendDepthMask(shaderstate.curshader->passes[0].shaderbits);
|
||||||
BE_EnableShaderAttributes(gl_config_nofixedfunc?(1u<<VATTR_VERTEX1):(1u<<VATTR_LEG_VERTEX), 0);
|
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];
|
float m16[16];
|
||||||
Matrix4_Multiply(r_refdef.m_projection, shaderstate.modelviewmatrix, m16);
|
Matrix4_Multiply(r_refdef.m_projection, shaderstate.modelviewmatrix, m16);
|
||||||
qglUniformMatrix4fvARB(shaderstate.allblack_mvp, 1, false, 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;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef GLSLONLY
|
#ifndef GLSLONLY
|
||||||
|
@ -3987,7 +4009,7 @@ static void DrawMeshes(void)
|
||||||
BE_SendPassBlendDepthMask(shaderstate.curshader->passes[0].shaderbits);
|
BE_SendPassBlendDepthMask(shaderstate.curshader->passes[0].shaderbits);
|
||||||
|
|
||||||
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR), 0);
|
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR), 0);
|
||||||
BE_SubmitMeshChain();
|
BE_SubmitMeshChain(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -4039,7 +4061,7 @@ static void DrawMeshes(void)
|
||||||
|
|
||||||
GenerateTCFog(0, shaderstate.curbatch->fog);
|
GenerateTCFog(0, shaderstate.curbatch->fog);
|
||||||
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR) | (1u<<VATTR_LEG_TMU0), 0);
|
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR) | (1u<<VATTR_LEG_TMU0), 0);
|
||||||
BE_SubmitMeshChain();
|
BE_SubmitMeshChain(false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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.vbo = vbos[1];
|
||||||
vbo->indicies.gl.addr = (index_t*)((char*)vbo->indicies.gl.addr - (char*)edata);
|
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)
|
if (vbo->coord.gl.addr)
|
||||||
{
|
{
|
||||||
vbo->coord.gl.vbo = vbos[0];
|
vbo->coord.gl.vbo = vbos[0];
|
||||||
vbo->coord.gl.addr = (vecV_t*)((char*)vbo->coord.gl.addr - (char*)vdata);
|
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)
|
if (vbo->texcoord.gl.addr)
|
||||||
{
|
{
|
||||||
vbo->texcoord.gl.vbo = vbos[0];
|
vbo->texcoord.gl.vbo = vbos[0];
|
||||||
vbo->texcoord.gl.addr = (vec2_t*)((char*)vbo->texcoord.gl.addr - (char*)vdata);
|
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++)
|
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);
|
vbo->colours[s].gl.addr = (vec4_t*)((char*)vbo->colours[s].gl.addr - (char*)vdata);
|
||||||
switch(s)
|
switch(s)
|
||||||
{
|
{
|
||||||
default: vaostatic |= VATTR_COLOUR; break;
|
default: vaostatic |= 1u<<VATTR_COLOUR; break;
|
||||||
#if MAXRLIGHTMAPS > 1
|
#if MAXRLIGHTMAPS > 1
|
||||||
case 1: vaostatic |= VATTR_COLOUR2; break;
|
case 1: vaostatic |= 1u<<VATTR_COLOUR2; break;
|
||||||
case 2: vaostatic |= VATTR_COLOUR3; break;
|
case 2: vaostatic |= 1u<<VATTR_COLOUR3; break;
|
||||||
case 3: vaostatic |= VATTR_COLOUR4; break;
|
case 3: vaostatic |= 1u<<VATTR_COLOUR4; break;
|
||||||
#endif
|
#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);
|
vbo->lmcoord[s].gl.addr = (vec2_t*)((char*)vbo->lmcoord[s].gl.addr - (char*)vdata);
|
||||||
switch(s)
|
switch(s)
|
||||||
{
|
{
|
||||||
default: vaostatic |= VATTR_LMCOORD; break;
|
default: vaostatic |= 1u<<VATTR_LMCOORD; break;
|
||||||
#if MAXRLIGHTMAPS > 1
|
#if MAXRLIGHTMAPS > 1
|
||||||
case 1: vaostatic |= VATTR_LMCOORD2; break;
|
case 1: vaostatic |= 1u<<VATTR_LMCOORD2; break;
|
||||||
case 2: vaostatic |= VATTR_LMCOORD3; break;
|
case 2: vaostatic |= 1u<<VATTR_LMCOORD3; break;
|
||||||
case 3: vaostatic |= VATTR_LMCOORD4; break;
|
case 3: vaostatic |= 1u<<VATTR_LMCOORD4; break;
|
||||||
#endif
|
#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.vbo = vbos[0];
|
||||||
vbo->normals.gl.addr = (vec3_t*)((char*)vbo->normals.gl.addr - (char*)vdata);
|
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)
|
if (vbo->svector.gl.addr)
|
||||||
{
|
{
|
||||||
vbo->svector.gl.vbo = vbos[0];
|
vbo->svector.gl.vbo = vbos[0];
|
||||||
vbo->svector.gl.addr = (vec3_t*)((char*)vbo->svector.gl.addr - (char*)vdata);
|
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)
|
if (vbo->tvector.gl.addr)
|
||||||
{
|
{
|
||||||
vbo->tvector.gl.vbo = vbos[0];
|
vbo->tvector.gl.vbo = vbos[0];
|
||||||
vbo->tvector.gl.addr = (vec3_t*)((char*)vbo->tvector.gl.addr - (char*)vdata);
|
vbo->tvector.gl.addr = (vec3_t*)((char*)vbo->tvector.gl.addr - (char*)vdata);
|
||||||
vaostatic |= VATTR_TNORMALS;
|
vaostatic |= 1u<<VATTR_TNORMALS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1783,11 +1783,11 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
|
||||||
prog->parm[prog->numparams].type = parmtype;
|
prog->parm[prog->numparams].type = parmtype;
|
||||||
for (p = 0; p < PERMUTATIONS; p++)
|
for (p = 0; p < PERMUTATIONS; p++)
|
||||||
{
|
{
|
||||||
if (!prog->permu[p].handle.glsl)
|
if (!prog->permu[p].handle.glsl.handle)
|
||||||
continue;
|
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;
|
prog->permu[p].parm[prog->numparams] = uniformloc;
|
||||||
|
|
||||||
if (uniformloc != -1)
|
if (uniformloc != -1)
|
||||||
|
|
|
@ -220,6 +220,8 @@ int mtexid0;
|
||||||
FTEPFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
|
FTEPFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
|
||||||
FTEPFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
|
FTEPFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
|
||||||
|
|
||||||
|
void (APIENTRY *qglPatchParameteriARB)(GLenum pname, GLint value); //core in gl4
|
||||||
|
|
||||||
//stencil shadowing
|
//stencil shadowing
|
||||||
FTEPFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT;
|
FTEPFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT;
|
||||||
|
|
||||||
|
@ -742,6 +744,13 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
||||||
qglPNTrianglesfATI = (void *)getglext("glPNTrianglesfATI");
|
qglPNTrianglesfATI = (void *)getglext("glPNTrianglesfATI");
|
||||||
qglPNTrianglesiATI = (void *)getglext("glPNTrianglesiATI");
|
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
|
#ifndef GL_STATIC
|
||||||
if (GL_CheckExtension("GL_EXT_texture_object"))
|
if (GL_CheckExtension("GL_EXT_texture_object"))
|
||||||
|
@ -1207,9 +1216,12 @@ static const char *glsl_hdrs[] =
|
||||||
"uniform float cvar_r_glsl_offsetmapping_scale;\n"
|
"uniform float cvar_r_glsl_offsetmapping_scale;\n"
|
||||||
"vec2 offsetmap(sampler2D normtex, vec2 base, vec3 eyevector)\n"
|
"vec2 offsetmap(sampler2D normtex, vec2 base, vec3 eyevector)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
"#if !defined(OFFSETMAPPING_SCALE)\n"
|
||||||
|
"#define OFFSETMAPPING_SCALE 1.0\n"
|
||||||
|
"#endif\n"
|
||||||
"#if defined(RELIEFMAPPING) && !defined(GL_ES)\n"
|
"#if defined(RELIEFMAPPING) && !defined(GL_ES)\n"
|
||||||
"float i, f;\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"
|
"vec3 RT = vec3(vec2(base.xy"/* - OffsetVector.xy*OffsetMapping_Bias*/"), 1.0);\n"
|
||||||
"OffsetVector /= 10.0;\n"
|
"OffsetVector /= 10.0;\n"
|
||||||
"for(i = 1.0; i < 10.0; ++i)\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"
|
"RT += OffsetVector * (step(texture2D(normtex, RT.xy).a, RT.z) * f - 0.5 * f);\n"
|
||||||
"return RT.xy;\n"
|
"return RT.xy;\n"
|
||||||
"#elif defined(OFFSETMAPPING)\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"
|
"vec2 tc = base;\n"
|
||||||
"tc += OffsetVector;\n"
|
"tc += OffsetVector;\n"
|
||||||
"OffsetVector *= 0.333;\n"
|
"OffsetVector *= 0.333;\n"
|
||||||
|
@ -1426,6 +1438,9 @@ static GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char *
|
||||||
int strings = 0;
|
int strings = 0;
|
||||||
char verline[64];
|
char verline[64];
|
||||||
|
|
||||||
|
if (!shadersource)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (ver)
|
if (ver)
|
||||||
{
|
{
|
||||||
/*required version not supported, don't even try*/
|
/*required version not supported, don't even try*/
|
||||||
|
@ -1471,6 +1486,16 @@ static GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char *
|
||||||
strings++;
|
strings++;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case GL_VERTEX_SHADER_ARB:
|
||||||
prstrings[strings] = "#define VERTEX_SHADER\n";
|
prstrings[strings] = "#define VERTEX_SHADER\n";
|
||||||
length[strings] = strlen(prstrings[strings]);
|
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]);
|
length[strings] = strlen(prstrings[strings]);
|
||||||
strings++;
|
strings++;
|
||||||
}
|
}
|
||||||
if (gl_config.nofixedfunc)
|
if (ver < 140)
|
||||||
{
|
{
|
||||||
prstrings[strings] =
|
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"
|
"#ifdef FRAMEBLEND\n"
|
||||||
"attribute vec3 v_position2;\n"
|
"in vec3 v_position2;\n"
|
||||||
"uniform vec2 e_vblend;\n"
|
"uniform vec2 e_vblend;\n"
|
||||||
"#define v_position ((v_position1*e_vblend.x)+(v_position2*e_vblend.y))\n"
|
"#define v_position ((v_position1*e_vblend.x)+(v_position2*e_vblend.y))\n"
|
||||||
"#else\n"
|
"#else\n"
|
||||||
|
@ -1509,7 +1550,7 @@ static GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char *
|
||||||
{
|
{
|
||||||
prstrings[strings] =
|
prstrings[strings] =
|
||||||
"#ifdef FRAMEBLEND\n"
|
"#ifdef FRAMEBLEND\n"
|
||||||
"attribute vec3 v_position2;\n"
|
"in vec3 v_position2;\n"
|
||||||
"uniform vec2 e_vblend;\n"
|
"uniform vec2 e_vblend;\n"
|
||||||
"#define v_position (gl_Vertex.xyz*e_vblend.x+v_position2*e_vblend.y)\n"
|
"#define v_position (gl_Vertex.xyz*e_vblend.x+v_position2*e_vblend.y)\n"
|
||||||
"uniform mat4 m_modelviewprojection;\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:
|
case GL_VERTEX_SHADER_ARB:
|
||||||
typedesc = "Vertex";
|
typedesc = "Vertex";
|
||||||
break;
|
break;
|
||||||
|
case GL_TESS_CONTROL_SHADER_ARB:
|
||||||
|
typedesc = "Tesselation Control";
|
||||||
|
break;
|
||||||
|
case GL_TESS_EVALUATION_SHADER_ARB:
|
||||||
|
typedesc = "Tesselation Evaluation";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
typedesc = "???";
|
typedesc = "???";
|
||||||
break;
|
break;
|
||||||
|
@ -1633,13 +1680,15 @@ static GLhandleARB GLSlang_FinishShader(GLhandleARB shader, const char *name, GL
|
||||||
return shader;
|
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;
|
GLhandleARB program;
|
||||||
|
|
||||||
program = qglCreateProgramObjectARB();
|
program = qglCreateProgramObjectARB();
|
||||||
qglAttachObjectARB(program, vert);
|
if (vert) qglAttachObjectARB(program, vert);
|
||||||
qglAttachObjectARB(program, frag);
|
if (cont) qglAttachObjectARB(program, cont);
|
||||||
|
if (eval) qglAttachObjectARB(program, eval);
|
||||||
|
if (frag) qglAttachObjectARB(program, frag);
|
||||||
|
|
||||||
qglBindAttribLocationARB(program, VATTR_VERTEX1, "v_position1");
|
qglBindAttribLocationARB(program, VATTR_VERTEX1, "v_position1");
|
||||||
qglBindAttribLocationARB(program, VATTR_COLOUR, "v_colour");
|
qglBindAttribLocationARB(program, VATTR_COLOUR, "v_colour");
|
||||||
|
@ -1666,108 +1715,124 @@ GLhandleARB GLSlang_CreateProgramObject (const char *name, GLhandleARB vert, GLh
|
||||||
return program;
|
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 str[2048];
|
||||||
char *nullconstants = NULL;
|
char *nullconstants = NULL;
|
||||||
GLint linked;
|
GLint linked;
|
||||||
|
|
||||||
if (!program)
|
if (!h->glsl.handle)
|
||||||
return (GLhandleARB)0;
|
return false;
|
||||||
qglGetProgramParameteriv_(program, GL_OBJECT_LINK_STATUS_ARB, &linked);
|
qglGetProgramParameteriv_(h->glsl.handle, GL_OBJECT_LINK_STATUS_ARB, &linked);
|
||||||
|
|
||||||
if(!linked)
|
if(!linked)
|
||||||
{
|
{
|
||||||
if (!silent)
|
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);
|
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;
|
return (GLhandleARB)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program && blobfile && qglGetProgramBinary)
|
if (h->glsl.handle && blobfile && qglGetProgramBinary)
|
||||||
{
|
{
|
||||||
GLuint ui;
|
GLuint ui;
|
||||||
GLenum e;
|
GLenum e;
|
||||||
unsigned int len, fmt;
|
unsigned int len, fmt;
|
||||||
void *blobdata;
|
void *blobdata;
|
||||||
|
|
||||||
qglGetProgramParameteriv_(program, GL_PROGRAM_BINARY_LENGTH, &ui);
|
qglGetProgramParameteriv_(h->glsl.handle, GL_PROGRAM_BINARY_LENGTH, &ui);
|
||||||
len = ui;
|
len = ui;
|
||||||
|
|
||||||
blobdata = BZ_Malloc(len);
|
blobdata = BZ_Malloc(len);
|
||||||
qglGetProgramBinary(program, len, NULL, &e, blobdata);
|
qglGetProgramBinary(h->glsl.handle, len, NULL, &e, blobdata);
|
||||||
fmt = e;
|
fmt = e;
|
||||||
|
|
||||||
VFS_WRITE(blobfile, &fmt, sizeof(fmt));
|
VFS_WRITE(blobfile, &fmt, sizeof(fmt));
|
||||||
VFS_WRITE(blobfile, &len, sizeof(len));
|
VFS_WRITE(blobfile, &len, sizeof(len));
|
||||||
VFS_WRITE(blobfile, blobdata, len);
|
VFS_WRITE(blobfile, blobdata, len);
|
||||||
|
VFS_WRITE(blobfile, &h->glsl.usetesselation, sizeof(h->glsl.usetesselation));
|
||||||
BZ_Free(blobdata);
|
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 vs;
|
||||||
GLhandleARB fs;
|
GLhandleARB fs;
|
||||||
|
GLhandleARB cs;
|
||||||
|
GLhandleARB es;
|
||||||
const char *nullconstants = NULL;
|
const char *nullconstants = NULL;
|
||||||
|
|
||||||
|
memset(&ret, 0, sizeof(ret));
|
||||||
|
|
||||||
if (!gl_config.arb_shader_objects)
|
if (!gl_config.arb_shader_objects)
|
||||||
return 0;
|
return ret;
|
||||||
|
if ((cont || frag) && !qglPatchParameteriARB)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (!precompilerconstants)
|
if (!precompilerconstants)
|
||||||
precompilerconstants = &nullconstants;
|
precompilerconstants = &nullconstants;
|
||||||
|
|
||||||
fs = GLSlang_CreateShader(name, ver, precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB, silent);
|
fs = GLSlang_CreateShader(name, ver, precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB, silent);
|
||||||
vs = GLSlang_CreateShader(name, ver, precompilerconstants, vert, GL_VERTEX_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);
|
fs = GLSlang_FinishShader(fs, name, GL_FRAGMENT_SHADER_ARB, silent);
|
||||||
vs = GLSlang_FinishShader(vs, name, GL_VERTEX_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)
|
if (!vs || !fs)
|
||||||
handle = 0;
|
ret.glsl.handle = 0;
|
||||||
else
|
else
|
||||||
handle = GLSlang_CreateProgramObject(name, vs, fs, silent);
|
ret.glsl.handle = GLSlang_CreateProgramObject(name, vs, cs, es, fs, silent);
|
||||||
//delete ignores 0s.
|
//delete ignores 0s.
|
||||||
qglDeleteShaderObject_(vs);
|
if (vs) qglDeleteShaderObject_(vs);
|
||||||
qglDeleteShaderObject_(fs);
|
if (fs) qglDeleteShaderObject_(fs);
|
||||||
|
if (cs) qglDeleteShaderObject_(cs);
|
||||||
|
if (es) qglDeleteShaderObject_(es);
|
||||||
|
|
||||||
checkglerror();
|
checkglerror();
|
||||||
|
|
||||||
if (handle && blobfile && qglGetProgramBinary)
|
if (ret.glsl.handle && blobfile && qglGetProgramBinary)
|
||||||
{
|
{
|
||||||
GLuint ui;
|
GLuint ui;
|
||||||
GLenum e;
|
GLenum e;
|
||||||
unsigned int len, fmt;
|
unsigned int len, fmt;
|
||||||
void *blobdata;
|
void *blobdata;
|
||||||
|
|
||||||
qglGetProgramParameteriv_(handle, GL_PROGRAM_BINARY_LENGTH, &ui);
|
qglGetProgramParameteriv_(ret.glsl.handle, GL_PROGRAM_BINARY_LENGTH, &ui);
|
||||||
len = ui;
|
len = ui;
|
||||||
|
|
||||||
blobdata = BZ_Malloc(len);
|
blobdata = BZ_Malloc(len);
|
||||||
qglGetProgramBinary(handle, len, NULL, &e, blobdata);
|
qglGetProgramBinary(ret.glsl.handle, len, NULL, &e, blobdata);
|
||||||
fmt = e;
|
fmt = e;
|
||||||
|
|
||||||
VFS_WRITE(blobfile, &fmt, sizeof(fmt));
|
VFS_WRITE(blobfile, &fmt, sizeof(fmt));
|
||||||
VFS_WRITE(blobfile, &len, sizeof(len));
|
VFS_WRITE(blobfile, &len, sizeof(len));
|
||||||
VFS_WRITE(blobfile, blobdata, len);
|
VFS_WRITE(blobfile, blobdata, len);
|
||||||
|
VFS_WRITE(blobfile, &ret.glsl.usetesselation, sizeof(ret.glsl.usetesselation));
|
||||||
BZ_Free(blobdata);
|
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)
|
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 GLSlang_ValidateProgram(&prog->permu[permu].handle, name, noerrors, blobfile);
|
||||||
return !!prog->permu[permu].handle.glsl;
|
|
||||||
}
|
}
|
||||||
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)
|
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)
|
if (permu & PERMUTATION_SKELETAL)
|
||||||
ver = 120;
|
ver = 120;
|
||||||
}
|
}
|
||||||
prog->permu[permu].handle.glsl = GLSlang_CreateProgram(name, ver, precompilerconstants, vert, frag, noerrors, blobfile);
|
prog->permu[permu].handle = GLSlang_CreateProgram(name, ver, precompilerconstants, vert, tcs, tes, frag, noerrors, blobfile);
|
||||||
if (prog->permu[permu].handle.glsl)
|
if (prog->permu[permu].handle.glsl.handle)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1805,26 +1870,27 @@ static qboolean GLSlang_LoadBlob(program_t *prog, const char *name, unsigned int
|
||||||
VFS_READ(blobfile, &length, sizeof(length));
|
VFS_READ(blobfile, &length, sizeof(length));
|
||||||
binary = BZ_Malloc(length);
|
binary = BZ_Malloc(length);
|
||||||
VFS_READ(blobfile, binary, 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();
|
prog->permu[permu].handle.glsl.handle = qglCreateProgramObjectARB();
|
||||||
qglProgramBinary(prog->permu[permu].handle.glsl, fmt, binary, length);
|
qglProgramBinary(prog->permu[permu].handle.glsl.handle, fmt, binary, length);
|
||||||
BZ_Free(binary);
|
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)
|
if (!success)
|
||||||
{
|
{
|
||||||
qglDeleteProgramObject_(prog->permu[permu].handle.glsl);
|
qglDeleteProgramObject_(prog->permu[permu].handle.glsl.handle);
|
||||||
prog->permu[permu].handle.glsl = 0;
|
memset(&prog->permu[permu].handle, 0, sizeof(prog->permu[permu].handle));
|
||||||
}
|
}
|
||||||
return !!success;
|
return !!success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GLSlang_DeleteProg(program_t *prog, unsigned int permu)
|
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);
|
qglDeleteProgramObject_(prog->permu[permu].handle.glsl.handle);
|
||||||
prog->permu[permu].handle.glsl = 0;
|
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
|
//figure out visible attributes
|
||||||
for (p = 0; p < PERMUTATIONS; p++)
|
for (p = 0; p < PERMUTATIONS; p++)
|
||||||
{
|
{
|
||||||
if (!prog->permu[p].handle.glsl)
|
if (!prog->permu[p].handle.glsl.handle)
|
||||||
continue;
|
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++)
|
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 (uniformloc != -1)
|
||||||
{
|
{
|
||||||
if (shader_attr_names[i].ptype != uniformloc)
|
if (shader_attr_names[i].ptype != uniformloc)
|
||||||
|
@ -1863,11 +1929,11 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
|
||||||
found = false;
|
found = false;
|
||||||
for (p = 0; p < PERMUTATIONS; p++)
|
for (p = 0; p < PERMUTATIONS; p++)
|
||||||
{
|
{
|
||||||
if (!prog->permu[p].handle.glsl)
|
if (!prog->permu[p].handle.glsl.handle)
|
||||||
continue;
|
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)
|
if (uniformloc != -1)
|
||||||
found = true;
|
found = true;
|
||||||
|
|
||||||
|
@ -1911,11 +1977,11 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
|
||||||
for (p = 0; p < PERMUTATIONS; p++)
|
for (p = 0; p < PERMUTATIONS; p++)
|
||||||
{
|
{
|
||||||
char uniformname[64];
|
char uniformname[64];
|
||||||
if (!prog->permu[p].handle.glsl)
|
if (!prog->permu[p].handle.glsl.handle)
|
||||||
continue;
|
continue;
|
||||||
GL_SelectProgram(prog->permu[p].handle.glsl);
|
GL_SelectProgram(prog->permu[p].handle.glsl.handle);
|
||||||
Q_snprintfz(uniformname, sizeof(uniformname), "cvar_%s", tmpname);
|
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)
|
if (uniformloc != -1)
|
||||||
{
|
{
|
||||||
//qglUniform1fARB(uniformloc, cvar->value);
|
//qglUniform1fARB(uniformloc, cvar->value);
|
||||||
|
@ -1929,15 +1995,15 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
|
||||||
/*set texture uniforms*/
|
/*set texture uniforms*/
|
||||||
for (p = 0; p < PERMUTATIONS; p++)
|
for (p = 0; p < PERMUTATIONS; p++)
|
||||||
{
|
{
|
||||||
if (!prog->permu[p].handle.glsl)
|
if (!prog->permu[p].handle.glsl.handle)
|
||||||
continue;
|
continue;
|
||||||
if (!(prog->permu[p].attrmask & (1u<<VATTR_VERTEX1))) //a shader kinda has to use one of these...
|
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);
|
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++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
Q_snprintfz(tmpname, sizeof(tmpname), "s_t%i", 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)
|
if (uniformloc != -1)
|
||||||
qglUniform1iARB(uniformloc, i);
|
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))
|
void GL_Init(void *(*getglfunction) (char *name))
|
||||||
{
|
{
|
||||||
#ifndef GL_STATIC
|
#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");
|
qglBlendFunc = (void *)getglcore("glBlendFunc");
|
||||||
qglClear = (void *)getglcore("glClear");
|
qglClear = (void *)getglcore("glClear");
|
||||||
qglClearColor = (void *)getglcore("glClearColor");
|
qglClearColor = (void *)getglcore("glClearColor");
|
||||||
|
|
|
@ -198,6 +198,7 @@ extern FTEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB;
|
||||||
extern FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB;
|
extern FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB;
|
||||||
extern FTEPFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
|
extern FTEPFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
|
||||||
extern FTEPFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
|
extern FTEPFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
|
||||||
|
extern void (APIENTRY *qglPatchParameteriARB)(GLenum pname, GLint value); //core in gl4
|
||||||
|
|
||||||
qboolean GL_CheckExtension(char *extname);
|
qboolean GL_CheckExtension(char *extname);
|
||||||
|
|
||||||
|
@ -1061,7 +1062,7 @@ extern void (APIENTRY *qglBindVertexArray)(GLuint vaoarray);
|
||||||
|
|
||||||
|
|
||||||
//glslang helper api
|
//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);
|
GLint GLSlang_GetUniformLocation (int prog, char *name);
|
||||||
void GL_SelectProgram(int program);
|
void GL_SelectProgram(int program);
|
||||||
#define GLSlang_UseProgram(prog) GL_SelectProgram(prog)
|
#define GLSlang_UseProgram(prog) GL_SelectProgram(prog)
|
||||||
|
|
|
@ -579,6 +579,11 @@ typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei
|
||||||
#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
|
#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
|
||||||
#endif
|
#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
|
#ifndef GL_ARB_fragment_shader
|
||||||
#define GL_FRAGMENT_SHADER_ARB 0x8B30
|
#define GL_FRAGMENT_SHADER_ARB 0x8B30
|
||||||
#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49
|
#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49
|
||||||
|
|
|
@ -422,7 +422,11 @@ typedef struct {
|
||||||
|
|
||||||
union programhandle_u
|
union programhandle_u
|
||||||
{
|
{
|
||||||
int glsl;
|
struct
|
||||||
|
{
|
||||||
|
int handle;
|
||||||
|
qboolean usetesselation;
|
||||||
|
} glsl;
|
||||||
#ifdef D3DQUAKE
|
#ifdef D3DQUAKE
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue