integrate wxglcanvas with other events (lists, buttons, others)

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.
pedromigl010
In need of some credit
In need of some credit
Posts: 7
Joined: Sun May 07, 2017 3:53 pm

integrate wxglcanvas with other events (lists, buttons, others)

Postby pedromigl010 » Tue May 01, 2018 4:50 am

First of all I apologize for my bad English.

I need to show a frame where there are two boxes. A box must contain lists, where one of the list is for months and the other is to contain a range of years. The other box must show a graph made with opengl and for that I use the wxglcanvas function.

I can show the graph in the frame, but this happens if I do not include the list in the first box. If I include the list in that case it shows me only the list but not the graph.

How can I insert the list in a box and the graph in another box?

Code: Select all


#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#if !wxUSE_GLCANVAS
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
#endif

#ifdef __WXMAC__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif


//#include "../../sample.xpm"

#ifndef __WXMSW__     // for StopWatch, see remark below
#if defined(__WXMAC__) && !defined(__DARWIN__)
#include <utime.h>
#include <unistd.h>
#else
#include <sys/time.h>
#include <sys/unistd.h>
#endif
#else
#include <sys/timeb.h>
#endif

#define ID_NEW_WINDOW 10000

BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
   EVT_SIZE(TestGLCanvas::OnSize)
   EVT_PAINT(TestGLCanvas::OnPaint)
   END_EVENT_TABLE()
   

TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id,
                     const wxPoint& pos, const wxSize& size, long style, const wxString& name)
   : wxGLCanvas(parent, (wxGLCanvas*) NULL, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE , name )
{
   m_init = false;
   //m_gllist = 0;
   
   //wxMessageBox("hola");
}

TestGLCanvas::TestGLCanvas(wxWindow *parent, const TestGLCanvas *other,
                     wxWindowID id, const wxPoint& pos, const wxSize& size, long style,
                     const wxString& name )
   : wxGLCanvas(parent, other->GetContext(), id, pos, size, style|wxFULL_REPAINT_ON_RESIZE , name)
{
   m_init = false;
   //m_gllist = other->m_gllist; // share display list
   
}

TestGLCanvas::~TestGLCanvas()
{
}

//GLubyte ubImage[65536];
GLint point1[1000][2];

