我最近遇到过使用openGL的问题。在我之前运行良好的程序中,我尝试在屏幕上绘制一组多边形,但程序会抛出一个错误,而对于我的生活,我无法找到它的原因。我几乎从我的代码中没有改变,它只是在一个月后回到它之后的一天开始抛出错误。错误是:
Unhandled exception at 0x69F2883E (nvoglv32.dll) in openGLtest.exe:
0xC0000005: Access violation reading location 0x00000000.
我已使用以下代码重现了错误。我注意到的一些更奇怪的行为是,如果我将对glDrawArrays的调用更改为:
glDrawArrays(GL_TRIANGLES, 3, numV);
或
glDrawArrays(GL_TRIANGLES, 0, 258);
然后程序不会抛出错误,但显然它没有正确渲染,只渲染矩形的一半,或渲染矩形加上一些垃圾输入。
这很奇怪,如果它渲染超过255点它可以正常工作但不会更少,它会引发错误。
#include <SDL.h>
#include <GL/glew.h>
#include <math.h>
#include <vector>
struct Vector2f{
public:
float x, y;
Vector2f() {}
Vector2f(float _x, float _y) { x = _x; y = _y; }
};
struct Vector3f {
public:
float x, y, z;
Vector3f() { x = 0.0, y = 0.0, z = 0.0; }
Vector3f(float _x, float _y, float _z) { x = _x; y = _y; z = _z; }
};
struct Vertex {
Vector3f m_pos;
Vector2f m_tex;
Vector3f m_normal;
Vertex() {}
Vertex(Vector3f pos, Vector2f tex) {
m_pos = pos;
m_tex = tex;
m_normal = Vector3f(0.0f, 0.0f, 0.0f);
}
Vertex(Vector3f pos, Vector2f tex, Vector3f norm) {
m_pos = pos;
m_tex = tex;
m_normal = norm;
}
};
SDL_Window* Window_Display = NULL;
SDL_GLContext glcontext;
GLuint VBO;
int width = 800;
int height = 600;
float ratio = (float)width / (float)height;
int numV;
std::vector<Vertex> _VBO;
bool initWindow() {
//draw a square
_VBO.push_back(Vertex(Vector3f(-0.8f, -0.8f, 0.0f), Vector2f(0.0f, 0.0f), Vector3f(0.0f, 0.0f, 0.0f)));
_VBO.push_back(Vertex(Vector3f(0.8f, -0.8f, 0.0f), Vector2f(0.0f, 0.0f), Vector3f(0.0f, 0.0f, 0.0f)));
_VBO.push_back(Vertex(Vector3f(0.8f, 0.8f, 0.0f), Vector2f(0.0f, 0.0f), Vector3f(0.0f, 0.0f, 0.0f)));
_VBO.push_back(Vertex(Vector3f(-0.8f, -0.8f, 0.0f), Vector2f(0.0f, 0.0f), Vector3f(0.0f, 0.0f, 0.0f)));
_VBO.push_back(Vertex(Vector3f(-0.8f, 0.8f, 0.0f), Vector2f(0.0f, 0.0f), Vector3f(0.0f, 0.0f, 0.0f)));
_VBO.push_back(Vertex(Vector3f(0.8f, 0.8f, 0.0f), Vector2f(0.0f, 0.0f), Vector3f(0.0f, 0.0f, 0.0f)));
numV = 6;
if (SDL_Init(SDL_INIT_VIDEO) < 0) return false;
if ((Window_Display = SDL_CreateWindow("OpenGL Drawing Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL)) == NULL) return false;
glcontext = SDL_GL_CreateContext(Window_Display);
glewInit();
return true;
}
bool drawScene() {
glEnableClientState(GL_VERTEX_ARRAY);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, numV * sizeof(Vertex), &_VBO[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20);
glDrawArrays(GL_TRIANGLES, 0, numV); //Unhandled exception at 0x69F2883E (nvoglv32.dll) in openGLtest.exe: 0xC0000005: Access violation reading location 0x00000000.
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
SDL_GL_SwapWindow(Window_Display); //Send the 3D scene to the screen
glDisableClientState(GL_VERTEX_ARRAY);
return true;
}
int main(int argc, char* args[]) {
if (initWindow()) {
while (drawScene()) {}
}
return 0;
}