【问题标题】:How to debug openGL code?如何调试openGL代码?
【发布时间】:2014-05-24 14:58:43
【问题描述】:

我在进行 OpenGL 调试时遇到问题。我发现很多时候,OpenGL 会通过不绘制任何东西来告诉你它失败了。每次代码看起来都很好,但它没有在 GL 窗口上绘制任何东西。

例如考虑下面的代码。我写它来绘制立方体,但它没有绘制任何东西,我无法找到原因。

================================================ =========

// cube_vertex_array.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include <glut.h>

static GLfloat vertex[]=
                        {
                            100.0,100.0,0.0,
                            400.0,100.0,0.0,
                            400.0,400.0,0.0,
                            100.0,400.0,0.0,
                            100.0,100.0,-300.0,
                            400.0,100.0,-300.0,
                            400.0,400.0,-300.0,
                            100.0,400.0,-300.0
                    };

static GLfloat color[]=
                        {
                            1.0,0.0,0.0,
                            0.0,1.0,0.0,
                            0.0,0.0,1.0,
                            1.0,1.0,0.0,
                            1.0,0.0,1.0,
                            0.0,1.0,1.0
                        };


static GLubyte frontIndices[] = {0,1,2,3};
static GLubyte leftIndices[] = {1,5,6,2};
static GLubyte backIndices[] = {4,7,6,5};
static GLubyte rightIndices[] = {0,3,7,4};
static GLubyte topIndices[] = {3,2,6,7};
static GLubyte bottomIndices[] = {0,4,5,1};

void init(void)
{
    glClearColor(0.0,0.0,0.0,0.0);                              //Set default background color to black.
    glClearDepth(2.0);                                      //Set the depth level for clearing depth buffer.
    glShadeModel(GL_FLAT);                                  //Set the     shading model to FLAT
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     //Clear the color and depth buffer.
}

void Display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     //Clear the color and depth buffer.

glColor3f(1.0,0.0,0.0);

//glBegin(GL_LINE_STRIP);
//  glVertex3f(0.0,0.0,0.0);
//  glVertex3f(200.0,100.0,0.0);
//glEnd();  

glEnableClientState(GL_VERTEX_ARRAY);                   //Enable vertex array.
glEnableClientState(GL_COLOR_ARRAY);                    //Enable vertex array color.

glColorPointer(3,GL_FLOAT,0,color);                     //Specify the array for colors.
glVertexPointer(3,GL_FLOAT,0,vertex);                   //Specify the array for vertex.

glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,frontIndices);      //Draw front face.
glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,leftIndices);       //Draw left face.
glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,backIndices);       //Draw back face.
glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,rightIndices);      //Draw right face.
glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,topIndices);        //Draw top face.
glDrawElements(GL_QUADS,4,GL_UNSIGNED_BYTE,bottomIndices);     //Draw bottom face.

glutSwapBuffers();               //Swap the buffers.
}

void Reshape(int w,int h)
{
    glViewport(0.0,(GLsizei)w,0.0,(GLsizei)h);           //Set the viewport according to new window size.
    glMatrixMode(GL_PROJECTION);                         //Set matrix mode to projection.
    glLoadIdentity();                                    //Replace the top matrix in the stack to the identity matrix.
    gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);         //Set the orthographic projection.
    glMatrixMode(GL_MODELVIEW);                          //Set matrix mode to modelview.
}

int main(int argc, char **argv)
{
    glutInit(&argc,argv);                             //Initialize the glut.
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);      //Set display mode and also enable double buffering.
    glutInitWindowSize(500,500);                      //Set the initial window size.
    glutCreateWindow("Cube");                         //Create the window and also assign name to it.
    init();                                           //Initialize the app.
    glutDisplayFunc(Display);                         //Register the Display function.
    glutReshapeFunc(Reshape);                         //Register the Reshape function.
    glutMainLoop();                                   //Start the main loop.
    return 0;
}

