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: 6
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: 12321
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: 6
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 158 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 158 times

User avatar
doublemax
Moderator
Moderator
Posts: 12321
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: 6
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 105 times

User avatar
doublemax
Moderator
Moderator
Posts: 12321
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: 6
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 6 times
wxglcanvas wxpaintdc.png
wxglcanvas wxpaintdc (I)
wxglcanvas wxpaintdc.png (17.04 KiB) Viewed 6 times

User avatar
doublemax
Moderator
Moderator
Posts: 12321
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!


Return to “C++ Development”

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot] and 6 guests