Anyone using wxGLString? Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Schrja
In need of some credit
In need of some credit
Posts: 9
Joined: Wed Oct 31, 2012 11:21 pm

Anyone using wxGLString?

Post by Schrja » Wed Jan 23, 2013 1:10 am

Hello,

I just tried wxGLString. I built the simplest example I could similar to the sample provided with the code. Drew a couple of shapes, then some text using the sample code. However, when I resized the frame, all the shapes drawn before the text disappeared. There hasn't been much discussion of wxGLString so I am wondering if everyone else is using it successfully, or maybe not using it at all. The complete code for even a simple example is a bit much to post here. I have included the essential drawing code. Much commented out at the moment. It appears the call to my_message.consolidate(&dc); below is what causes the previous shapes to disappear on resizing.

Code: Select all

void Canvas::Render( wxPaintEvent& evt )
{
    if(!IsShown()) return;

    wxGLCanvas::SetCurrent(*m_context);

    wxPaintDC dc(this);

    Prepare2DViewport(0, 0, GetWidth(), GetHeight());

    glColor3f(0.,0.,0.);

    // draw a box
    glLineWidth(2.);
    glBegin(GL_LINE_LOOP);
      glVertex2i(50,  50);
      glVertex2i(50,  100);
      glVertex2i(100, 100);
      glVertex2i(100, 50);
    glEnd();

    // draw a circle
    const float PI = 3.14159;
 	GLint points  = 200;
 	GLfloat angle;
 	GLfloat xc, yc, r;

 	r  = 25.;   // radius
    xc = 75.;  // x coordinate of center
    yc = 200.;  // y coordinate of center
    glBegin(GL_LINE_LOOP);
      for(int i = 0; i < points; i++)
      {
          angle = 2*PI*i/points;
          glVertex2f(xc+r*cos(angle), yc+r*sin(angle));
       }
    glEnd();

    // draw some text
    static wxGLString my_message;
    static wxGLStringArray my_messages;
    static wxGLNumberRenderer number;

    // init them the first time only
    if(my_message.IsEmpty())
    {
         my_message = wxString( wxT("Hello world !!!") );
         my_message.setFont( wxFont( 50, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD) );
         //my_message.consolidate(&dc);

         my_messages.addString( wxT("wxGLString can") );
         my_messages.addString( wxT("render strings in") );
         my_messages.addString( wxT("OpenGL easily!! ") );
         my_messages.addString( wxT("And with Unicode : \x1414 \x1562 \x1593") );
         //my_messages.consolidate(&dc);

         //number.consolidate(&dc);
    }

    /*

    // render string everytime
    my_message.bind();
    my_message.rotate(30);

    glColor3f(1,0,0);
    my_message.render(80,80);

    my_messages.bind();
    glColor3f(0,0.6,0);     my_messages.get(0).render(5,200);
    glColor3f(0,0,0.6);     my_messages.get(1).render(55,225);
    glColor3f(0,0.6,0.6);   my_messages.get(2).render(105,250);
    glColor3f(0.6,0.6,0);   my_messages.get(3).render(155,275);

    number.bind();
    glColor3f(0,0,0);
    number.renderNumber( -3.141591f, 250, 50 );
*/
    glFlush();
    SwapBuffers();
}


John.

Manolo
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 698
Joined: Mon Apr 30, 2012 11:07 pm

Re: Anyone using wxGLString?

Post by Manolo » Wed Jan 23, 2013 1:39 am

I don't see where you handle size-event.
If you'd have an OnSize handler, then you could use there

Code: Select all

Prepare2DViewport(0, 0, event.GetSize().x, event.GetSize().y);
glViewport() (which is eventually called by Prepare2DViewport) tells what piece of the window is to be painted.
If you want all of your window to be painted, you pass its size to glViewport.

EDIT:
I see you are following wxGLString sample code.
I see a critical difference: the initial "p" for Prepare2DViewport(). Make it lowercase.

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: Anyone using wxGLString?

Post by Auria » Wed Jan 23, 2013 11:29 pm

I am successfully using wxGLString (I am the author ;) )

I would need to some more code, not just the render function. If possible a full compilable sample

But I do notice you are mixing the render of primitive (lines) and text (textures). Make sure textures are enabled (glEnable(GL_TEXTURE_2D);) after drawing primitives
"Keyboard not detected. Press F1 to continue"
-- Windows

Schrja
In need of some credit
In need of some credit
Posts: 9
Joined: Wed Oct 31, 2012 11:21 pm

Re: Anyone using wxGLString?

Post by Schrja » Thu Jan 24, 2013 2:09 am

Auria wrote:I am successfully using wxGLString (I am the author ;) )

I would need to some more code, not just the render function. If possible a full compilable sample

