OpenGL窗口变黑

时间:2015-01-23 15:06:44

标签: c++ opengl

在开发过程中,基于OpenGL的点云渲染器遇到了一个非常令人不安的问题。

我的第一种方法是直接可视化点云 - 在一个DrawArrays()命令中,我渲染了超过1500万点云。一切都很好,直到我的VRAM上有足够的内存来存储整点云 - 如果不是我从Nvidia OpenGL驱动程序收到错误,告诉我我的计算机不符合应用程序规范。

所以我已经搜索了一下,我已经知道我必须将我的点云划分为多个块并为每个块调用DrawArray()。因此,为了测试它,我创建了一个包含大约60 000个点的点云,我正在加载数百次以模拟前面描述的行为。

在调用次数而不是OpenGL驱动程序错误后,我的opengl窗口变为黑色。当我将一个块中的点数更改为40 000时,我设法加载并显示超过600万个没有黑屏的点。

所以我有很多问题:

  1. 为什么会出现这样的事情?

  2. 我该如何避免这种行为?

  3. 我如何预测这种行为?

  4. 为什么会出现这样的事情时没有opengl错误(是的,我已经检查过)?

  5. 我的点云基本上是:

    std::vector<Point3D<float>> vfLXYZ; 
    std::vector<Point4D<unsigned char>> vucRGBA;
    

    其中:

    template <class T>
    union Point4D
    {
        T data[4];
            struct{
                T R;
                T G;
                T B;
                T A;
            };
    };
    
    template <class T>
    union Point3D
    {
        T data[3];
            struct{
                T x;
                T y;
                T z;
            };
    };
    

    OpenGL上下文创建:

    bool OpenGLContext::create30Context(HDC hdc) {
        this->hdc = hdc;
    
        PIXELFORMATDESCRIPTOR pfd; 
        memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); 
        pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); 
        pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; 
        pfd.iPixelType = PFD_TYPE_RGBA; 
        pfd.cColorBits = 32;
        pfd.cDepthBits = 32;
        pfd.iLayerType = PFD_MAIN_PLANE; 
    
        int nPixelFormat = ChoosePixelFormat(hdc, &pfd); 
        if (nPixelFormat == 0) 
            return false;
    
        bool bResult = SetPixelFormat(hdc, nPixelFormat, &pfd); 
        if (!bResult) 
            return false;
    
        HGLRC tempOpenGLContext = wglCreateContext(hdc);
        wglMakeCurrent(hdc, tempOpenGLContext); /
    
        GLenum error = glewInit(); 
        if (error != GLEW_OK) 
            return false;
    
        int attributes[] = {
            WGL_CONTEXT_MAJOR_VERSION_ARB, 4, 
            WGL_CONTEXT_MINOR_VERSION_ARB, 2, 
            WGL_CONTEXT_FLAGS_ARB,WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, 
        WGL_CONTEXT_PROFILE_MASK_ARB,WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
            0
        };
    
        if (wglewIsSupported("WGL_ARB_create_context") == 1) { 
            hrc = wglCreateContextAttribsARB(hdc, NULL, attributes); 
            wglMakeCurrent(NULL, NULL); 
            wglDeleteContext(tempOpenGLContext); 
            wglMakeCurrent(hdc, hrc); 
        }
        else {
            hrc = tempOpenGLContext; 
            return false;
        }
    
        int glVersion[2] = { -1, -1 }; /
        glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]);
        glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); 
    
        return true; 
    }
    

    缓冲区初始化(遍历所有点云):

    glBindVertexArray(pxCloudHeader.uiVBA);
    
            glBindBuffer(GL_ARRAY_BUFFER, pxCloudHeader.xVBOs.uiVBO_XYZ); 
            glBufferData(GL_ARRAY_BUFFER, iPointCount * sizeof(GLfloat) * 3, &p3DfXYZ->data[0], GL_STREAM_DRAW); 
            glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); 
            glEnableVertexAttribArray(0); 
    
            glBindBuffer(GL_ARRAY_BUFFER, pxCloudHeader.xVBOs.uiVBO_RGBA); 
            glBufferData(GL_ARRAY_BUFFER, iPointCount * sizeof(GLubyte) * 4, &p4DfRGBA->data[0], GL_STREAM_DRAW); 
            glVertexAttribPointer((GLuint)1, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0); 
            glEnableVertexAttribArray(1); 
    
    glBindVertexArray(0);
    

    点云渲染(遍历所有点云):

    glBindVertexArray(pxCloudHeader.uiVBA);
            // iLOD is a Level Of Detail
            glBindBuffer(GL_ARRAY_BUFFER, pxCloudHeader.xVBOs.uiVBO_XYZ);
            glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float) * iLOD, 0);
    
            glBindBuffer(GL_ARRAY_BUFFER, pxCloudHeader.xVBOs.uiVBO_RGBA);
            glVertexAttribPointer((GLuint)1, 4, GL_UNSIGNED_BYTE, GL_FALSE, 4 * sizeof(unsigned char)*iLOD, 0);
    
            glDrawArrays(GL_POINTS, 0, pxCloudHeader.iPointsCount / iLOD);
    
    glBindVertexArray(0);
    

    主要渲染功能:

        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);   
    
        glClearDepth(fFar); 
    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    
        RenderPointCloud();
    
        SwapBuffers(hdc);
    

    我的渲染代码很简单,所以我发布了一些我认为可以解决问题的东西。如果你想了解更多(着色器代码等),请写评论,我将编辑我的帖子。我向你保证,除了这个问题,渲染效果还不错。

    另外我注意到当我的opengl窗口黑色应用程序没有停止工作时 - 点云渲染循环正在执行bu MUCH SLOWER而不是预期。此外,我的单线程应用程序开始表现得像双线程 - 它消耗的CPU使用率是黑窗口崩溃前的两倍。

    其他一些信息:

    • 我正在使用VS2013和x64编译器,

    • 拥有32GB内存,

    • 拥有2 GB VRAM(GeForce GTX 760M),

    • 拥有最新的图形卡驱动程序

0 个答案:

没有答案