wxWidgets OpenGl着色器,无法绘制任何内容

时间:2013-01-12 16:21:59

标签: c++ opengl wxwidgets

我一直在尝试将着色器和OpenGl合并到wxWidgets程序中。我使用过以下链接:

http://nehe.gamedev.net/article/glsl_an_introduction/25007/

http://www.lighthouse3d.com/tutorials/glsl-tutorial/hello-world-in-glsl/

现在我一直在尝试使用lighthouse3d教程提供的着色器测试程序并重新创建输出(蓝色茶壶在白色背景上慢慢旋转)。我似乎无法得到任何东西,但我能看到的只是黑屏。到目前为止,我的代码在下面,(我将忽略大多数着色器,因为我99%确定它们没问题):

void BasicGLPane::render( wxPaintEvent& evt )
{
    //wxGLCanvas::SetCurrent(*m_context);
    wxPaintDC(this); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    //prepare2DViewport(0,0,getWidth()/2, getHeight());
    glLoadIdentity();
    gluLookAt(0.0,0.0,5.0, 
          0.0,0.0,-1.0,
          0.0f,1.0f,0.0f);

    glLightfv(GL_LIGHT0, GL_POSITION, lpos);
    //glRotatef(a,0,1,1);
    glutSolidTeapot(1);
    glFlush();
    //a+=0.1;

    SwapBuffers();
}

void BasicGLPane::InitializeGLEW()
{
    //prepare2DViewport(0,0,getWidth(), getHeight());
    // The current canvas has to be set before GLEW can be initialized.
    wxGLCanvas::SetCurrent(*m_context);
    GLenum err = glewInit();

    // If Glew doesn't initialize correctly.
    if(GLEW_OK != err)
    {
        std::cerr << "Error:" << glewGetString(err) << std::endl;
        const GLubyte* String = glewGetErrorString(err);
        wxMessageBox("GLEW is not initialized");
    }

BasicGLPane::BasicGLPane(wxFrame* parent, int* args) :
wxGLCanvas(parent, wxID_ANY, args, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
{

    m_context = new wxGLContext(this);

    // To avoid flashing on MSW
    SetBackgroundStyle(wxBG_STYLE_CUSTOM);
}

我已经想过为什么我没有得到任何输出。我以为我有一个想法是与m_context有关。在运行GLEW之前,我必须为WxWidgets设置当前上下文。在教程中还有许多属性被初始化,我在wxWidgets版本中没有使用这些函数,我想知道是否应该这样做。这些是:

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("MM 2004-05");

glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glutReshapeFunc(changeSize);
glutKeyboardFunc(processNormalKeys);

glEnable(GL_DEPTH_TEST);
glClearColor(1.0,1.0,1.0,1.0);
glEnable(GL_CULL_FACE);

但是我非常希望避免使用过剩,并且到目前为止已经设法避免使用过剩。我之前添加它的唯一原因是尝试复制教程的行为。

编辑:

我要添加一点,因为我注意到一两个奇怪的行为。如果我在平局中调用此函数:

void BasicGLPane::prepare2DViewport(int topleft_x, int topleft_y, int bottomrigth_x, int bottomrigth_y)
{
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Black Background
    glEnable(GL_TEXTURE_2D);   // textures
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

    glViewport(topleft_x, topleft_y, bottomrigth_x-topleft_x, bottomrigth_y-topleft_y);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluOrtho2D(topleft_x, bottomrigth_x, bottomrigth_y, topleft_y);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

当我改变窗口大小时,我可以获得改变颜色的背景。我还应该提一下,它不是每个帧都刷新,它只绘制一个帧,然后在我改变窗口大小之前不会再次调用渲染函数。

2 个答案:

答案 0 :(得分:0)

到目前为止,您的代码看起来很不错。你在很多教程中找到的一件事,但不好的做法是,显然有一些初始化正在发生。不是这种情况。 OpenGL没有初始化,它是一个状态机,你应该在需要时设置状态。行

glEnable(GL_DEPTH_TEST);
glClearColor(1.0,1.0,1.0,1.0);
glEnable(GL_CULL_FACE);

在绘图功能中非常满意。您还需要设置投影。在教程中,您经常会在窗口调整大小处理程序中找到它们。请不要陷入这个坏习惯。投影和视口是绘制状态,因此在绘图函数中设置它们。

如果您使用的是OpenGL-3(核心配置文件)或更高版本,则必须至少提供一个顶点一个片段着色器。在旧版本中,每个着色器阶段都是可选的,并且内置变量为固定功能和可编程管道之间的通信提供了共同的基础。不过我强烈反对混合操作。始终使用着色器并同时使用顶点和片段着色器。从长远来看,他们会让事情变得更容易。

答案 1 :(得分:0)

原来我在渲染中不需要gluLookAt。