void TestGLCanvas::Render() ///vendria siendo el void display_cb()
{
   
   wxPaintDC dc(this);
   
/*#ifndef __WXMOTIF__
   if (!GetContext()) return;
#endif*/
   
   SetCurrent();
   // Init OpenGL once, but after SetCurrent
   if (!m_init)
   {
   InitGL();
   m_init = true;
   }
   glClearColor(1.f,1.f,1.f,1.f);
   glClear(GL_COLOR_BUFFER_BIT);
   
   /**
graphics code----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
   
   glFlush();
   SwapBuffers();
   
   
}

void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
{
   Render();
}


void TestGLCanvas::OnSize(wxSizeEvent& event) ///Para redimensionar la grafica
{
   // this is also necessary to update the context on some platforms
   wxGLCanvas::OnSize(event);
   
   
   // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
   int w, h;
   GetClientSize(&w, &h);
#ifndef __WXMOTIF__
   if (GetContext())
#endif
   {
      SetCurrent();
      glViewport(0, 0, (GLint) w, (GLint) h);
   }
   
   
}


void TestGLCanvas::InitGL() ///vendria siendo el void reshape_cb (int w, int h)
{
   //SetCurrent();
   

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity ();
   gluOrtho2D(0,700,0,250);
   
   

   ///glMatrixMode(GL_MODELVIEW);
   //glLoadIdentity();
   //glScalef(1.25, 1.25,0);
   //glOrtho(-1, 200, -1, 200, -1, 200);
   ///
   //glPolygonMode(GL_FRONT, GL_FILL);
}


BEGIN_EVENT_TABLE(MyFrame, wxFrame)
   END_EVENT_TABLE()
   
   // My frame constructor
   MyFrame::MyFrame(wxWindow *parent, const wxString& title, const wxPoint& pos,
                const wxSize& size, long style)
   : wxFrame(parent, wxID_ANY, title, pos, size, style)
{
   m_canvas = NULL;
   
   
}

/*static*/ MyFrame *MyFrame::Create(MyFrame *parentFrame, bool isCloneWindow)
{
   
   wxString str = wxT("Grafica");
   if (isCloneWindow) str += wxT(" - Clone");
   
   MyFrame *frame = new MyFrame(parentFrame, str, wxDefaultPosition, wxSize(400, 300));
   
   
   if (parentFrame)
   {
   frame->m_canvas = new TestGLCanvas(frame, parentFrame->m_canvas,
   wxID_ANY, wxDefaultPosition, wxDefaultSize );
   }
   else
   {
   frame->m_canvas = new TestGLCanvas(frame, wxID_ANY,
   wxDefaultPosition, wxDefaultSize);
   }
   
   wxBoxSizer* bSizer28;
   bSizer28 = new wxBoxSizer( wxVERTICAL );
   
   wxArrayString m_choice2Choices;
   wxChoice *m_choice2 = new wxChoice( frame, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choice2Choices, 0 );
   m_choice2->SetSelection( 0 );
   bSizer28->Add( m_choice2, 0, wxALL, 5 );
   
   bSizer28->Add( frame, 1, wxALL|wxEXPAND, 5 );
   
   
   frame->Show(true);
   
   return frame;
   
}


void VPrincipal::ClickGrafica(wxCommandEvent& event){
   
   (void) MyFrame::Create(NULL);
   
}



I guess the problem is when I call first: frame-> m_canvas = new TestGLCanvas (frame, wxID_ANY,
wxDefaultPosition, wxDefaultSize), so that it generates the graph and then I pass the instruction so that the list is generated in the frame: bSizer28-> Add (m_choice2, 0, wxALL, 5), but this does it above the graph, I think there the problem arises.

How do I do for this type of case?

User avatar
doublemax
Moderator
Moderator
Posts: 12690
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: integrate wxglcanvas with other events (lists, buttons, others)

Postby doublemax » Tue May 01, 2018 7:09 am

Do you want them side-by-side? Then you need to use a horizontal boxsizer. In any case you need to add the wxGLCanvas to the sizer, too.

Try this:

Code: Select all

   wxBoxSizer* bSizer28;
   bSizer28 = new wxBoxSizer( wxHORIZONTAL );
   
   wxArrayString m_choice2Choices;
   wxChoice *m_choice2 = new wxChoice( frame, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choice2Choices, 0 );
   m_choice2->SetSelection( 0 );
   bSizer28->Add( m_choice2, 0, wxALL|wxEXPAND, 5 );

   bSizer28->Add( m_canvas, 1, wxALL|wxEXPAND, 5 );
   
   frame->SetSizer( bSizer28 );
   
   frame->Show(true);
Use the source, Luke!

pedromigl010
In need of some credit
In need of some credit
Posts: 7
Joined: Sun May 07, 2017 3:53 pm

Re: integrate wxglcanvas with other events (lists, buttons, others)

Postby pedromigl010 » Tue May 01, 2018 7:30 pm

I'm sorry doublemax, wrongly put the code in the frame, really the code in the frame is this:

Code: Select all

/*static*/ MyFrame *MyFrame::Create(MyFrame *parentFrame, bool isCloneWindow)
{
   wxString str = wxT("Grafica");
   if (isCloneWindow) str += wxT(" - Clone");
   
   MyFrame *frame = new MyFrame(parentFrame, str, wxDefaultPosition, wxSize(400, 300));
   
   
   if (parentFrame)
   {
   frame->m_canvas = new TestGLCanvas(frame, parentFrame->m_canvas,
   wxID_ANY, wxDefaultPosition, wxDefaultSize );
   }
   else
   {
   //wxMessageBox("hola");
   frame->m_canvas = new TestGLCanvas(frame, wxID_ANY,
   wxDefaultPosition, wxDefaultSize);
   }
   
   wxBoxSizer* bSizer28;
   bSizer28 = new wxBoxSizer( wxVERTICAL );
   
   wxBoxSizer* bSizer25;
   bSizer25 = new wxBoxSizer( wxVERTICAL );
   
   wxArrayString m_choice2Choices;
   wxChoice *m_choice2 = new wxChoice(frame, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choice2Choices, 0 );
   m_choice2->SetSelection( 0 );
   bSizer25->Add( m_choice2, 0, wxALL, 5 );
   
   
   bSizer28->Add( bSizer25, 0, wxEXPAND, 5 );
   
   wxBoxSizer* bSizer27;
   bSizer27 = new wxBoxSizer( wxVERTICAL );
   
   bSizer27->Add(frame->m_canvas, 0, wxALL, 5 );
   
   
   bSizer28->Add( bSizer27, 1, wxEXPAND, 5 );
   
   
   frame->SetSizer( bSizer28 );
   
   frame->Show(true);
   
   return frame;
}



Then as you can see there are three boxes, with vertical orientation (The orientation for me is not so important).
The main bSizer28 box, which contains the other two, bSizer25 where the list (choice) and bSizer27 are present, where the graph should be supposed to be.


I could see that you suggested to me to place in the bsizer where will show the graph the following:
bSizer27-> Add (frame-> m_canvas, 0, wxALL, 5). However, the problem keeps appearing, it does show me the frame but only with the list (choice). On the other hand, if I remove the list in this way:

Code: Select all


/*static*/ MyFrame *MyFrame::Create(MyFrame *parentFrame, bool isCloneWindow)
{
   wxString str = wxT("Grafica");
   if (isCloneWindow) str += wxT(" - Clone");
   
   MyFrame *frame = new MyFrame(parentFrame, str, wxDefaultPosition, wxSize(400, 300));
   
   
   if (parentFrame)
   {
   frame->m_canvas = new TestGLCanvas(frame, parentFrame->m_canvas,
   wxID_ANY, wxDefaultPosition, wxDefaultSize );
   }
   else
   {
   //wxMessageBox("hola");
   frame->m_canvas = new TestGLCanvas(frame, wxID_ANY,
   wxDefaultPosition, wxDefaultSize);
   }
   
   wxBoxSizer* bSizer28;
   bSizer28 = new wxBoxSizer( wxVERTICAL );
   
   wxBoxSizer* bSizer25;
   bSizer25 = new wxBoxSizer( wxVERTICAL );
   
   /*wxArrayString m_choice2Choices;
   wxChoice *m_choice2 = new wxChoice(frame, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choice2Choices, 0 );
   m_choice2->SetSelection( 0 );
   bSizer25->Add( m_choice2, 0, wxALL, 5 );*/
   
   
   bSizer28->Add( bSizer25, 0, wxEXPAND, 5 );
   
   wxBoxSizer* bSizer27;
   bSizer27 = new wxBoxSizer( wxVERTICAL );
   
   bSizer27->Add(frame->m_canvas, 0, wxALL, 5 );
   
   
   bSizer28->Add( bSizer27, 1, wxEXPAND, 5 );
   
   
   //frame->SetSizer( bSizer28 );
   
   frame->Show(true);
   
   return frame;
   
}


The frame is shown with the graph but without the list.

I attach some files so they can visualize better.
Attachments
the frame with the graphic but without the list.png
the frame with the graphic but without the list
the frame with the graphic but without the list.png (6.07 KiB) Viewed 545 times
the frame with the list but without the graph.png
the frame with the list but without the graph
the frame with the list but without the graph.png (4.38 KiB) Viewed 545 times

User avatar
doublemax
Moderator
Moderator
Posts: 12690
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: integrate wxglcanvas with other events (lists, buttons, others)

Postby doublemax » Tue May 01, 2018 9:02 pm

I still don't see why you use 3 sizers when you only need 1. Did you try with one sizer like in my code?

Also, why did you a static Create() method? This is very unusual and makes it harder to follow what's happening. Maybe that has a side-effect that i'm not seeing at the moment.

I'd need a compiable sample to say more.
Use the source, Luke!

pedromigl010
In need of some credit
In need of some credit
Posts: 7
Joined: Sun May 07, 2017 3:53 pm

Re: integrate wxglcanvas with other events (lists, buttons, others)

Postby pedromigl010 » Sat May 05, 2018 8:33 pm

I made it! doublemax, place 3 sizers because in fact one them (horizontal) was to place a wxcalendarctrl and next a list and down in the other sizer place the graph. In the end I was able to do it thank you very much for your help! You are my hero :lol: . The code he placed was the following:

Code: Select all


/*static*/ MyFrame *MyFrame::Create(MyFrame *parentFrame)
{
   
   wxString str = wxT("Grafica");
   
   MyFrame *frame = new MyFrame(parentFrame, str, wxPoint(30, 20), wxSize(500, 650));
   
   frame->SetSizeHints( wxDefaultSize, wxDefaultSize );
   
   
   wxBoxSizer* bSizer28;
   
   bSizer28 = new wxBoxSizer( wxVERTICAL );
   
   
   wxPanel *m_panel6 = new wxPanel( frame, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
   m_panel6->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNHIGHLIGHT ) );
   wxBoxSizer* bSizer25;
   bSizer25 = new wxBoxSizer( wxVERTICAL );
   
   
   if (parentFrame)
   {
   frame->m_canvas = new TestGLCanvas(m_panel6, parentFrame->m_canvas,
   wxID_ANY, wxDefaultPosition, wxDefaultSize );
   }
   else
   {
   frame->m_canvas = new TestGLCanvas(m_panel6, wxID_ANY,
   wxDefaultPosition, wxDefaultSize);
   }

   wxCalendarCtrl *m_calendar5 = new wxCalendarCtrl( m_panel6, wxID_ANY, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxCAL_SHOW_HOLIDAYS );
   bSizer25->Add( m_calendar5, 0, wxALL, 5 );
   
   wxArrayString m_choice3Choices;
   wxChoice *m_choice3 = new wxChoice( m_panel6, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choice3Choices, 0 );
   m_choice3->SetSelection( 0 );
   bSizer25->Add( m_choice3, 0, wxALL, 5 );
   
   bSizer25->Add( frame->m_canvas, 1, wxALL|wxEXPAND, 5 );
   
   wxButton *m_button6 = new wxButton( m_panel6, wxID_ANY, wxT("&Buscar"), wxDefaultPosition, wxDefaultSize, 0 );
   bSizer25->Add( m_button6, 0, wxALL|wxALIGN_RIGHT, 5 );
   
   
   m_panel6->SetSizer( bSizer25 );
   m_panel6->Layout();
   bSizer25->Fit( m_panel6 );
   bSizer28->Add( m_panel6, 1, wxEXPAND | wxALL, 5 );
   
   
   frame->SetSizer( bSizer28 );
   
   
   frame->Show(true);
   

   return frame;
   
   
}




