问题
Basic Description of Problem
I don't seem to be able to draw a triangle in any color other than white.
Here is my fragment shader code.
#version 330 core
out vec3 color;
void main()
{
color = vec3(1.0, 0.0, 0.0);
}
For the sake of clarity, I have not included any other code. My vertex shader works - I can see a white triangle on the screen.
I am new to the programmable pipeline way of using OpenGL.
More Details and main.cpp Code
It has been suggested that the fault may be that my program falls back to the fixed pipeline way of doing things, so here is my main.cpp code which perhaps contains the problem rather than the shader code.
#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;
}
Compilation Information
Here is some info on the compilation process if relevant:
I am compiling within codeblocks, and linking with -lGL -lGLU -lGLEW -lglut. Optimization level is -O3. --std=c++11.
回答1:
Replacement LoadShaders() function, which was not complete.
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;
}
Essentially the important changes are that the shaders were not linked before.
来源:https://stackoverflow.com/questions/32894931/opengl-fragment-shader-not-working-correctly-unable-to-draw-any-color-other-th