Page 1 of 1

Using GLEW in own implementation of wxGLCanvas

Posted: Wed Oct 27, 2010 4:17 pm
by kie
Hello,
i want to add shadersupport in my custom derivation of wxGLCanvas with GLEW. Here is my initialization code of the widget:

Code: Select all

ShaderPreview::ShaderPreview(wxFrame *parent)
: wxGLCanvas(parent, wxID_ANY,  wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas"))
{
    int argc = 1;
    char* argv[1] = { wxString((wxTheApp->argv)[0]).char_str() };

   glutInit(&argc, argv);
   WXUINT err=glGetError();
   if(err!=GL_NO_ERROR)
   {
      wxMessageBox( wxString("GLUT Error: ") +
                 wxString(gluErrorString(err)),
                 _("ERROR"),
                 wxOK | wxICON_EXCLAMATION
               );
   }

   err=glewInit();
   if(err!=GLEW_OK)
   {
      wxMessageBox( wxString("GLEW Error: ") +
                 wxString(glewGetErrorString(err)),
                 _("ERROR"),
                 wxOK | wxICON_EXCLAMATION
               );
   }
   
   
}


In compiles and liks well, but I get a GLUT Error: invalid operation and a GLEW Error: missing gl version.
The rendering of an glutSolidTeapot() works perfectly, but I can't use procedures that are served by glew.

I think glutInit() fails, because wxGLCanvas already initializes an opengl context. But why is glewInit failing?

Greets Daniel

Posted: Thu Oct 28, 2010 6:53 am
by kie
I turns out, that i have to call glutInit and glewInit within my PaintIt Event. So I added a GlSetup() function that will be called in PaintIt just once.

But it seems to be a hack to me. Is there an better alternative?

Greetings

Re: Using GLEW in own implementation of wxGLCanvas

Posted: Sun Jul 26, 2015 4:28 pm
by Zeos
Hello !
As I also searched that solution for some time and browsing solutions on Google I came on this post not resolved,
I will drop for you my solution.

Simplified Version (with GLEW) ...
See the OpenGl tutorial ! on the website of OpenGl (http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/) for unknowns functions

MainInterface.h

Code: Select all

#ifndef INTERFACE_H
#define INTERFACE_H
#include <GL/glew.h>
#include <glm/glm.hpp>
using namespace glm;
#include "Shader.h"
#include <iostream>
#include <string>
#include <cassert>
#include <cmath>
#include <wx/wx.h>
#include <wx/glcanvas.h>
#include <wx/notebook.h>
// An array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
   -1.0f, -1.0f, 0.0f,
   1.0f, -1.0f, 0.0f,
   0.0f,  1.0f, 0.0f,
};
class MainInterface : public wxGLCanvas
{
public:
   MainInterface(wxWindow * parent, wxWindowID id,
             const wxPoint & pos, const wxSize& size, long style=0,
             const wxString & name = _("MainInterface"), int * attribList = 0,
             const wxPalette & palette = wxNullPalette);
   virtual ~MainInterface() { }
   //void OnPaint(wxPaintEvent& event);
   void OnIdle(wxIdleEvent & event);
   void Draw();
   //
   void InitOpenGl();
private:
    GLuint programID,vertexbuffer;
    bool InitGL;
    DECLARE_EVENT_TABLE();
};
#endif // INTERFACE_H


MainInterface.cpp

Code: Select all

#include "MainInterface.h"

BEGIN_EVENT_TABLE(MainInterface, wxGLCanvas)
    EVT_IDLE(MainInterface::OnIdle)
END_EVENT_TABLE()

MainInterface::MainInterface(wxWindow * parent, wxWindowID id,const wxPoint & pos, const wxSize& size, long style,const wxString & name, int * attribList,const wxPalette & palette) :
    wxGLCanvas(parent, id, pos, size, style, name, attribList, palette), InitGL(false)
{
    InitOpenGl();
    // Create and compile our GLSL program from the shaders
    programID = LoadShaders( "resources/SimpleVertexShader.vertexshader", "resources/SimpleFragmentShader.fragmentshader" );
    //
    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);
    // Generate 1 buffer, put the resulting identifier in vertexbuffer
    glGenBuffers(1, &vertexbuffer);
    // The following commands will talk about our 'vertexbuffer' buffer
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    // Give our vertices to OpenGL.
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

}
void MainInterface::InitOpenGl()
{
    if(InitGL) return;
    //
    while ( !IsShown() ) {};  // Force the Shown
    wxGLCanvas::SetCurrent();

    /// Init OpenGL
    glLoadIdentity();
    GLenum err = glewInit();
    if(err!=GL_NO_ERROR)
    {
        wxMessageBox(
            wxString("GLEW Error: ") +
            wxString(glewGetErrorString(err)),
            _("OpenGl ERROR"),
            wxOK | wxICON_EXCLAMATION
        );
    exit(4001); //
   }
   InitGL=true;
}
void MainInterface::OnIdle(wxIdleEvent & event)
{
    Draw();
    event.RequestMore();
}
void MainInterface::Draw()
{
    if(!IsShown()) return;
    wxGLCanvas::SetCurrent();

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, (GLint)200, (GLint)200);

    // Attribuer 1er tampon: sommets
    glEnableVertexAttribArray (0);
    glBindBuffer (GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer (
       0,                   // attribut 0. Pas de raison particulière à 0, mais il doit correspondre à la disposition dans le shader.
       3,                   // taille
       GL_FLOAT,            // Type
       GL_FALSE,            // normalisée?
       0,                   // foulée
       ( void *) 0          // tampon de tableau de décalage
    );

    // Utilisez notre shaders
    glUseProgram (programID);

    // Dessine le triangle!
    glDrawArrays (GL_TRIANGLES, 0, 3); // partir de sommet 0; 3 sommets Total -> 1 triangle
    glDisableVertexAttribArray (0);
    SwapBuffers();
}