But I do notice you are mixing the render of primitive (lines) and text (textures). Make sure textures are enabled (glEnable(GL_TEXTURE_2D);) after drawing primitives
Ok, I am including the full code below. I had it broken into files by class. I started with your example and have been modifying it to make a simple test bed for things I need to understand better. It is probably clear I am a wxWidgets novice and struggling with things that are obvious to others. Note that in void Canvas::Resized(wxSizeEvent& evt) I have commented out a call to the parent OnSize() method. I am using wxWidgets 2.9 and seeing "deprecated" warnings about this call, and as written, it has no effect anyway.

One of the issues I am still wrestling with is which methods need to be developed differently when different "canvas" types are used. My next step on this code will be to make the window scrollable. I am still pondering the changes this will require.

Thanks for looking...

Code: Select all

/*
 * app.h
 *
 *  Created on: Jan 14, 2013
 *      Author: John
 */

#ifndef APP_H_
#define APP_H_

#include "wx/wx.h"

class App: public wxApp
{
public:

    virtual bool OnInit();
    virtual int  OnExit();

};

DECLARE_APP(App)

#endif /* APP_H_ */

/*
 * canvas.h
 *
 *  Created on: Jan 14, 2013
 *      Author: John
 */

#ifndef CANVAS_H_
#define CANVAS_H_

#include "wx/wx.h"
#include "wx/glcanvas.h"

class Canvas : public wxGLCanvas
{
    wxGLContext*	m_context;

public:
	Canvas(wxFrame* parent, int* args);
	virtual ~Canvas();

	void Resized(wxSizeEvent& evt);

	int GetWidth();
	int GetHeight();

	void Render(wxPaintEvent& evt);
	void Prepare2DViewport(int topleft_x, int topleft_y,
			               int bottomright_x, int bottomright_y);

	// events
	void MouseMoved(wxMouseEvent& event);
	void MouseDown(wxMouseEvent& event);
	void MouseWheelMoved(wxMouseEvent& event);
	void MouseReleased(wxMouseEvent& event);
	void RightClick(wxMouseEvent& event);
	void MouseLeftWindow(wxMouseEvent& event);
	void KeyPressed(wxKeyEvent& event);
	void KeyReleased(wxKeyEvent& event);

	DECLARE_EVENT_TABLE()
};

#endif /* CANVAS_H_ */


/*
 * frame.h
 *
 *  Created on: Jan 14, 2013
 *      Author: John
 */

#ifndef MAINFRAME_H_
#define MAINFRAME_H_

class Canvas;

class MainFrame : public wxFrame
{
public:

    MainFrame();
    virtual ~MainFrame();

private:

    void OnClose(wxCloseEvent& event);
    void OnQuit(wxCommandEvent& event);

    Canvas * m_canvas;

    DECLARE_EVENT_TABLE()
};

#endif /* MAINFRAME_H_ */

/*------------------------------------------------------------------------------
 * app.cpp
 *
 *  Created on: Jan 14, 2013
 *      Author: John
 */

#include "wx/wx.h"
//#include "app.h"
//#include "mainframe.h"

IMPLEMENT_APP(App)

//------------------------------------------------------------------------------

bool App::OnInit()
{
    if ( !wxApp::OnInit() )
        return false;

    MainFrame *frame = new MainFrame;
    frame->Show(true);

    return true;
}

//------------------------------------------------------------------------------

int App::OnExit()
{
    return wxApp::OnExit();
}

//------------------------------------------------------------------------------


/*
 * canvas.cpp
 *
 *  Created on: Jan 14, 2013
 *      Author: John
 */

//#include "canvas.h"

#include "wx/wx.h"
#include "wx/sizer.h"
#include "wx/glcanvas.h"
//#include "main.h"

// include OpenGL
#include <GL/glu.h>
#include <GL/gl.h>

//#include "canvas.h"
#include "wxGLString.h"

BEGIN_EVENT_TABLE(Canvas, wxGLCanvas)
    EVT_MOTION(Canvas::MouseMoved)
    EVT_LEFT_DOWN(Canvas::MouseDown)
    EVT_LEFT_UP(Canvas::MouseReleased)
    EVT_RIGHT_DOWN(Canvas::RightClick)
    EVT_LEAVE_WINDOW(Canvas::MouseLeftWindow)
    EVT_SIZE(Canvas::Resized)
    EVT_KEY_DOWN(Canvas::KeyPressed)
    EVT_KEY_UP(Canvas::KeyReleased)
    EVT_MOUSEWHEEL(Canvas::MouseWheelMoved)
    EVT_PAINT(Canvas::Render)
END_EVENT_TABLE()

