0
votes

I've been trying to incorporate shaders and OpenGl into a wxWidgets program. I've used the links below:

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

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

Now I've been trying in a test program to use the shaders provided by the lighthouse3d tutorial and recreate the output, (a blue teapot spinning slowly on a white background). I can't seem to get anything to draw though and all I can see is a black screen. My code so far is below, (I'm going to ignore most of the shaders intially as I'm 99% sure they're fine):

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);
}

I've had thoughts as to why I'm not getting any output. One thought I'm having is something to do with the m_context. I'm having to set the current context for WxWidgets before I can run GLEW. There's also a number of properties that in the tutorial are initialized and I'm not using these functions in my wxWidgets version and I'm wondering if I should. These are:

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);

But I'm quite keen to avoid using glut and have managed to avoid it up until now. The only reason I've previously added it is to try and replicate the tutorial's behaviour.

Edit:

I'm going to add a bit more as I have noticed one or two bits of odd behaviour. If I call this function in my draw:

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();
}

I can get the background to change colour when I change the window size. I should also mention, it's NOT refreshing every frame, It only draws one frame and then won't call the render function again until I change the window size.

2
@ravenspoint I'm removed/edited some bits, but the main problem is that I can't get any output when I'm expecting some as I've copied parts of those tutorials. I've tried to give as much information as to what I think it could be the cause, but I don't have a strong/lead idea so I've made references to multiple places where I think something might be going wrong. I didn't mean to represent that as multiple problems.Bushes
And by output I mean something other than a black screen.Bushes

2 Answers

0
votes

Your code looks good so far. One thing you find in a lot of tutorials, but is bad practice is, that there's apparently some initialization happening. This is not the case. OpenGL is not initialized, it's a state machine and you're supposed to set state when you need it. The lines

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

Are perfectly happy in the drawing function. You also need to setup a projection. In tutorials you often find them to be set in the window resize handler. Please don't fall into this bad habit. Projection and viewport are drawing state, so set them in the drawing function.

If you're using OpenGL-3 (core profile) or later you must supply at least a vertex and a fragment shader. In the older versions each shader stage is optional and there are builtin variables to provide a common grounds for communication between fixed function and programmable pipeline. However I strongly advise against mixed operation. Always use shaders and use both a vertex and a fragment shader. In the long term they make things soooo much easier.

0
votes

Turns out I didn't need the gluLookAt in my render.