【问题讨论】:

  • 您可以使用 KHR_debug_output(或者在您的情况下为 ARB_debug_output)来获取有关 OpenGL 正在做什么的更多信息。此外,某些绑定,如glad (glad.dav1d.de) 可以生成调试模式绑定,带有前后回调,将在每次调用时自动检查 GL 错误。

标签: c++ c opengl visual-c++ opengl-3


【解决方案1】:

您已在 glDrawElements() 中将 GL_UNSIGNED_BYTE 作为类型参数。这将导致 openGL 将您输入的索引数组解释为每个索引一个字节。您应该在此处使用 GL_UNSIGNED_INT。

这是基于您提供的代码的工作代码(我确实将它移植到了 java):

import java.nio.ByteBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import static org.lwjgl.opengl.GL11.*;

public class GLTest {
    public static void main(String[] args) {
        try {
            Display.create();
            Display.setDisplayMode(new DisplayMode(500, 500));
            Display.setResizable(true);

            //the same arrays as the ones you specified.

            float[] vertices = new float[]{100.0f,100.0f,0.0f,
                    400.0f,100.0f,0.0f,
                    400.0f,400.0f,0.0f,
                    100.0f,400.0f,0.0f,
                    100.0f,100.0f,-300.0f,
                    400.0f,100.0f,-300.0f,
                    400.0f,400.0f,-300.0f,
                    100.0f,400.0f,-300.0f};

            float[] color = new float[]{1,0,0,
                    0,1,0,
                    0,0,1,
                    1,1,0,
                    1,0,1,
                    0,1,1};

            int[] frontIndices = new int[]{0, 1, 2, 3};


            //JWJGL bookkeeping.. 
            ByteBuffer vertexBuffer = BufferUtils.createByteBuffer(vertices.length * 4);
            ByteBuffer colourBuffer = BufferUtils.createByteBuffer(color.length * 4);

            for(int i = 0; i < vertices.length; i++) {
                vertexBuffer.putFloat(vertices[i]);
            }
            vertexBuffer.rewind();

            for(int i = 0; i < color.length; i++) {
                colourBuffer.putFloat(color[i]);
            }
            colourBuffer.rewind();


            ByteBuffer indexBuffer = BufferUtils.createByteBuffer(4 * frontIndices.length);
            for(int i = 0; i < frontIndices.length; i++) {
                indexBuffer.putInt(frontIndices[i]);
            }
            indexBuffer.rewind();

            //back you your code

            glClearColor(1,1,1,1);
            glShadeModel(GL_SMOOTH);

            while(!Display.isCloseRequested()) {
                glViewport(0, 0, Display.getWidth(), Display.getHeight()); 
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                glOrtho(0,Display.getWidth(), 0, Display.getHeight(), -1, 1);     
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();

                glEnableClientState(GL_VERTEX_ARRAY);         
                glEnableClientState(GL_COLOR_ARRAY);         

                glColorPointer(3, GL_FLOAT, 0, colourBuffer);       
                glVertexPointer(3, GL_FLOAT, 0, vertexBuffer);          

                glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, indexBuffer);    
                Display.update();
                Display.sync(60);
            }
        } catch (LWJGLException e) {
            e.printStackTrace();
        }
    }
}

结果:

【讨论】:

    【解决方案2】:

    使用 glTrace / glIntercept(查看 OpenGL 调用跟踪)、gDebugger(可视化纹理、着色器、OGL 状态等)等工具

    【讨论】:

    • 感谢回答..我试过 glIntercept 但我没有发现我的代码有什么问题??
    【解决方案3】:

    这里有一个OpenGL调试工具列表:https://www.opengl.org/wiki/Debugging_Tools

    此外,您的代码正在使用自 OpenGL 3.3 以来被认为已弃用的旧固定管道,因此我建议您不要将标签“opengl-3”放在您的问题上,或者使用 opengl 3.3 核心上下文并学习“现代” OpenGL(更强大,更难学习,但可以让您了解 GPU 的工作原理)。

    【讨论】:

      猜你喜欢
      • 2011-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-04
      • 2013-09-17
      • 2011-10-30
      相关资源
      最近更新 更多