问题
I'm rather confused about what my shaders are doing.
I have a shader class which wraps the opengl parts of the shading for me. I build my application in code::blocks and run it, the compile fase fails, the linking stage fails but the verification with GL_VALIDATE_STATUS
succeeds and the shader actually works.
When I run it outside the codeblocks IDE the compile and linking stage succeeds and so does verification. When run in the IDE the ProgramLog and InfoLog are empty not even warnings but when running outside the IDE when compiling and linking succeed the InfoLogs do show warnings.
I'm really confused about this, this is my compile stage:
GLuint handle = glCreateShader(a_Type);
glShaderSource(handle, 1, &a_Source, NULL);
glCompileShader(handle);
a_Type can be GL_VERTEX_SHADER
, GL_FRAGMENT_SHADER
or GL_GEOMETRY_SHADER
and a_Source
is a const char*
with my shader code loaded from a file.
I then go on to check the compile status:
glGetShaderiv(handle, GL_COMPILE_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{
This is a logical check and will be GL_TRUE
when run from the terminal but GL_FALSE
when run from the IDE.
The linking check is as follows
glGetProgramiv(m_ProgramHandle, GL_LINK_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{
And the verification
glValidateProgram(m_ProgramHandle); OGLCHECK
glGetProgramiv(m_ProgramHandle, GL_VALIDATE_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{
To sum it all up, from withing the IDE the shader compile and link status fail but the verification passes and the shader works but the InfoLog is empty. When run from the terminal the compile and link status succeeds and so does the verification and the shader works. And when run from the terminal I also have a filled InfoLog with, for example, warnings.
This question was formed after I did some investigation into my problem coming from here: GLSL shader compilation on linux
Here's the source for the shader class
#include "Shader.h"
Shader::Shader():m_FragmentHandle(0),m_GeometryHandle(0),m_VertexHandle(0),m_ProgramHandle(0),m_CurrentTexture(0)
{
}
Shader::~Shader()
{
if(m_GeometryHandle != 0)
{
glDeleteShader(m_GeometryHandle);
m_GeometryHandle = 0;
}
if(m_VertexHandle != 0)
{
glDeleteShader(m_VertexHandle);
m_VertexHandle = 0;
}
if(m_FragmentHandle != 0)
{
glDeleteShader(m_FragmentHandle);
m_FragmentHandle = 0;
}
}
bool Shader::Load(const char* a_FileName)
{
printf( "Loading shader: %s\n", a_FileName );
char* shaderFile = new char[strlen(a_FileName) + 6]; //(char*)calloc(custom::strlen(a_FileName) + 6, sizeof(char));
char* source = NULL;
strcpy(shaderFile, a_FileName);
strcat(shaderFile, ".geom");
source = GetShaderSource(shaderFile);
if(source != NULL)
{
printf( "Compiling geometry shader...\n" );
m_GeometryHandle = Compile(GL_GEOMETRY_SHADER, source);
free(source);
source = 0;
if(m_GeometryHandle == 0)
{
printf( "Geometry shader compiling failed.\n" );
delete[] shaderFile;
shaderFile = 0;
return false;
}
}
strcpy(shaderFile, a_FileName);
strcat(shaderFile, ".vert");
source = GetShaderSource(shaderFile);
if(source != NULL)
{
printf( "Compiling vertex shader...\n" );
m_VertexHandle = Compile(GL_VERTEX_SHADER, source);
free(source);
source = 0;
if(m_VertexHandle == 0)
{
printf( "Vertex shader compiling failed.\n" );
delete[] shaderFile;
shaderFile = 0;
return false;
}
}
else
{
printf("No vertex shader found. A vertex and fragment shader are required!\n");
}
strcpy(shaderFile, a_FileName);
strcat(shaderFile, ".frag");
source = GetShaderSource(shaderFile);
if(source != NULL)
{
printf( "Compiling fragment shader...\n" );
m_FragmentHandle = Compile(GL_FRAGMENT_SHADER, source);
free(source);
source = 0;
if(m_FragmentHandle == 0)
{
printf( "Fragment shader compiling failed.\n" );
delete[] shaderFile;
shaderFile = 0;
return false;
}
}
else
{
printf("No fragment shader found. A vertex and fragment shader are required!\n");
}
delete[] shaderFile;
shaderFile = 0;
CreateProgram();
if(!Link())
{
printf( "Linking of shader \"%s\" failed!\n", a_FileName );
return false;
}
printf( "Shader build succesfully!\n" );
return true;
}
// WARNING: YOU NEED TO FREE THE RETURNED SOURCE YOURSELF!! free(buffer);
char* Shader::GetShaderSource(const char* a_FileName)
{
FILE* f;
f = fopen(a_FileName, "rb");
if(f != NULL)
{
// Shader is available
char* buffer;
long size;
fseek(f, 0L, SEEK_END);
size = ftell(f);
rewind(f);
buffer = (char*)calloc(1, size+1);
if(!buffer)
{
fclose(f);
return NULL;
}
if(fread(buffer, size, 1, f) != 1)
{
fclose(f);
return NULL;
}
fclose(f);
return buffer;
}
return NULL;
}
GLuint Shader::Compile(const GLuint a_Type, const char* a_Source)
{
if(a_Source == NULL)
return 0;
GLuint handle = glCreateShader(a_Type); OGLCHECK
glShaderSource(handle, 1, &a_Source, NULL); OGLCHECK
glCompileShader(handle); OGLCHECK
int bufflen = 0;
GLint success = GL_FALSE;
glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &bufflen); OGLCHECK
if(bufflen > 1)
{
GLchar* logString = new GLchar[bufflen + 1];
glGetShaderInfoLog(handle, bufflen, 0, logString); OGLCHECK
printf( "Shader compile output:\n%s\n", logString );
delete logString;
logString = 0;
} else {
glGetShaderiv(handle, GL_PROGRAM_LOG_LENGTH, &bufflen); OGLCHECK
}
glGetShaderiv(handle, GL_COMPILE_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{
printf( "Failed to compile shader!\n" );
glDeleteShader(handle); OGLCHECK
//handle = 0;
}
return handle;
}
void Shader::CreateProgram()
{
m_ProgramHandle = glCreateProgram(); OGLCHECK
if(m_GeometryHandle != 0)
{
glAttachShader(m_ProgramHandle, m_GeometryHandle); OGLCHECK
printf( "Attaching geometry shader...\n" );
}
if(m_VertexHandle != 0)
{
glAttachShader(m_ProgramHandle, m_VertexHandle); OGLCHECK
printf( "Attaching vertex shader...\n" );
}
if(m_FragmentHandle != 0)
{
glAttachShader(m_ProgramHandle, m_FragmentHandle); OGLCHECK
printf( "Attaching fragment shader...\n" );
}
}
bool Shader::Link()
{
glLinkProgram(m_ProgramHandle);
GLint bufflen = 0;
glGetProgramiv(m_ProgramHandle, GL_INFO_LOG_LENGTH, &bufflen); OGLCHECK
if(bufflen > 1)
{
GLchar *logString = new GLchar[bufflen + 1];
glGetProgramInfoLog(m_ProgramHandle, bufflen, 0, logString);
printf( "Shader linking output:\n%s\n", logString );
delete logString;
logString = 0;
}
GLint success = GL_FALSE;
glGetProgramiv(m_ProgramHandle, GL_LINK_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{
printf( "Shader failed to link!\n" );
return false;
}
glValidateProgram(m_ProgramHandle); OGLCHECK
glGetProgramiv(m_ProgramHandle, GL_VALIDATE_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{
printf( "Shader program was not validated.!\n" );
}
GLint activeCount = 0;
GLint maxNameLength = 0;
glGetProgramiv(m_ProgramHandle, GL_ACTIVE_UNIFORMS, &activeCount); OGLCHECK
glGetProgramiv(m_ProgramHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength); OGLCHECK
GLchar* name = new GLchar[maxNameLength];
GLsizei length = 100;
GLenum type = GL_INVALID_ENUM;
GLint size = 0;
for(int i=0; i<activeCount; ++i)
{
glGetActiveUniform(m_ProgramHandle, i, maxNameLength, &length, &size, &type, name); OGLCHECK
GLint handle = glGetUniformLocation(m_ProgramHandle, name); OGLCHECK
m_Parameters.insert(ParameterPair(name, handle));
}
glGetProgramiv(m_ProgramHandle, GL_ACTIVE_ATTRIBUTES, &activeCount); OGLCHECK
glGetProgramiv(m_ProgramHandle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength); OGLCHECK
delete name;
name = new GLchar[maxNameLength];
for(int i=0; i<activeCount; ++i)
{
glGetActiveAttrib(m_ProgramHandle, i, maxNameLength, &length, &size, &type, name); OGLCHECK
GLint handle = glGetAttribLocation(m_ProgramHandle, name); OGLCHECK
m_Attributes.insert(ParameterPair(name, handle));
}
delete name;
name = 0;
return true;
}
When I create the shader I do:
Shader gShader;
gShader.load("data/shaders/myshader");
The loader loads data/shaders/myshader.frag data/shaders/myshader.vert etc. You can see this in the Load function.
Update 1: I found out that eventhough the shader seems to work from the IDE I cannot bind to attribute locations.. But I can change the color in the fragment shader and this will show. From the terminal the attributes work fine, I tried to bind 2 textures on 2 uniform locations and did some blending, worked fine.
来源:https://stackoverflow.com/questions/11649104/compiling-a-shader-and-linking-fail-but-verification-of-the-shader-succeeds