On the other hand you're right! The static Frame is causing me problems, because it is preventing me from adding public variables of the frame class and taking values ​​from it and that is a problem since I need to take dynamic values ​​from the framework in my app. The reason why I took the static framework was because I took it from an example I saw on the wxglcanvas website and I took it because it is the example that seemed simpler and worked for me, this is the class:

Code: Select all


class TestGLCanvas;

class MyFrame: public wxFrame
{
public:
static MyFrame * Create (MyFrame * parentFrame);
TestGLCanvas * m_canvas;

void start_time (wxTimerEvent &);

private:

MyFrame (wxWindow * parent, const wxString & title, const wxPoint & pos,
const wxSize & size, long style = wxDEFAULT_FRAME_STYLE);


DECLARE_EVENT_TABLE ()

};



What happens if I remove the static function Create, the compiler comes out the following message:

can not call member function 'MyFrame * Frame :: Create (MyFrame * parentFrame);

I have to make the frame call that way. I need to be able to make the call from the Create, since for what I investigate in wxwidgets, the Create is one of the few ways to simulate the call of the main function, necessary for Opengl to graph. The call is made in the following way:

Code: Select all


void VPrincipal::ClickGrafica(wxCommandEvent& event){
   
(void) MyFrame::Create(NULL);
   
}



