0

我一直在尝试将着色器和 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();
}

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

4

2 回答 2

0

事实证明,我的渲染中不需要 gluLookAt。

于 2013-01-14T15:50:09.980 回答
0

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

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

对绘图功能非常满意。您还需要设置投影。在教程中,您经常会发现它们是在窗口调整大小处理程序中设置的。请不要养成这个坏习惯。投影和视口是绘图状态,所以在绘图函数中设置它们。

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

于 2013-01-12T21:48:53.043 回答