// some useful events to use
void Canvas::MouseMoved(wxMouseEvent& event) {}
void Canvas::MouseDown(wxMouseEvent& event) {}
void Canvas::MouseWheelMoved(wxMouseEvent& event) {}
void Canvas::MouseReleased(wxMouseEvent& event) {}
void Canvas::RightClick(wxMouseEvent& event) {}
void Canvas::MouseLeftWindow(wxMouseEvent& event) {}
void Canvas::KeyPressed(wxKeyEvent& event) {}
void Canvas::KeyReleased(wxKeyEvent& event) {}

Canvas::Canvas(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);

}

Canvas::~Canvas()
{
	delete m_context;
}

void Canvas::Resized(wxSizeEvent& evt)
{
	//wxGLCanvas::OnSize(evt);
    Refresh();
}

/** Inits the OpenGL viewport for drawing in 2D. */
void Canvas::Prepare2DViewport(int x1, int y1,
		                       int x2, int y2)
{
/*
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(x1, y1, abs(x2-x1), abs(y2-y1));
    glOrtho(x1, x2, y2, y1, 0, 1);
    glDisable(GL_DEPTH_TEST);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
*/
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // white Background
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);   // textures
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_BLEND);
    glDisable(GL_CULL_FACE);
    glDisable(GL_DEPTH_TEST);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

    glViewport(x1, y1, x2 - x1, y2 - y1);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluOrtho2D(x1, x2, y2, y1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

int Canvas::GetWidth()
{
    return GetSize().x;
}

int Canvas::GetHeight()
{
    return GetSize().y;
}


void Canvas::Render( wxPaintEvent& evt )
{
    if(!IsShown()) return;

    wxGLCanvas::SetCurrent(*m_context);

    wxPaintDC dc(this);

    Prepare2DViewport(0, 0, GetWidth(), GetHeight());

    glColor3f(0.,0.,0.);

    // draw a box
    glLineWidth(2.);
    glBegin(GL_LINE_LOOP);
      glVertex2i(50,  50);
      glVertex2i(50,  100);
      glVertex2i(100, 100);
      glVertex2i(100, 50);
    glEnd();

    // draw a circle
    const float PI = 3.14159;
 	GLint points  = 200;
 	GLfloat angle;
 	GLfloat xc, yc, r;

 	r  = 25.;   // radius
    xc = 75.;  // x coordinate of center
    yc = 200.;  // y coordinate of center
    glBegin(GL_LINE_LOOP);
      for(int i = 0; i < points; i++)
      {
          angle = 2*PI*i/points;
          glVertex2f(xc+r*cos(angle), yc+r*sin(angle));
       }
    glEnd();

    // draw some text
    static wxGLString my_message;
    static wxGLStringArray my_messages;
    static wxGLNumberRenderer number;

    // init them the first time only
    if(my_message.IsEmpty())
    {
         my_message = wxString( wxT("Hello world !!!") );
         my_message.setFont( wxFont( 50, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD) );
         my_message.consolidate(&dc);

         my_messages.addString( wxT("wxGLString can") );
         my_messages.addString( wxT("render strings in") );
         my_messages.addString( wxT("OpenGL easily!! ") );
         my_messages.addString( wxT("And with Unicode : \x1414 \x1562 \x1593") );
         my_messages.consolidate(&dc);

         number.consolidate(&dc);
    }



    // render string everytime
    my_message.bind();
    my_message.rotate(30);

    glColor3f(1,0,0);
    my_message.render(80,80);

    my_messages.bind();
    glColor3f(0,0.6,0);     my_messages.get(0).render(5,200);
    glColor3f(0,0,0.6);     my_messages.get(1).render(55,225);
    glColor3f(0,0.6,0.6);   my_messages.get(2).render(105,250);
    glColor3f(0.6,0.6,0);   my_messages.get(3).render(155,275);

    number.bind();
    glColor3f(0,0,0);
    number.renderNumber( -3.141591f, 250, 50 );

    glFlush();
    SwapBuffers();
}

/*------------------------------------------------------------------------------
 * frame.cpp
 *
 *  Created on: Jan 14, 2013
 *      Author: John
 */

#include "wx/wx.h"
//#include "canvas.h"
//#include "mainframe.h"

BEGIN_EVENT_TABLE(MainFrame, wxFrame)
    EVT_CLOSE(MainFrame::OnClose)
    EVT_MENU(wxID_EXIT, MainFrame::OnQuit)
END_EVENT_TABLE()

// -----------------------------------------------------------------------------

MainFrame::MainFrame()
    : wxFrame(NULL, wxID_ANY, "wxWidgets MDI Sample",
              wxDefaultPosition, wxSize(647, 400))
{
	// Layout the frame:

    //  -- create a box sizer to control the canvas
	wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);

	//  -- create the canvas
    int args[] = {WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 16, 0};
    m_canvas = new Canvas( (wxFrame*) this, args);

    //  -- add the canvas to the sizer
    sizer->Add(m_canvas, 1, wxEXPAND);

    //  -- add the sizer to the frame
    this->SetSizer(sizer);
    this->SetAutoLayout(true);

    //  -- create a status bar
    CreateStatusBar();

    //  -- and make it all visible
    this->Show();

 }