What I really need to know now is, how to call the Create function without the static?

Attach image file so you can see how it is doing
Attachments
Frame.png
Frame
Frame.png (15.13 KiB) Viewed 492 times

User avatar
doublemax
Moderator
Moderator
Posts: 12690
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: integrate wxglcanvas with other events (lists, buttons, others)

Postby doublemax » Sat May 05, 2018 8:40 pm

I still don't see the purpose the the static Create() method. Most of the code in that method should just go into the MyFrame constructor

And this line

Code: Select all

(void) MyFrame::Create(NULL);
should then be replaced with

Code: Select all

new MyFrame(NULL);
Use the source, Luke!

pedromigl010
In need of some credit
In need of some credit
Posts: 7
Joined: Sun May 07, 2017 3:53 pm

Re: integrate wxglcanvas with other events (lists, buttons, others)

Postby pedromigl010 » Mon Jun 25, 2018 3:03 am

Hello, I'm here again, doublemax I thank you for what you helped me a few days ago. I was able to solve my problem with your response from that moment. In this opportunity I have another problem related to the same function wxglcanvas. I want to know how to add a character string using wxglcanvas ?, I mention this because I have tried to do it and I have not yet achieved it. The program stops, I could see some examples on the web, I saw another related topic in this forum and from what I could understand it was not easy to include the string using wxglcanvas, I do not know if I am wrong. My solution was to use wxpaintdc, but in this way it is difficult for me to adjust the string to the graphic, if I enlarge or minimize everything is unbalanced and of course I can not show the program in this way.
Once again I would be grateful in advance for your response.

