我搞糊涂了什么我的着色器在做什么。 我有一个着色器类包装了阴影OpenGL的部分我。 我建立我的代码::块应用程序并运行它,编译FASE失败,连接一阶段失败,但与验证GL_VALIDATE_STATUS
成功,并且着色器实际工作。
当我运行它的代码块外IDE编译和链接阶段成功也是如此验证。 当在IDE中运行ProgramLog和信息日志是空的甚至没有警告,但在IDE外部运行时编译和链接成功当InfoLogs确实显示警告。
我真搞不清楚这一点,这是我的编译阶段:
GLuint handle = glCreateShader(a_Type);
glShaderSource(handle, 1, &a_Source, NULL);
glCompileShader(handle);
a_Type可以GL_VERTEX_SHADER
, GL_FRAGMENT_SHADER
或GL_GEOMETRY_SHADER
和a_Source
是const char*
从文件中加载我的着色器代码。
然后我去检查编译状态:
glGetShaderiv(handle, GL_COMPILE_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{
这是一个逻辑检查和将GL_TRUE
从终端运行,但是当GL_FALSE
从IDE运行时。
链接检查如下:
glGetProgramiv(m_ProgramHandle, GL_LINK_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{
和验证
glValidateProgram(m_ProgramHandle); OGLCHECK
glGetProgramiv(m_ProgramHandle, GL_VALIDATE_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{
总结这一切,从withing IDE中的着色器编译和链接状态失败,但验证通过,并且着色的作品,但在信息日志是空的。 当从终端上运行的编译和链接状态的成功也是如此核查和着色器的工作原理。 而从终端中运行时,我也有一个充满信息日志,例如,警告。
:我做了一些调查,我的问题从这里来后,形成这个问题在Linux上GLSL着色器编译
这里的着色器类的源
#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;
}
当我创建的着色器我做的:
Shader gShader;
gShader.load("data/shaders/myshader");
加载器加载数据/着色器/ myshader.frag数据/着色器/ myshader.vert等,您可以在装载功能看到这一点。
更新1:我发现eventhough着色器似乎从IDE工作,我不能绑定的属性的位置。但我可以在片段着色器改变颜色,这将显示。 从属性做工精细的终端,我试图绑定2个均匀地点2个纹理和做了一些混合,工作得很好。