现在我正在使用Visual Studio 2015编写一个基本的OpenGL包装器,我遇到了这个非常奇怪的现象,当我在调试模式下构建和运行时,我的立方体不会呈现.然而,在发布模式下,一切看起来都很完美.
值得注意的是,程序确实在调试模式下运行,它确实用我设置的绿色清除了屏幕.因此看起来OpenGL在一定程度上起作用.问题是它没有像在Release模式下那样渲染我的立方体网格物体.我已经通过调试确认我的资源(着色器和图像文件)正在调试模式下正确加载,所以这似乎不是问题.
代码方面,以下是该计划的有趣部分:
在Main.cpp中:
renderer.Clear(0.2f, 0.3f, 0.3f, 1.0f); for(GLuint i = 0; i < 10; ++i) { renderer.PushMatrix(); renderer.Translate(cubePositions[i].x, cubePositions[i].y, cubePositions[i].z); renderer.Rotate(20.0f * i, glm::vec3(1.0f, 0.3f, 0.5f)); renderer.Render(cube); renderer.PopMatrix(); } window.SwapBuffers();
在Renderer.cpp中:
void Renderer::updateMVP() const { glm::mat4 _proj = camera.GetProjectionMatrix(); glm::mat4 _view = camera.GetViewMatrix(); glm::mat4 _model = model.top(); glUniformMatrix4fv(glGetUniformLocation(shader.GetProgram(), "projection"), 1, GL_FALSE, glm::value_ptr(_proj)); glUniformMatrix4fv(glGetUniformLocation(shader.GetProgram(), "view"), 1, GL_FALSE, glm::value_ptr(_view)); glUniformMatrix4fv(glGetUniformLocation(shader.GetProgram(), "model"), 1, GL_FALSE, glm::value_ptr(_model)); } void Renderer::Clear(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) const { glClearColor(red, green, blue, alpha); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void Renderer::Render(const Mesh& mesh) const { shader.Use(); updateMVP(); mesh.Render(this->shader); }
在Mesh.cpp中:
void Mesh::Render(const Shader& shader) const { assert(this->VAO); for (GLuint i = 0; i < this->textures.size(); ++i) { shader.BindTexture(this->textures[i], i); } glBindVertexArray(this->VAO); glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0); glBindVertexArray(0); for (GLuint i = 0; i < this->textures.size(); ++i) { shader.UnbindTexture(i); } }
我使用以下(静态)库:GLEW,GLFW,SOIL2
我也在使用仅限标题的库:GLM
在构建静态库时,我确保它们都是使用Visual Studio的v140 Platform工具集构建的.我在Debug和Release中构建了每个静态库.Debug版本都是使用/ MDd CRT构建的,Release版本是使用/ MD CRT构建的.
我的所有代码和项目配置文件都是开源的:Github
任何帮助是极大的赞赏!谢谢.
问题:
我觉得很傻.我放置了一堆glError检查,我设法将问题查明到我的函数生成立方体网格我依赖于RVO.但是使用visual studio RVO显然只能在Release模式下完成而不是Debug模式.所以我的网格析构函数一旦被创建就被调用,在它被渲染之前将其从GPU内存中移除.
解决方案:
始终始终遵循5规则.解决方案是简单地添加复制并将构造函数/赋值运算符移动到我的Mesh和Texture类,以防止重新分配其托管资源.
网格析构函数:
Mesh::~Mesh() { glDeleteVertexArrays(1, &this->VAO); glDeleteBuffers(1, &this->VBO); glDeleteBuffers(1, &this->EBO); }
立方体创建功能:
sr::Mesh createCube() { sr::Mesh mesh; mesh.AddTexture(sr::Texture("wood_container.jpg", "Texture1")); mesh.AddTexture(sr::Texture("awesome_face.png", "Texture2")); glm::vec3 p1(-0.5f, -0.5f, 0.5f); glm::vec3 p2( 0.5f, -0.5f, 0.5f); glm::vec3 p3( 0.5f, 0.5f, 0.5f); glm::vec3 p4(-0.5f, 0.5f, 0.5f); glm::vec3 p5( 0.5f, -0.5f, -0.5f); glm::vec3 p6(-0.5f, -0.5f, -0.5f); glm::vec3 p7(-0.5f, 0.5f, -0.5f); glm::vec3 p8( 0.5f, 0.5f, -0.5f); glm::vec2 tc00(0.0f, 0.0f); glm::vec2 tc01(0.0f, 1.0f); glm::vec2 tc10(1.0f, 0.0f); glm::vec2 tc11(1.0f, 1.0f); glm::vec3 norm; GLuint v1, v2, v3, v4, v5, v6, v7, v8; // Front norm = glm::vec3(0.0f, 0.0f, 1.0f); v1 = mesh.AddVertex(p1, norm, tc00); v2 = mesh.AddVertex(p2, norm, tc10); v3 = mesh.AddVertex(p3, norm, tc11); v4 = mesh.AddVertex(p4, norm, tc01); mesh.AddTriangle(v1, v2, v3); mesh.AddTriangle(v1, v3, v4); // Back norm = glm::vec3(0.0f, 0.0f, -1.0f); v5 = mesh.AddVertex(p5, norm, tc00); v6 = mesh.AddVertex(p6, norm, tc10); v7 = mesh.AddVertex(p7, norm, tc11); v8 = mesh.AddVertex(p8, norm, tc01); mesh.AddTriangle(v5, v6, v7); mesh.AddTriangle(v5, v7, v8); // Right norm = glm::vec3(1.0f, 0.0f, 0.0f); v2 = mesh.AddVertex(p2, norm, tc00); v5 = mesh.AddVertex(p5, norm, tc10); v8 = mesh.AddVertex(p8, norm, tc11); v3 = mesh.AddVertex(p3, norm, tc01); mesh.AddTriangle(v2, v5, v8); mesh.AddTriangle(v2, v8, v3); // Left norm = glm::vec3(-1.0f, 0.0f, 0.0f); v6 = mesh.AddVertex(p6, norm, tc00); v1 = mesh.AddVertex(p1, norm, tc10); v4 = mesh.AddVertex(p4, norm, tc11); v7 = mesh.AddVertex(p7, norm, tc01); mesh.AddTriangle(v6, v1, v4); mesh.AddTriangle(v6, v4, v7); // Top norm = glm::vec3(0.0f, 1.0f, 0.0f); v4 = mesh.AddVertex(p4, norm, tc00); v3 = mesh.AddVertex(p3, norm, tc10); v8 = mesh.AddVertex(p8, norm, tc11); v7 = mesh.AddVertex(p7, norm, tc01); mesh.AddTriangle(v4, v3, v8); mesh.AddTriangle(v4, v8, v7); // Bottom norm = glm::vec3(0.0f, -1.0f, 0.0f); v6 = mesh.AddVertex(p6, norm, tc00); v5 = mesh.AddVertex(p5, norm, tc10); v2 = mesh.AddVertex(p2, norm, tc11); v1 = mesh.AddVertex(p1, norm, tc01); mesh.AddTriangle(v6, v5, v2); mesh.AddTriangle(v6, v2, v1); mesh.Build(); return mesh; }