我在MacOSX 10.10上使用OpenGL和SDL2。我一直在嘗試在現代OpenGL中使用VAO和VBO,但我無法讓它們繪製。我的着色器非常簡單,但根據我一直試圖遵循的教程,他們應該工作。我沒有收到任何錯誤,但仍然無法正常工作。我收到的只是一個完全黑色的窗口。如果有人能夠幫助我瞭解我的問題在哪裏以及如何解決問題,我將不勝感激。我希望我不重複先前的問題,但是我已經搜索和搜索,沒有找到任何解決這個問題的方法。這裏是我的代碼:OpenGL - 無法獲取頂點陣列對象和頂點緩衝區對象繪製
vertexShader.glsl:
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
void main(){
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
fragmentShader.glsl
#version 330 core
out vec4 color;
void main(){
color = vec4(1.0, 1.0, 0.0, 1.0);
}
這裏是我的加載着色器代碼,裏面有工作,沒有提供任何錯誤:
//Note: PXConsole is a util class for printing to the console.
GLuint loadShaders(std::string vertexPath, std::string fragmentPath){
const char* vertexShaderPath = vertexPath.c_str();
const char* fragmentShaderPath = fragmentPath.c_str();
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertexShaderPath, std::ios::in);
if(VertexShaderStream.is_open()){
std::string Line = "";
while(getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
}else{
std::string error ="Could not open vertex shader at \"" + vertexPath +"\". Is the the path written correctly? ";
PXConsole::err(error);
return 0;
}
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragmentShaderPath, std::ios::in);
if(FragmentShaderStream.is_open()){
std::string Line = "";
while(getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}else{
std::string error ="Could not open fragment shader at \"" + fragmentPath +"\". Is the the path written correctly? ";
PXConsole::err(error);
return 0;
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
PXConsole::info("Compiling Vertex Shader at: " + vertexPath);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0){
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
PXConsole::err(&VertexShaderErrorMessage[0]);
}
// Compile Fragment Shader
PXConsole::info("Compiling Fragment Shader at: " + fragmentPath);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0){
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
PXConsole::err(&FragmentShaderErrorMessage[0]);
}
// Link the program
PXConsole::info("Linking Shader Program!");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0){
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
PXConsole::err(&ProgramErrorMessage[0]);
}
glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
這是我用SDL2創建的OpenGL上下文:
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
appWindow = SDL_CreateWindow("Window Title", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL);
if (!application->appWindow) {
PXConsole::err("Couldn't Initialize Window!!");
endApp();
}
appGLContext = SDL_GL_CreateContext(appWindow);
而且最後這裏是我的渲染功能,這是一個循環:
void render(){
GLuint vaoID;
GLuint posVBO;
GLfloat positions[] = {-0.5f, -0.5f, 1.0f,
0.5f, -0.5f, 1.0f,
0.5f, 0.5f, 1.0f,
-0.5f, 0.5f, 1.0f};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//shaderProgramID = the function mentioned above in an initializating function and has no errors finding the shader files
glUseProgram(shaderProgramID);
glColor4f(1.0, 1.0, 0.0, 1.0);
glGenVertexArrays(1, &vaoID);
glBindVertexArray(vaoID);
glGenBuffers(1, &posVBO);
glBindBuffer(GL_ARRAY_BUFFER, posVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, posVBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glColor4f(1.0, 0.0, 0.0, 1.0);
glDrawArrays(GL_QUADS, 0, 4);
glDisableVertexAttribArray(0);
SDL_GL_SwapWindow(appWindow);
}
我希望這是足夠的代碼,以便能夠確定問題。謝謝你的幫助!
非常感謝您的幫助和建議!我更新以正確的方式使用OpenGL。我在每幀中生成緩衝區的原因是因爲我習慣於改變對象的位置以使其移動,而不是使用OpenGL相機。我不認爲我正在檢查OpenGL錯誤。我應該怎麼做?而且你的解決方案几乎可以完美工作,除了調用glDisableVertexAttribArray(0)只允許形狀出現在一個框架上,然後消失。我應該在節目結束時打電話嗎?但真的,再次感謝您的幫助和建議! – Gyo
嗯,對不起。那一個溜走了。你不必這麼叫。這隻有在不使用VAO時纔有意義。在解決問題時,可以在'glDeleteVertexArray'方法中完成。 – BDL
對於位置更新:請參閱答案中的更新。 – BDL