Here I put the code used for the graph:

Code: Select all


void TestGLCanvas::Render() ///vendria siendo el void display_cb()
{
   
   MyFrame *li;
   
   
   wxPaintDC dc(this);
   
#ifndef __WXMOTIF__
   if (!GetContext()) return;
#endif
   
   SetCurrent();
   // Init OpenGL once, but after SetCurrent
   if (!m_init)
   {
   InitGL();
   m_init = true;
   }
   
   glClearColor(1.f,1.f,1.f,1.f); ///Color Blanco
   ///Limpia el buffer, quita el color negro y lo pasa a blanco
   glClear(GL_COLOR_BUFFER_BIT);
   
   // code of the graphic

   // end of the code
   
   /*glLoadIdentity();
   glColor3f(0,1,0);
   glTranslatef(10, -0.1,0); ///indica la posicion en pantalla
   glScalef(0.09f,0.08f,0); ///Escala de la letra, tambien en el eje Y, si colocas
   ///signo - puedes invertir las palabras
   //glScalef(1.25, -1.25,0);
   
   char *fech=strdup(fecha_a.c_str());
   
   for(;*fech != '\0'; fech++)
   {
   glutStrokeCharacter(GLUT_STROKE_ROMAN , *fech);
   }*/
   
   
   //GLvoid *font_style = GLUT_BITMAP_TIMES_ROMAN_10;
   //glFontBegin(fecha_a);
   //drawString(fecha_a);
   
   //glColor3f(0.0, 0.0, 1.0);
   /*glEnable(GL_TEXTURE_2D);
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glRasterPos2f(100, 100);
   char *fech=strdup(fecha_a.c_str());
   //for (int i = 0; i < fecha_a.length(); i++)
   glutBitmapCharacter(font_style, fech[0]);
   glDisable(GL_TEXTURE_2D);*/
   
   
   wxString str;
   //wxPaintDC dc(this);
   SetCurrent();
   
   dc.SetFont( wxFont(6, wxMODERN, wxNORMAL, wxNORMAL, TRUE) );
   dc.SetTextForeground(*wxBLUE);
   str.Printf("Ene");
   dc.DrawText(str, 32, 480);
   str.Printf("Feb");
   dc.DrawText(str, 70, 480);
   str.Printf("Mar");
   dc.DrawText(str, 100, 480);
   str.Printf("Abr");
   dc.DrawText(str, 140, 480);
   str.Printf("May");
   dc.DrawText(str, 180, 480);
   str.Printf("Jun");
   dc.DrawText(str, 220, 480);
   str.Printf("Jul");
   dc.DrawText(str, 260, 480);
   str.Printf("Agos");
   dc.DrawText(str, 300, 480);
   str.Printf("Sept");
   dc.DrawText(str, 340, 480);
   str.Printf("Oct");
   dc.DrawText(str, 380, 480);
   str.Printf("Nov");
   dc.DrawText(str, 420, 480);
   str.Printf("Dic");
   dc.DrawText(str, 460, 480);
   
   /*glColor3f(0,1,0);
   glTranslatef(10, -0.1,0); ///indica la posicion en pantalla
   glScalef(0.09f,0.08f,0); ///Escala de la letra, tambien en el eje Y, si colocas
   ///signo - puedes invertir las palabras
   //glScalef(1.25, -1.25,0);
   char *fech=strdup(fecha_a.c_str());
   for (; *fech!= '\0'; fech++)
   {
   glutStrokeCharacter(GLUT_STROKE_ROMAN , *fech);
   }
   
   glFlush();
   SwapBuffers(); */
   
}


