OpenGL 片段着色器无法正常工作 - 无法绘制白色以外的任何颜色
OpenGL Fragment Shader not working correctly - Unable to draw any color other than white
问题的基本描述
我好像不会用白色以外的任何颜色画三角形。
这是我的片段着色器代码。
#version 330 core
out vec3 color;
void main()
{
color = vec3(1.0, 0.0, 0.0);
}
为了清楚起见,我没有包含任何其他代码。我的顶点着色器有效 - 我可以在屏幕上看到一个白色三角形。
我不熟悉使用 OpenGL 的可编程流水线方式。
更多详细信息和main.cpp代码
有人建议故障可能是我的程序回退到固定管道做事的方式,所以这里是我的 main.cpp 代码,它可能包含问题而不是着色器代码。
#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#include <fstream>
GLuint LoadShaders(const char *vertex_shader_path, const char *fragment_shader_path)
{
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
std::ifstream vertex_shader_file;
vertex_shader_file.open(vertex_shader_path, std::ios::in | std::ios::ate);
if(vertex_shader_file.is_open())
{
unsigned long long vertex_shader_code_size = vertex_shader_file.tellg();
char *vertex_shader_code = new char[vertex_shader_code_size];
vertex_shader_file.seekg(0, std::ios::beg);
vertex_shader_file.read(vertex_shader_code, vertex_shader_code_size);
vertex_shader_file.close();
GLint Result = GL_FALSE;
int InfoLogLength;
std::cout << "Compiling Vertex Shader: " << vertex_shader_path << std::endl;
glShaderSource(VertexShaderID, 1, (const GLchar**)(&vertex_shader_code), (const GLint*)(&vertex_shader_code_size));
glCompileShader(VertexShaderID);
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char *VertexShaderErrorMessage = new char[InfoLogLength];
glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]);
std::cout.write(VertexShaderErrorMessage, InfoLogLength);
std::cout.flush();
delete [] VertexShaderErrorMessage;
delete [] vertex_shader_code;
std::cout << "Done" << std::endl;
}
else
{
std::cout << "Error: Could not open vertex shader source: " << vertex_shader_path << std::endl;
exit(-1);
}
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
std::ifstream fragment_shader_file;
fragment_shader_file.open(fragment_shader_path, std::ios::in | std::ios::ate);
if(fragment_shader_file.is_open())
{
unsigned long long fragment_shader_code_size = fragment_shader_file.tellg();
char *fragment_shader_code = new char[fragment_shader_code_size];
fragment_shader_file.seekg(0, std::ios::beg);
fragment_shader_file.read(fragment_shader_code, fragment_shader_code_size);
fragment_shader_file.close();
GLint Result = GL_FALSE;
int InfoLogLength;
std::cout << "Compiling Fragment Shader: " << fragment_shader_path << std::endl;
glShaderSource(FragmentShaderID, 1, (const GLchar**)(&fragment_shader_code), (const GLint*)(&fragment_shader_code_size));
glCompileShader(FragmentShaderID);
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char *FragmentShaderErrorMessage = new char[InfoLogLength];
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]);
std::cout.write(FragmentShaderErrorMessage, InfoLogLength);
std::cout.flush();
delete [] FragmentShaderErrorMessage;
delete [] fragment_shader_code;
std::cout << "Done" << std::endl;
}
else
{
std::cout << "Error: Could not open fragment shader source: " << fragment_shader_path << std::endl;
}
}
GLuint vertexbuffer;
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0, 0.0, -10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
//glFlush();
glutSwapBuffers();
}
void reshape(int width, int height)
{
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLdouble)width/(GLdouble)height, 0.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
if(key == 27)
{
exit(0);
}
}
int main(int argc, char argv[])
{
glutInit(&argc, &argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowSize(800, 600);
glutCreateWindow("window");
glewExperimental = true;
glewInit();
GLuint vertexarrayID;
glGenVertexArrays(1, &vertexarrayID);
glBindVertexArray(vertexarrayID);
static const GLfloat gvertexbufferdata[] = {-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f};
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(gvertexbufferdata), gvertexbufferdata, GL_STATIC_DRAW);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
GLuint programID = LoadShaders("vertexshader.glsl", "fragmentshader.glsl");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
glutMainLoop();
return 0;
}
编译信息
如果相关,这里有一些关于编译过程的信息:
我在代码块内编译,并与 -lGL -lGLU -lGLEW -lglut
链接。优化级别为 -O3
。 --std=c++11
.
替换LoadShaders()
功能,不完整。
GLuint LoadShaders(const char *vertex_shader_path, const char *fragment_shader_path)
{
// Load and Compile Vertex Shader
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
std::ifstream vertex_shader_file;
vertex_shader_file.open(vertex_shader_path, std::ios::in | std::ios::ate);
if(vertex_shader_file.is_open())
{
unsigned long long vertex_shader_code_size = vertex_shader_file.tellg();
char *vertex_shader_code = new char[vertex_shader_code_size];
vertex_shader_file.seekg(0, std::ios::beg);
vertex_shader_file.read(vertex_shader_code, vertex_shader_code_size);
vertex_shader_file.close();
GLint Result = GL_FALSE;
int InfoLogLength;
std::cout << "Compiling Vertex Shader: " << vertex_shader_path << std::endl;
glShaderSource(VertexShaderID, 1, (const GLchar**)(&vertex_shader_code), (const GLint*)(&vertex_shader_code_size));
glCompileShader(VertexShaderID);
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char *VertexShaderErrorMessage = new char[InfoLogLength];
glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]);
std::cout.write(VertexShaderErrorMessage, InfoLogLength);
std::cout.flush();
delete [] VertexShaderErrorMessage;
delete [] vertex_shader_code;
std::cout << "Done" << std::endl;
}
else
{
std::cout << "Error: Could not open vertex shader source: " << vertex_shader_path << std::endl;
exit(-1);
}
// Load and Compile Fragment Shader
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
std::ifstream fragment_shader_file;
fragment_shader_file.open(fragment_shader_path, std::ios::in | std::ios::ate);
if(fragment_shader_file.is_open())
{
unsigned long long fragment_shader_code_size = fragment_shader_file.tellg();
char *fragment_shader_code = new char[fragment_shader_code_size];
fragment_shader_file.seekg(0, std::ios::beg);
fragment_shader_file.read(fragment_shader_code, fragment_shader_code_size);
fragment_shader_file.close();
GLint Result = GL_FALSE;
int InfoLogLength;
std::cout << "Compiling Fragment Shader: " << fragment_shader_path << std::endl;
glShaderSource(FragmentShaderID, 1, (const GLchar**)(&fragment_shader_code), (const GLint*)(&fragment_shader_code_size));
glCompileShader(FragmentShaderID);
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char *FragmentShaderErrorMessage = new char[InfoLogLength];
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]);
std::cout.write(FragmentShaderErrorMessage, InfoLogLength);
std::cout.flush();
delete [] FragmentShaderErrorMessage;
delete [] fragment_shader_code;
std::cout << "Done" << std::endl;
}
else
{
std::cout << "Error: Could not open fragment shader source: " << fragment_shader_path << std::endl;
}
// Link Shaders
std::cout << "Linking Shaders" << std::endl;
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
GLint Result = GL_FALSE;
int InfoLogLength;
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if(InfoLogLength == 0) InfoLogLength = 1;
char *ProgramErrorMessage = new char[InfoLogLength];
glGetProgramInfoLog(ProgramID, InfoLogLength, nullptr, ProgramErrorMessage);
std::cout.write(ProgramErrorMessage, InfoLogLength);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
本质上重要的变化是着色器之前没有链接。
问题的基本描述
我好像不会用白色以外的任何颜色画三角形。
这是我的片段着色器代码。
#version 330 core
out vec3 color;
void main()
{
color = vec3(1.0, 0.0, 0.0);
}
为了清楚起见,我没有包含任何其他代码。我的顶点着色器有效 - 我可以在屏幕上看到一个白色三角形。
我不熟悉使用 OpenGL 的可编程流水线方式。
更多详细信息和main.cpp代码
有人建议故障可能是我的程序回退到固定管道做事的方式,所以这里是我的 main.cpp 代码,它可能包含问题而不是着色器代码。
#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>
#include <fstream>
GLuint LoadShaders(const char *vertex_shader_path, const char *fragment_shader_path)
{
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
std::ifstream vertex_shader_file;
vertex_shader_file.open(vertex_shader_path, std::ios::in | std::ios::ate);
if(vertex_shader_file.is_open())
{
unsigned long long vertex_shader_code_size = vertex_shader_file.tellg();
char *vertex_shader_code = new char[vertex_shader_code_size];
vertex_shader_file.seekg(0, std::ios::beg);
vertex_shader_file.read(vertex_shader_code, vertex_shader_code_size);
vertex_shader_file.close();
GLint Result = GL_FALSE;
int InfoLogLength;
std::cout << "Compiling Vertex Shader: " << vertex_shader_path << std::endl;
glShaderSource(VertexShaderID, 1, (const GLchar**)(&vertex_shader_code), (const GLint*)(&vertex_shader_code_size));
glCompileShader(VertexShaderID);
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char *VertexShaderErrorMessage = new char[InfoLogLength];
glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]);
std::cout.write(VertexShaderErrorMessage, InfoLogLength);
std::cout.flush();
delete [] VertexShaderErrorMessage;
delete [] vertex_shader_code;
std::cout << "Done" << std::endl;
}
else
{
std::cout << "Error: Could not open vertex shader source: " << vertex_shader_path << std::endl;
exit(-1);
}
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
std::ifstream fragment_shader_file;
fragment_shader_file.open(fragment_shader_path, std::ios::in | std::ios::ate);
if(fragment_shader_file.is_open())
{
unsigned long long fragment_shader_code_size = fragment_shader_file.tellg();
char *fragment_shader_code = new char[fragment_shader_code_size];
fragment_shader_file.seekg(0, std::ios::beg);
fragment_shader_file.read(fragment_shader_code, fragment_shader_code_size);
fragment_shader_file.close();
GLint Result = GL_FALSE;
int InfoLogLength;
std::cout << "Compiling Fragment Shader: " << fragment_shader_path << std::endl;
glShaderSource(FragmentShaderID, 1, (const GLchar**)(&fragment_shader_code), (const GLint*)(&fragment_shader_code_size));
glCompileShader(FragmentShaderID);
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char *FragmentShaderErrorMessage = new char[InfoLogLength];
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]);
std::cout.write(FragmentShaderErrorMessage, InfoLogLength);
std::cout.flush();
delete [] FragmentShaderErrorMessage;
delete [] fragment_shader_code;
std::cout << "Done" << std::endl;
}
else
{
std::cout << "Error: Could not open fragment shader source: " << fragment_shader_path << std::endl;
}
}
GLuint vertexbuffer;
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0, 0.0, -10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
//glFlush();
glutSwapBuffers();
}
void reshape(int width, int height)
{
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLdouble)width/(GLdouble)height, 0.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
if(key == 27)
{
exit(0);
}
}
int main(int argc, char argv[])
{
glutInit(&argc, &argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowSize(800, 600);
glutCreateWindow("window");
glewExperimental = true;
glewInit();
GLuint vertexarrayID;
glGenVertexArrays(1, &vertexarrayID);
glBindVertexArray(vertexarrayID);
static const GLfloat gvertexbufferdata[] = {-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f};
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(gvertexbufferdata), gvertexbufferdata, GL_STATIC_DRAW);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
GLuint programID = LoadShaders("vertexshader.glsl", "fragmentshader.glsl");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
glutMainLoop();
return 0;
}
编译信息
如果相关,这里有一些关于编译过程的信息:
我在代码块内编译,并与 -lGL -lGLU -lGLEW -lglut
链接。优化级别为 -O3
。 --std=c++11
.
替换LoadShaders()
功能,不完整。
GLuint LoadShaders(const char *vertex_shader_path, const char *fragment_shader_path)
{
// Load and Compile Vertex Shader
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
std::ifstream vertex_shader_file;
vertex_shader_file.open(vertex_shader_path, std::ios::in | std::ios::ate);
if(vertex_shader_file.is_open())
{
unsigned long long vertex_shader_code_size = vertex_shader_file.tellg();
char *vertex_shader_code = new char[vertex_shader_code_size];
vertex_shader_file.seekg(0, std::ios::beg);
vertex_shader_file.read(vertex_shader_code, vertex_shader_code_size);
vertex_shader_file.close();
GLint Result = GL_FALSE;
int InfoLogLength;
std::cout << "Compiling Vertex Shader: " << vertex_shader_path << std::endl;
glShaderSource(VertexShaderID, 1, (const GLchar**)(&vertex_shader_code), (const GLint*)(&vertex_shader_code_size));
glCompileShader(VertexShaderID);
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char *VertexShaderErrorMessage = new char[InfoLogLength];
glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]);
std::cout.write(VertexShaderErrorMessage, InfoLogLength);
std::cout.flush();
delete [] VertexShaderErrorMessage;
delete [] vertex_shader_code;
std::cout << "Done" << std::endl;
}
else
{
std::cout << "Error: Could not open vertex shader source: " << vertex_shader_path << std::endl;
exit(-1);
}
// Load and Compile Fragment Shader
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
std::ifstream fragment_shader_file;
fragment_shader_file.open(fragment_shader_path, std::ios::in | std::ios::ate);
if(fragment_shader_file.is_open())
{
unsigned long long fragment_shader_code_size = fragment_shader_file.tellg();
char *fragment_shader_code = new char[fragment_shader_code_size];
fragment_shader_file.seekg(0, std::ios::beg);
fragment_shader_file.read(fragment_shader_code, fragment_shader_code_size);
fragment_shader_file.close();
GLint Result = GL_FALSE;
int InfoLogLength;
std::cout << "Compiling Fragment Shader: " << fragment_shader_path << std::endl;
glShaderSource(FragmentShaderID, 1, (const GLchar**)(&fragment_shader_code), (const GLint*)(&fragment_shader_code_size));
glCompileShader(FragmentShaderID);
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char *FragmentShaderErrorMessage = new char[InfoLogLength];
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]);
std::cout.write(FragmentShaderErrorMessage, InfoLogLength);
std::cout.flush();
delete [] FragmentShaderErrorMessage;
delete [] fragment_shader_code;
std::cout << "Done" << std::endl;
}
else
{
std::cout << "Error: Could not open fragment shader source: " << fragment_shader_path << std::endl;
}
// Link Shaders
std::cout << "Linking Shaders" << std::endl;
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
GLint Result = GL_FALSE;
int InfoLogLength;
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if(InfoLogLength == 0) InfoLogLength = 1;
char *ProgramErrorMessage = new char[InfoLogLength];
glGetProgramInfoLog(ProgramID, InfoLogLength, nullptr, ProgramErrorMessage);
std::cout.write(ProgramErrorMessage, InfoLogLength);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
本质上重要的变化是着色器之前没有链接。