带有 GLFW 和 GLEW 的 OpenGL 应用程序崩溃
Posted
技术标签:
【中文标题】带有 GLFW 和 GLEW 的 OpenGL 应用程序崩溃【英文标题】:OpenGL app with GLFW and GLEW crashes 【发布时间】:2014-01-30 05:07:24 【问题描述】:问题: 我尝试编写一个类来绘制可点击的矩形,问题是因为我开始在程序中使用新的 OpenGL 版本(4.0),它不会渲染,并且在读取位置 0x00000000 时给我运行时错误错误。 我将在底部包含类的代码以及主循环。
GUI::GUI(std::string name, int top, int left,int heigh, int width, bool isvisible, void(_cdecl * func)())
Name=name;
Top=top;
Left=left;
Heigh=heigh;
Width=width;
BackColor = struct_RGB();
glClearColor(0.0f, 0.0f, 0.4f, 1.0f);
BackDrawFunc=func;
Visibility=isvisible;
GuiObj = std::vector<GUIOBJ *>();
vertices = std::vector<float>();
vertices.clear();
for(unsigned int i=0; i<GuiObj.size(); i++)
GuiObj[i]->addVertices();
;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &VBO);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW);
program = LoadShaders("res/VertexShader.glsl", "res/FragmentShader.glsl");
void GUI::Draw()
glClear(GL_COLOR_BUFFER_BIT);
// Use our shader
glUseProgram(program);
// 1rst attribute buffer : vertices
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
vertices.size(), // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, vertices.size()); // 3 indices starting at 0 -> 1 triangle
printf("drawing\n");
glDisableVertexAttribArray(0);
void main()
init();
//Main Loop
while(!glfwWindowShouldClose(Window))
if (glfwGetKey(Window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(Window, GL_TRUE);
Test->Draw();
glfwSwapBuffers(Window);
glfwPollEvents();
//Termination
glfwTerminate();
编辑: 我将所有代码复制到同一个文件中,错误已解决,但仍无法呈现
#include "extincludes.h"
#include <vector>
#include <fstream>
#include <sstream>
GLFWwindow* Window;
typedef unsigned int GLuint;
GLuint VertexArrayID;
GLuint VBO;
GLuint program;
GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path)
// 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 = std::ifstream(vertex_file_path, std::ios::in);
if (!VertexShaderStream.is_open()) VertexShaderStream.open(vertex_file_path, std::ios::in);
if(VertexShaderStream.is_open())
std::string Line = "";
while(getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
else
printf("Couldn't open VertexShader");
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open())
std::string Line = "";
while(getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
else
printf("Couldn't open FragmentShader");
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
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);
std::vector<char> VertexShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
// Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
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);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
// Link the program
fprintf(stdout, "Linking program\n");
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);
std::vector<char> ProgramErrorMessage( glm::max(InfoLogLength, int(1)) );
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
void main()
//GLFW
printf("started init of GLFW \n");
if (!glfwInit())
printf("startup of GLFW errored \n");
printf("started GLFW \n");
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //excluding old openGL functionality
Window = glfwCreateWindow(640, 768, "Simple example", NULL, NULL);
printf("attempt to create window \n");
if (!Window)
glfwTerminate();
exit(EXIT_FAILURE);
glfwMakeContextCurrent(Window);
printf("Init of GLFW done \n");
//GLEW
printf("start init of GLEW \n");
glewExperimental = true; // Needed for core profile
printf("using experimental version of GLEW\n");
if (glewInit() != GLEW_OK)
printf("Failed to initialize GLEW\n");
printf("done with GLEW\n");
if (glfwGetCurrentContext()!=Window)
printf("context error");
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
program = LoadShaders("res/VertexShader.glsl", "res/FragmentShader.glsl");
std::vector<float> vertices = std::vector<float>();
vertices.clear();
//triangle 1
vertices.push_back(1);
vertices.push_back(1);
vertices.push_back(0);
vertices.push_back(1);
vertices.push_back(0);
vertices.push_back(3);
//triangle 2
vertices.push_back(1);
vertices.push_back(1);
vertices.push_back(0);
vertices.push_back(1);
vertices.push_back(0);
vertices.push_back(3);
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &VBO);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
//Main Loop
while(!glfwWindowShouldClose(Window))
if (glfwGetKey(Window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(Window, GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT);
// Use our shader
glUseProgram(program);
// 1rst attribute buffer : vertices
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(VertexArrayID);
// Draw the triangle !
printf("everything setup we can draw \n");
glDrawArrays(GL_TRIANGLES, 0, vertices.size()); // 3 indices starting at 0 -> 1 triangle
printf("drawing\n");
glfwSwapBuffers(Window);
glfwPollEvents();
//Termination
glDisableVertexAttribArray(0);
glfwDestroyWindow(Window);
glfwTerminate();
【问题讨论】:
使用跟踪语句或调试器尝试隔离在哪里发生故障。除此之外,请先尝试glewExperimental = true;
,然后再致电glewInit();
你打电话给glewInit()
了吗?
是的,我没有添加初始化阶段,但 glew 设置正确。 glDrawArrays 也发生了崩溃,我忘了提
顺便说一句,您没有有效地使用 VAO。如果您按照预期的方式使用它们,您就不必每次调用GUI::Draw (...)
时都调用glBindBuffer (...)
、glEnableVertexAttribArray (...)
和glVertexAttribPointer (...)
。您所要做的就是绑定您的 VAO 并绘制。
请显示GUI
的对象在哪里被实例化。我相信您在拥有 OpenGL 上下文之前就实例化了GUI
,这可以解释很多。如果在你有上下文之前调用了那个构造函数,你会很抱歉。
【参考方案1】:
我发现崩溃的错误只是你需要三个维度而不是一个维度。这导致了draw函数读取超出范围的错误......
【讨论】:
它仍然没有渲染四边形 :(以上是关于带有 GLFW 和 GLEW 的 OpenGL 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章