As you can see, try in several ways to insert characters with wxglcanvas but without success, so leave it in comment mode.

I would like to know how to insert the characters with wxglcanvas and know where my error is.

I attach two images so that you can see what I mean, the first (I) with the original size of the frame and the second (II) with the enlarged frame.
Attachments
wxglcanvas wxpaintdc II.png
wxglcanvas wxpaintdc (II)
wxglcanvas wxpaintdc II.png (16.87 KiB) Viewed 393 times
wxglcanvas wxpaintdc.png
wxglcanvas wxpaintdc (I)
wxglcanvas wxpaintdc.png (17.04 KiB) Viewed 393 times

User avatar
doublemax
Moderator
Moderator
Posts: 12690
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: integrate wxglcanvas with other events (lists, buttons, others)

Postby doublemax » Mon Jun 25, 2018 5:16 am

I don't know too much about OpenGL. Try wxGLString:
viewtopic.php?p=96261#p96261
viewtopic.php?p=149969#p149969

It's pretty old, but maybe it still works.
Use the source, Luke!

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

Re: integrate wxglcanvas with other events (lists, buttons, others)

Postby Manolo » Mon Jun 25, 2018 12:57 pm

While the OS provides string drawing (wxDC::DrawText), OpenGL has nothing for string rendering. And the bad news is that mixing OS and OGL renderings (read: a DC and a gl-context) is near-sure not working.

There are two approaches for the solution:
a) Convert the string to an image, for example drawing to a memory DC. Then use a gl-texture to render that image. This is how wxGLString works.
wxGLString uses old OpenGL 1.1. For the same idea, but with modern OpenGL (>= 3.2), see the opengl/pyramid sample.

b)The other approach is that first you do all your OpenGL render. Then, by using glReadPixels, you make a "screen shot" into an image. Then, with OS commands (wxDC) you draw that image as a bakcground of the window. Finally, also with wxDC features you draw the strings or whatever you like.