// -----------------------------------------------------------------------------

MainFrame::~MainFrame()
{

}

// -----------------------------------------------------------------------------

void MainFrame::OnClose(wxCloseEvent& event)
{
    event.Skip();
	return;
}

// -----------------------------------------------------------------------------

void MainFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    Close();
}

// -----------------------------------------------------------------------------




Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: Anyone using wxGLString?

Post by Auria » Fri Jan 25, 2013 1:31 am

On which OS are you? your sample works fine for me on ubuntu
"Keyboard not detected. Press F1 to continue"
-- Windows

Schrja
In need of some credit
In need of some credit
Posts: 9
Joined: Wed Oct 31, 2012 11:21 pm

Re: Anyone using wxGLString?

Post by Schrja » Fri Jan 25, 2013 2:30 am

Auria wrote:On which OS are you? your sample works fine for me on ubuntu
I am running on Windows 7 (x86_64). I am building with MinGW/msys and g++ 4.7.2 using the eclipse IDE.

I also keep Visual Studio Express 2010 around but try to avoid using it. I guess I could build wxWidgets there and set up a test case.

Note that as simple as the sample is, the circle and square work properly when I don't include the wxGLString code.

Since you are the author, you might be interested in knowing the wxGLString does not compile in this environment without the following addition to wxGLString.h

Code: Select all


#define GL_CLAMP_TO_EDGE 0x812F


Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: Anyone using wxGLString?

Post by Auria » Fri Jan 25, 2013 3:57 am

Oh sorry I misread the problem. I thought the issue was that the text was not visible.

Why the shapes are not visible is because you enabled texture mode. Change render this way, you need to deactivate textures when drawing primitives. Note that this is more an OpenGL question than a wxWidgets question

Code: Select all

void Canvas::Render( wxPaintEvent& evt )
{
    if(!IsShown()) return;

    wxGLCanvas::SetCurrent(*m_context);

    wxPaintDC dc(this);

    Prepare2DViewport(0, 0, GetWidth(), GetHeight());

    glDisable(GL_TEXTURE_2D);
    
    glColor3f(0.,0.,0.);

    // draw a box
    glLineWidth(2.);
    glBegin(GL_LINE_LOOP);
      glVertex2i(50,  50);
      glVertex2i(50,  100);
      glVertex2i(100, 100);
      glVertex2i(100, 50);
    glEnd();

    // draw a circle
    const float PI = 3.14159;
    GLint points  = 200;
    GLfloat angle;
    GLfloat xc, yc, r;

    r  = 25.;   // radius
    xc = 75.;  // x coordinate of center
    yc = 200.;  // y coordinate of center
    glBegin(GL_LINE_LOOP);
      for(int i = 0; i < points; i++)
      {
          angle = 2*PI*i/points;
          glVertex2f(xc+r*cos(angle), yc+r*sin(angle));
       }
    glEnd();

    glEnable(GL_TEXTURE_2D);
    
    // draw some text
    static wxGLString my_message;
    static wxGLStringArray my_messages;
    static wxGLNumberRenderer number;

    // init them the first time only
    if(my_message.IsEmpty())
    {
         my_message = wxString( wxT("Hello world !!!") );
         my_message.setFont( wxFont( 50, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD) );
         my_message.consolidate(&dc);

         my_messages.addString( wxT("wxGLString can") );
         my_messages.addString( wxT("render strings in") );
         my_messages.addString( wxT("OpenGL easily!! ") );
         my_messages.addString( wxT("And with Unicode : \x1414 \x1562 \x1593") );
         my_messages.consolidate(&dc);

         number.consolidate(&dc);
    }



    // render string everytime
    my_message.bind();
    my_message.rotate(30);

    glColor3f(1,0,0);
    my_message.render(80,80);

    my_messages.bind();
    glColor3f(0,0.6,0);     my_messages.get(0).render(5,200);
    glColor3f(0,0,0.6);     my_messages.get(1).render(55,225);
    glColor3f(0,0.6,0.6);   my_messages.get(2).render(105,250);
    glColor3f(0.6,0.6,0);   my_messages.get(3).render(155,275);

    number.bind();
    glColor3f(0,0,0);
    number.renderNumber( -3.141591f, 250, 50 );

    glFlush();
    SwapBuffers();
}
"Keyboard not detected. Press F1 to continue"
-- Windows

Post Reply