I am currently writing an OpenGL game engine, in which I am currently experiencing a crash every 1 out of 6 times. The error message with Visual Studio 2015 is:
Exception thrown at 0x545579C6 (nvoglv32.dll). Access violation reading location 0x085C2000.
It points to either the end of the main method, or this line of code in the OBJ Loader class:
return renderer::Model3D( final_vertices, final_uvs, final_normals, final_indices, position, shader); I believe that it is a rendering issue on my behalf, relating to an Nvidia driver problem, or a GLFW/GLEW problem.
Here are the Renderer3D init, flush and submit methods:
void Batch::init(std::vector<const Model3D*> models) { glGenVertexArrays(1, &pr_VAO); glGenBuffers(1, &pr_VBO); glBindVertexArray(pr_VAO); glBindBuffer(GL_ARRAY_BUFFER, pr_VBO); glBufferData(GL_ARRAY_BUFFER, RENDERER_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); glEnableVertexAttribArray(SHADER_VERTEX_INDEX); glEnableVertexAttribArray(SHADER_UV_INDEX); glEnableVertexAttribArray(SHADER_NORMAL_INDEX); glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const GLvoid*)0); glVertexAttribPointer(SHADER_UV_INDEX, 2, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const GLvoid*)(offsetof(renderer::VertexData, renderer::VertexData::uv))); glVertexAttribPointer(SHADER_NORMAL_INDEX, 3, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const GLvoid*)(3 * sizeof(GL_FLOAT))); for (const Model3D* model : models) { std::vector<unsigned short> indices = model->getIndices(); pr_IBO = new buffers::IndexBuffer(indices, RENDERER_INDICIES_SIZE); } glBindBuffer(GL_ARRAY_BUFFER, 0); } void Batch::flush() { glBindVertexArray(pr_VAO); pr_IBO->bind(); glDrawElements(GL_TRIANGLES, 128, GL_UNSIGNED_SHORT, NULL); pr_IBO->unbind(); glBindVertexArray(0); indexCount = 0; } void Batch::submit(const renderer::Model3D* renderable) { std::vector<glm::vec3> vertices = renderable->getVertices(); std::vector<glm::vec2> texCoords = renderable->getTexCoords(); std::vector<glm::vec3> normals = renderable->getNormals(); for (int i = 0; i < vertices.size(); i++) { pr_Buffer->vertex = vertices.at(i); pr_Buffer->uv = texCoords.at(i); pr_Buffer->normal = normals.at(i); pr_Buffer++; } indexCount += 6; } Here is the OBJLoader's LoadOBJ method:
renderer::Model3D OBJLoader::LoadOBJ (const char* filePath, glm::vec3 position, shaders::Shader& shader) { std::vector < glm::vec3 > temp_vertices; std::vector < glm::vec2 > temp_uvs; std::vector < glm::vec3 > temp_normals; std::vector < unsigned short> temp_indices; std::vector < glm::vec3 > out_vertices; std::vector < glm::vec2 > out_uvs; std::vector < glm::vec3 > out_normals; std::vector < unsigned short> out_indices; std::vector < glm::vec3 > final_vertices; std::vector < glm::vec2 > final_uvs; std::vector < glm::vec3 > final_normals; std::vector < unsigned short> final_indices; std::vector< unsigned int > vertexIndices, uvIndices, normalIndices; FILE * file = fopen(filePath, "r"); if (file == NULL) { printf("Impossible to open the file!\n"); getchar(); } while (1) { char lineHeader[128]; int res = fscanf(file, "%s", lineHeader); if (res == EOF) break; if (strcmp(lineHeader, "v") == 0) { glm::vec3 vertex; fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z); temp_vertices.push_back(vertex); } else if (strcmp(lineHeader, "vt") == 0) { glm::vec2 uv; fscanf(file, "%f %f\n", &uv.x, &uv.y); uv.y = -uv.y; temp_uvs.push_back(uv); } else if (strcmp(lineHeader, "vn") == 0) { glm::vec3 normal; fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z); temp_normals.push_back(normal); } else if (strcmp(lineHeader, "f") == 0) { std::string vertex1, vertex2, vertex3; unsigned int vertexIndex[3], uvIndex[3], normalIndex[3]; int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2]); if (matches != 9) { printf("File can't be read\n"); } vertexIndices.push_back(vertexIndex[0]); vertexIndices.push_back(vertexIndex[1]); vertexIndices.push_back(vertexIndex[2]); uvIndices.push_back(uvIndex[0]); uvIndices.push_back(uvIndex[1]); uvIndices.push_back(uvIndex[2]); normalIndices.push_back(normalIndex[0]); normalIndices.push_back(normalIndex[1]); normalIndices.push_back(normalIndex[2]); } else { char stupidBuffer[1000]; fgets(stupidBuffer, 1000, file); } } for (unsigned int i = 0; i<vertexIndices.size(); i++) { unsigned int vertexIndex = vertexIndices[i]; unsigned int uvIndex = uvIndices[i]; unsigned int normalIndex = normalIndices[i]; glm::vec3 vertex = temp_vertices[vertexIndex - 1]; glm::vec2 uv = temp_uvs[uvIndex - 1]; glm::vec3 normal = temp_normals[normalIndex - 1]; out_vertices.push_back(vertex); out_uvs.push_back(uv); out_normals.push_back(normal); } indexVBO(out_vertices, out_uvs, out_normals, final_indices, final_vertices, final_uvs, final_normals); return renderer::Model3D (final_vertices, final_uvs, final_normals, final_indices, position, shader); } } Finally, the main method:
int main() { Window window(800, 600, "Proton"); Shader shader("src/shaders/vertexShader.txt", "src/shaders/fragmentShader.txt"); shader.enable(); shader.setUniform3f("lightPosition", glm::vec3(4, 3, 3)); shader.setUniform3f("lightColour", glm::vec3(1, 1, 1)); GLuint texture = Texture::loadImage("res/textures/texture.bmp"); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); shader.setUniform1i("texture1", 0); Model3D model = OBJLoader::LoadOBJ("res/models/cube.obj", glm::vec3(0, 0, 0), shader); std::vector<const Model3D*> models; models.push_back(&model); Batch renderer(models); std::cout << glGetError() << std::endl; while (!window.shouldClose()) { window.clear(); glm::mat4 pr_matrix = glm::perspective(glm::radians(70.0f), 800.0f / 600.0f, 0.1f, 100.0f); glm::mat4 vw_matrix = glm::lookAt(glm::vec3(12, 9, 9), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); glm::mat4 matrix = glm::mat4(1.0f); shader.setUniformMat4("ml_matrix", matrix); shader.setUniformMat4("pr_matrix", pr_matrix); shader.setUniformMat4("vw_matrix", vw_matrix); renderer.begin(); renderer.submit(&model); renderer.end(); renderer.flush(); window.update(); } shader.disable(); return 0; }