pedromigl010
In need of some credit
In need of some credit
Posts: 7
Joined: Sun May 07, 2017 3:53 pm

Re: integrate wxglcanvas with other events (lists, buttons, others)

Postby pedromigl010 » Thu Jun 28, 2018 3:18 am

Thanks manolo for your answer, but now I have some doubts, I think if there are native OpenGl functions that work with characters such as:
glutStrokeCharacter (void * font, int character); it is precisely in the header glut. Next I will show the pure code in opengl that I use to show characters and the graph in OpenGl:

Code: Select all

#include <GL/glut.h>
#include <stdio.h>
#include <iostream>

using namespace std;

void reshape_cb (int w, int h) {
   
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity ();
   gluOrtho2D(0,700,0,250);
   
}

GLint point1[1000][2];

void display_cb() {
   
   void drawStrokeText(char*string,int x,int y,int z);
   
   glClear(GL_COLOR_BUFFER_BIT);
   
   graphic code
   :::::::::::::::
   end code
      
   drawStrokeText("Esto es una prueba");
   
   glFlush();
   glutSwapBuffers();
   
}


void drawStrokeText(char*string)
{
   char *c;

   glColor3f(0,1,0);
   glTranslatef(50, 120,0); ///indica la posicion en pantalla
   glScalef(0.2, 0.2,0);
   
   for (c=string; *c != '\0'; c++)
   {
   glutStrokeCharacter(GLUT_STROKE_ROMAN , *c);
   }
}


void initialize() {
   glutInitDisplayMode (GLUT_RGBA|GLUT_DOUBLE);
   glutInitWindowSize (640,480);
   glutInitWindowPosition (100,100);
   glutCreateWindow ("Ventana OpenGL");
   glutDisplayFunc (display_cb);
   glutReshapeFunc (reshape_cb);
   glClearColor(1.f,1.f,1.f,1.f);
}

int main (int argc, char **argv) {
   glutInit (&argc, argv);
   initialize();
   glutMainLoop();
   return 0;
}



Attached () image so you can see how both representations are in the same frame.

What I have been able to observe, is that I can not do that with wxglcanvas of wxwidgets, for example:

Code: Select all


void TestGLCanvas::Render() ///vendria siendo el void display_cb()
{
   
   MyFrame *li;
   
   wxPaintDC dc(this);
   
#ifndef __WXMOTIF__
   if (!GetContext()) return;
#endif
   
   SetCurrent();
   // Init OpenGL once, but after SetCurrent
   if (!m_init)
   {
   InitGL();
   m_init = true;
   }
   
   glClearColor(1.f,1.f,1.f,1.f); ///Color Blanco
   glClear(GL_COLOR_BUFFER_BIT);
   
   graphic code
   :::::::::::::::
   end code
   
   drawStrokeText("Esto es una segunda prueba");
   
   glFlush();
   SwapBuffers();
   
}


void TestGLCanvas::drawStrokeText(char*string)
{
   char *c;
   
   glColor3f(0,1,0);
   glTranslatef(10, 100,0); ///indica la posicion en pantalla
   glScalef(0.2, 0.2,0);
   
   for (c=string; *c != '\0'; c++)
   {
   glutStrokeCharacter(GLUT_STROKE_ROMAN , *c);
   }
}


void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
{   
   Render();
}


void TestGLCanvas::OnSize(wxSizeEvent& event) ///Para redimensionar la grafica
{
   // this is also necessary to update the context on some platforms
   wxGLCanvas::OnSize(event);
      
   // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
   int w, h;
   GetClientSize(&w, &h);
#ifndef __WXMOTIF__
   if (GetContext())
#endif
   {
      SetCurrent();
      glViewport(0, 0, (GLint) w, (GLint) h);
   }   
}


void TestGLCanvas::InitGL() ///vendria siendo el void reshape_cb (int w, int h)
{
   
   gluOrtho2D(0,700,0,250);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity ();   
}



