Batch indexing/no-fixed-function WIP.
This commit is contained in:
@@ -538,7 +538,7 @@ bool LLGLManager::initGL()
|
||||
{
|
||||
GLint num_tex_image_units;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
|
||||
mNumTextureImageUnits = num_tex_image_units;
|
||||
mNumTextureImageUnits = llmin(num_tex_image_units, 32);
|
||||
}
|
||||
|
||||
initGLStates();
|
||||
@@ -1299,6 +1299,7 @@ void LLGLState::checkStates(const std::string& msg)
|
||||
|
||||
void LLGLState::checkTextureChannels(const std::string& msg)
|
||||
{
|
||||
#if 0
|
||||
if (!gDebugGL)
|
||||
{
|
||||
return;
|
||||
@@ -1458,6 +1459,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
||||
LL_GL_ERRS << "GL texture state corruption detected. " << msg << LL_ENDL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
@@ -1574,7 +1576,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
}
|
||||
}
|
||||
|
||||
if (glIsEnabled(GL_TEXTURE_2D))
|
||||
/*if (glIsEnabled(GL_TEXTURE_2D))
|
||||
{
|
||||
if (!(data_mask & 0x0008))
|
||||
{
|
||||
@@ -1597,7 +1599,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
gFailLog << "GL does not have GL_TEXTURE_2D enabled on channel 1." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
gGL.getTexUnit(0)->activate();
|
||||
|
||||
@@ -54,6 +54,7 @@ using std::pair;
|
||||
using std::make_pair;
|
||||
using std::string;
|
||||
|
||||
GLhandleARB LLGLSLShader::sCurBoundShader = 0;
|
||||
BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
|
||||
{
|
||||
return v1 != v2;
|
||||
@@ -63,6 +64,7 @@ LLShaderFeatures::LLShaderFeatures()
|
||||
: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
|
||||
hasTransport(false), hasSkinning(false), hasAtmospherics(false), isSpecular(false),
|
||||
hasGamma(false), hasLighting(false), calculatesAtmospherics(false)
|
||||
, mIndexedTextureChannels(0), disableTextureIndex(false)
|
||||
#if MESH_ENABLED
|
||||
, hasObjectSkinning(false)
|
||||
#endif //MESH_ENABLED
|
||||
@@ -119,6 +121,27 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
||||
glDeleteObjectARB(mProgramObject);
|
||||
// Create program
|
||||
mProgramObject = glCreateProgramObjectARB();
|
||||
|
||||
if (gGLManager.mGLVersion < 3.1f)
|
||||
{ //force indexed texture channels to 1 if GL version is old (performance improvement for drivers with poor branching shader model support)
|
||||
mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
|
||||
}
|
||||
|
||||
//compile new source
|
||||
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
|
||||
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
|
||||
{
|
||||
GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels);
|
||||
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
|
||||
if (shaderhandle > 0)
|
||||
{
|
||||
attachObject(shaderhandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Attach existing objects
|
||||
if (!LLShaderMgr::instance()->attachShaderFeatures(this))
|
||||
@@ -129,19 +152,9 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
|
||||
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
|
||||
{
|
||||
GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second);
|
||||
LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
|
||||
if (mShaderLevel > 0)
|
||||
{
|
||||
attachObject(shaderhandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
if (gGLManager.mGLVersion < 3.1f)
|
||||
{ //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again
|
||||
mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
|
||||
}
|
||||
|
||||
// Map attributes and uniforms
|
||||
@@ -169,6 +182,28 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
||||
return createShader(attributes,uniforms);
|
||||
}
|
||||
}
|
||||
else if (mFeatures.mIndexedTextureChannels > 0)
|
||||
{ //override texture channels for indexed texture rendering
|
||||
bind();
|
||||
S32 channel_count = mFeatures.mIndexedTextureChannels;
|
||||
|
||||
for (S32 i = 0; i < channel_count; i++)
|
||||
{
|
||||
uniform1i(llformat("tex%d", i), i);
|
||||
}
|
||||
|
||||
S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
|
||||
for (U32 i = 0; i < mTexture.size(); i++)
|
||||
{
|
||||
if (mTexture[i] > -1 && mTexture[i] < channel_count)
|
||||
{
|
||||
llassert(cur_tex < gGLManager.mNumTextureImageUnits);
|
||||
uniform1i(i, cur_tex);
|
||||
mTexture[i] = cur_tex++;
|
||||
}
|
||||
}
|
||||
unbind();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -363,7 +398,7 @@ void LLGLSLShader::bind()
|
||||
if (gGLManager.mHasShaderObjects)
|
||||
{
|
||||
glUseProgramObjectARB(mProgramObject);
|
||||
|
||||
sCurBoundShader = mProgramObject;
|
||||
if (mUniformsDirty)
|
||||
{
|
||||
LLShaderMgr::instance()->updateShaderUniforms(this);
|
||||
@@ -386,6 +421,7 @@ void LLGLSLShader::unbind()
|
||||
}
|
||||
}
|
||||
glUseProgramObjectARB(0);
|
||||
sCurBoundShader = 0;
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
@@ -393,6 +429,7 @@ void LLGLSLShader::unbind()
|
||||
void LLGLSLShader::bindNoShader(void)
|
||||
{
|
||||
glUseProgramObjectARB(0);
|
||||
sCurBoundShader = 0;
|
||||
}
|
||||
|
||||
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
|
||||
|
||||
@@ -53,6 +53,8 @@ public:
|
||||
#endif //MESH_ENABLED
|
||||
bool hasAtmospherics;
|
||||
bool hasGamma;
|
||||
S32 mIndexedTextureChannels;
|
||||
bool disableTextureIndex;
|
||||
|
||||
// char numLights;
|
||||
|
||||
@@ -72,6 +74,8 @@ public:
|
||||
|
||||
LLGLSLShader(S32 shader_class);
|
||||
|
||||
static GLhandleARB sCurBoundShader;
|
||||
|
||||
void unload();
|
||||
BOOL createShader(std::vector<std::string> * attributes,
|
||||
std::vector<std::string> * uniforms);
|
||||
|
||||
@@ -1404,11 +1404,13 @@ void LLImageGL::deleteDeadTextures()
|
||||
{
|
||||
GLuint tex = sDeadTextureList.front();
|
||||
sDeadTextureList.pop_front();
|
||||
for (int i = 0; i < gGLManager.mNumTextureUnits; i++)
|
||||
for (int i = 0; i < gGLManager.mNumTextureImageUnits; i++)
|
||||
{
|
||||
if (sCurrentBoundTextures[i] == tex)
|
||||
LLTexUnit* tex_unit = gGL.getTexUnit(i);
|
||||
|
||||
if (tex_unit->getCurrTexture() == tex)
|
||||
{
|
||||
gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
tex_unit->unbind(tex_unit->getCurrType());
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ F64 gGLLastProjection[16];
|
||||
F64 gGLProjection[16];
|
||||
S32 gGLViewport[4];
|
||||
|
||||
static const U32 LL_NUM_TEXTURE_LAYERS = 8;
|
||||
|
||||
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
|
||||
static const U32 LL_NUM_LIGHT_UNITS = 8;
|
||||
|
||||
static GLenum sGLTextureType[] =
|
||||
|
||||
@@ -217,17 +217,39 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
||||
|
||||
if (features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightWaterF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightWaterNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightWaterF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,32 +260,76 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
||||
|
||||
if (features->isShiny && features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyWaterNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
else if (features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
|
||||
else if (features->isShiny)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightFullbrightNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,17 +340,39 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
||||
|
||||
if (features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightShinyWaterF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightShinyWaterNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightShinyWaterF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightShinyF.glsl"))
|
||||
if (features->disableTextureIndex)
|
||||
{
|
||||
return FALSE;
|
||||
if (!shader->attachObject("lighting/lightShinyNonIndexedF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightShinyF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,13 +416,16 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
|
||||
}
|
||||
}
|
||||
|
||||
GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type)
|
||||
GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels)
|
||||
{
|
||||
GLenum error;
|
||||
error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
GLenum error = GL_NO_ERROR;
|
||||
if (gDebugGL)
|
||||
{
|
||||
LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL;
|
||||
error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
{
|
||||
LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
LL_DEBUGS("ShaderLoading") << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL;
|
||||
@@ -375,11 +466,121 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
||||
|
||||
//we can't have any lines longer than 1024 characters
|
||||
//or any shaders longer than 1024 lines... deal - DaveP
|
||||
GLcharARB buff[1024];
|
||||
GLcharARB* text[1024];
|
||||
GLcharARB buff[1024] = {0};
|
||||
GLcharARB* text[1024] = {0};
|
||||
GLuint count = 0;
|
||||
|
||||
if (gGLManager.mGLVersion < 2.1f)
|
||||
{
|
||||
text[count++] = strdup("#version 110\n");
|
||||
}
|
||||
else if (gGLManager.mGLVersion < 3.f)
|
||||
{
|
||||
//set version to 1.20
|
||||
text[count++] = strdup("#version 120\n");
|
||||
}
|
||||
else
|
||||
{ //set version to 1.30
|
||||
text[count++] = strdup("#version 130\n");
|
||||
}
|
||||
|
||||
//copy preprocessor definitions into buffer
|
||||
for (std::map<std::string,std::string>::iterator iter = mDefinitions.begin(); iter != mDefinitions.end(); ++iter)
|
||||
{
|
||||
std::string define = "#define " + iter->first + " " + iter->second + "\n";
|
||||
text[count++] = (GLcharARB *) strdup(define.c_str());
|
||||
}
|
||||
|
||||
if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)
|
||||
{
|
||||
//use specified number of texture channels for indexed texture rendering
|
||||
|
||||
/* prepend shader code that looks like this:
|
||||
|
||||
uniform sampler2D tex0;
|
||||
uniform sampler2D tex1;
|
||||
uniform sampler2D tex2;
|
||||
.
|
||||
.
|
||||
.
|
||||
uniform sampler2D texN;
|
||||
|
||||
varying float vary_texture_index;
|
||||
|
||||
vec4 diffuseLookup(vec2 texcoord)
|
||||
{
|
||||
switch (int(vary_texture_index+0.25))
|
||||
{
|
||||
case 0: return texture2D(tex0, texcoord);
|
||||
case 1: return texture2D(tex1, texcoord);
|
||||
case 2: return texture2D(tex2, texcoord);
|
||||
.
|
||||
.
|
||||
.
|
||||
case N: return texture2D(texN, texcoord);
|
||||
}
|
||||
|
||||
return vec4(0,0,0,0);
|
||||
}
|
||||
*/
|
||||
|
||||
//uniform declartion
|
||||
for (S32 i = 0; i < texture_index_channels; ++i)
|
||||
{
|
||||
std::string decl = llformat("uniform sampler2D tex%d;\n", i);
|
||||
text[count++] = strdup(decl.c_str());
|
||||
}
|
||||
|
||||
text[count++] = strdup("varying float vary_texture_index;\n");
|
||||
text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
|
||||
text[count++] = strdup("{\n");
|
||||
|
||||
|
||||
if (texture_index_channels == 1)
|
||||
{ //don't use flow control, that's silly
|
||||
text[count++] = strdup("return texture2D(tex0, texcoord);\n");
|
||||
text[count++] = strdup("}\n");
|
||||
}
|
||||
else if (gGLManager.mGLVersion >= 3.f)
|
||||
{
|
||||
text[count++] = strdup("\tswitch (int(vary_texture_index+0.25))\n");
|
||||
text[count++] = strdup("\t{\n");
|
||||
|
||||
//switch body
|
||||
for (S32 i = 0; i < texture_index_channels; ++i)
|
||||
{
|
||||
std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i);
|
||||
text[count++] = strdup(case_str.c_str());
|
||||
}
|
||||
|
||||
text[count++] = strdup("\t}\n");
|
||||
text[count++] = strdup("\treturn vec4(0,0,0,0);\n");
|
||||
text[count++] = strdup("}\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//switches aren't supported, make block that looks like:
|
||||
/*
|
||||
int ti = int(vary_texture_index+0.25);
|
||||
if (ti == 0) return texture2D(tex0, texcoord);
|
||||
if (ti == 1) return texture2D(tex1, texcoord);
|
||||
.
|
||||
.
|
||||
.
|
||||
if (ti == N) return texture2D(texN, texcoord);
|
||||
*/
|
||||
|
||||
text[count++] = strdup("int ti = int(vary_texture_index+0.25);\n");
|
||||
for (S32 i = 0; i < texture_index_channels; ++i)
|
||||
{
|
||||
std::string if_str = llformat("if (ti == %d) return texture2D(tex%d, texcoord);\n", i, i);
|
||||
text[count++] = strdup(if_str.c_str());
|
||||
}
|
||||
|
||||
text[count++] = strdup("\treturn vec4(0,0,0,0);\n");
|
||||
text[count++] = strdup("}\n");
|
||||
}
|
||||
}
|
||||
//copy file into memory
|
||||
while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(buff) )
|
||||
{
|
||||
@@ -389,51 +590,67 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
||||
|
||||
//create shader object
|
||||
GLhandleARB ret = glCreateShaderObjectARB(type);
|
||||
error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
if (gDebugGL)
|
||||
{
|
||||
LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << LL_ENDL;
|
||||
error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
{
|
||||
LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << LL_ENDL;
|
||||
glDeleteObjectARB(ret); //no longer need handle
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
//load source
|
||||
glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL);
|
||||
|
||||
if (gDebugGL)
|
||||
{
|
||||
//load source
|
||||
glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL);
|
||||
error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
{
|
||||
LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << LL_ENDL;
|
||||
glDeleteObjectARB(ret); //no longer need handle
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
//compile source
|
||||
glCompileShaderARB(ret);
|
||||
|
||||
if (gDebugGL)
|
||||
{
|
||||
error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
{
|
||||
//compile source
|
||||
glCompileShaderARB(ret);
|
||||
error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
{
|
||||
LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL;
|
||||
glDeleteObjectARB(ret); //no longer need handle
|
||||
}
|
||||
LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL;
|
||||
glDeleteObjectARB(ret); //no longer need handle
|
||||
}
|
||||
}
|
||||
//free memory
|
||||
for (GLuint i = 0; i < count; i++)
|
||||
{
|
||||
free(text[i]);
|
||||
}
|
||||
|
||||
if (error == GL_NO_ERROR)
|
||||
{
|
||||
//check for errors
|
||||
GLint success = GL_TRUE;
|
||||
glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success);
|
||||
error = glGetError();
|
||||
if (error != GL_NO_ERROR || success == GL_FALSE)
|
||||
if (gDebugGL || success == GL_FALSE)
|
||||
{
|
||||
//an error occured, print log
|
||||
LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
|
||||
dumpObjectLog(ret);
|
||||
glDeleteObjectARB(ret); //no longer need handle
|
||||
ret = 0;
|
||||
error = glGetError();
|
||||
if (error != GL_NO_ERROR || success == GL_FALSE)
|
||||
{
|
||||
//an error occured, print log
|
||||
LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
|
||||
dumpObjectLog(ret);
|
||||
|
||||
std::stringstream ostr;
|
||||
//dump shader source for debugging
|
||||
for (GLuint i = 0; i < count; i++)
|
||||
{
|
||||
ostr << i << ": " << text[i];
|
||||
}
|
||||
|
||||
LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
|
||||
glDeleteObjectARB(ret); //no longer need handle
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -442,6 +659,12 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
||||
}
|
||||
stop_glerror();
|
||||
|
||||
//free memory
|
||||
for (GLuint i = 0; i < count; i++)
|
||||
{
|
||||
free(text[i]);
|
||||
}
|
||||
|
||||
//successfully loaded, save results
|
||||
if (ret)
|
||||
{
|
||||
@@ -454,7 +677,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
||||
if (shader_level > 1)
|
||||
{
|
||||
shader_level--;
|
||||
return loadShaderFile(filename,shader_level,type);
|
||||
return loadShaderFile(filename,shader_level,type,texture_index_channels);
|
||||
}
|
||||
LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
|
||||
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
|
||||
BOOL validateProgramObject(GLhandleARB obj);
|
||||
GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type);
|
||||
GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, S32 texture_index_channels = -1);
|
||||
|
||||
// Implemented in the application to actually point to the shader directory.
|
||||
virtual std::string getShaderDirPrefix(void) = 0; // Pure Virtual
|
||||
@@ -66,6 +66,9 @@ public:
|
||||
|
||||
std::vector<std::string> mReservedUniforms;
|
||||
|
||||
//preprocessor definitions (name/value)
|
||||
std::map<std::string, std::string> mDefinitions;
|
||||
|
||||
protected:
|
||||
|
||||
// our parameter manager singleton instance
|
||||
|
||||
@@ -1152,7 +1152,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index)
|
||||
void LLVertexBuffer::unmapBuffer(S32 type)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (!useVBOs())
|
||||
if (!useVBOs() || type == -2)
|
||||
{
|
||||
return ; //nothing to unmap
|
||||
}
|
||||
@@ -1605,7 +1605,14 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
|
||||
}
|
||||
if (data_mask & MAP_VERTEX)
|
||||
{
|
||||
glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0));
|
||||
if (data_mask & MAP_TEXTURE_INDEX)
|
||||
{
|
||||
glVertexPointer(4,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0));
|
||||
}
|
||||
}
|
||||
|
||||
llglassertok();
|
||||
|
||||
@@ -127,6 +127,9 @@ public:
|
||||
TYPE_CLOTHWEIGHT,
|
||||
TYPE_MAX,
|
||||
TYPE_INDEX,
|
||||
|
||||
//no actual additional data, but indicates position.w is texture index
|
||||
TYPE_TEXTURE_INDEX,
|
||||
};
|
||||
enum {
|
||||
MAP_VERTEX = (1<<TYPE_VERTEX),
|
||||
@@ -141,6 +144,7 @@ public:
|
||||
MAP_WEIGHT = (1<<TYPE_WEIGHT),
|
||||
MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
|
||||
MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
|
||||
MAP_TEXTURE_INDEX = (1<<TYPE_TEXTURE_INDEX),
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user