As you can see I did exactly the same as in the OpenGL example, but this time it just tries to load the characters with the graphic but in that process the frame is automatically closed. It's as if I came into conflict with something, it's strange, I do not know why I get that error.

On the other hand, due to that situation and according to your recommendations use wxGLstring in my code, an example:

Code: Select all


void TestGLCanvas::Render() ///vendria siendo el void display_cb()
{
   
   MyFrame *li;
   
   wxPaintDC dc(this);
   
#ifndef __WXMOTIF__
   if (!GetContext()) return;
#endif
   
   SetCurrent();
   // Init OpenGL once, but after SetCurrent
   if (!m_init)
   {
   InitGL(0,0,GetSize().x, GetSize().y);
   m_init = true;
   }
   
   glClearColor(1.f,1.f,1.f,1.f); ///Color Blanco
   glClear(GL_COLOR_BUFFER_BIT);
   
   graphic code
   :::::::::::::::
   end code
   
   static wxGLString my_message;
   my_message.Clear();
   dc.Clear();
   
   if(my_message.IsEmpty())
   {
   my_message = wxString( wxT("Hello world !!!") );
   my_message.setFont( wxFont( 5, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD) );
   my_message.consolidate(&dc);
   }
   
   
   // render string everytime
   my_message.bind();
   my_message.rotate(180);
   
   glColor3f(1,0,0);
   my_message.render(80,150);
   
   glFlush();
   SwapBuffers();

}

void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
{
   Render();
}


void TestGLCanvas::OnSize(wxSizeEvent& event) ///Para redimensionar la grafica
{
   // this is also necessary to update the context on some platforms
   wxGLCanvas::OnSize(event);
   
   
   // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
   int w, h;
   GetClientSize(&w, &h);
#ifndef __WXMOTIF__
   if (GetContext())
#endif
   {
      SetCurrent();
      glViewport(0, 0, (GLint) w, (GLint) h);
   }
   
   
}

void TestGLCanvas::InitGL(int topleft_x, int topleft_y, int bottomrigth_x, int bottomrigth_y) ///vendria siendo el void reshape_cb (int w, int h)
{
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity ();
   gluOrtho2D(0,700,0,250);

   glEnable(GL_TEXTURE_2D);
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
   
}


In this case it was useful for me as you can see in figure b that you attach, however, when I change the size of the frame the graphic is automatically deleted and the characters are kept in the frame (figure c), but that is more of a problem in OpenGL and not so much for this forum, however I will comment that I have managed to identify the function responsible for deleting the graph: glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

My problem continues to persist and I still can not solve it, what I do not understand is because the function glutStrokeCharacter (void * font, int character) does not work in wxwidgets; If it worked and my problem was solved, in any case thank you very much for your timely responses.
Attachments
imagen c.png
figure c
imagen c.png (14.42 KiB) Viewed 302 times
imagen b.png
figure b
imagen b.png (16.82 KiB) Viewed 302 times
Prueba_conOpengl.png
Prueba_conOpenGL
Prueba_conOpengl.png (9.11 KiB) Viewed 302 times

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

Re: integrate wxglcanvas with other events (lists, buttons, others)

Postby Manolo » Thu Jun 28, 2018 1:03 pm

In the old days (1992) when OpenGL started its own way appart from the original Silicon Graphics' Iris, some external APIs were also born. The two most famous were glu and glut. glu added some common features (setting the camera, or the projection, and some more) that OGL API lacked.

glut solved a common problem: dealing with windows and user inputs. It's quite simple. It also has the feature of bitmaps and stroke fonts. The last specification dates on march-2000. Modern OpenGL began about 2009.

You can not mix wxWidgets and glut. They will repeat window and gl-context handling, but without sharing anything between them.
You can use glu. My advice is that you don't and stick to modern OGL.


Return to “C++ Development”

Who is online

Users browsing this forum: wxJack and 22 guests