wxWidgets 中的简单 openGL 显示循环期间场景重绘不完整
我正在努力在 wxWidets openGl 应用程序中实现一个简单的动画循环。我遇到了循环迭代在每次迭代显示屏幕之前未完全绘制屏幕的问题。看起来 0.1 秒足以完全绘制简单的场景......任何人都可以告诉我为什么它可能不会吗?
谢谢!
#include <wx/wx.h>
#include <wx/glcanvas.h>
#ifdef __WXMAC__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#ifndef WIN32
#include <unistd.h> // FIXME: ¿This work/necessary in Windows?
//Not necessary, but if it was, it needs to be replaced by process.h AND io.h
#endif
//#include "GlBox.cpp"
#include <iostream>
using namespace std;
class wxGLCanvasSubClass: public wxGLCanvas {
public:
wxGLCanvasSubClass(wxFrame* parent);
void Paintit(wxPaintEvent& event);
void Render();
protected:
DECLARE_EVENT_TABLE()
//GlBox myBox;
};
wxGLCanvasSubClass *thing;
static void timerRender(int count)
{
thing->Render();
cout << "render timeout was called \n";
glutTimerFunc(25, timerRender, 0);
}
static void myIdleFunc()
{
cout << "idleing \n";
cout.flush();
}
static void setRender(wxGLCanvasSubClass *thing2)
{
thing = thing2;
cout << "global thing was set \n";
glutTimerFunc(1100, timerRender, 0);
}
BEGIN_EVENT_TABLE(wxGLCanvasSubClass, wxGLCanvas)
EVT_PAINT (wxGLCanvasSubClass::Paintit)
END_EVENT_TABLE()
wxGLCanvasSubClass::wxGLCanvasSubClass(wxFrame *parent)
:wxGLCanvas(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas")){
int argc = 1;
char* argv[1] = { wxString((wxTheApp->argv)[0]).char_str() };
/*
NOTE: this example uses GLUT in order to have a free teapot model
to display, to show 3D capabilities. GLUT, however, seems to cause problems
on some systems. If you meet problems, first try commenting out glutInit(),
then try comeenting out all glut code
*/
glutInit(&argc, argv);
glutIdleFunc(myIdleFunc);
}
void wxGLCanvasSubClass::Paintit(wxPaintEvent& WXUNUSED(event)){
Render();
}
void wxGLCanvasSubClass::Render()
{
SetCurrent();
wxPaintDC(this);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, (GLint)GetSize().x, (GLint)GetSize().y);
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(-0.5, -0.5);
glVertex2f(-0.5, 0.5);
glVertex2f(0.5, 0.5);
glVertex2f(0.5, -0.5);
glColor3f(0.4, 0.5, 0.4);
glVertex2f(0.0, -0.8);
glEnd();
// using a little of glut
glColor4f(0,0,1,1);
glutWireTeapot(0.4);
glLoadIdentity();
glColor4f(2,0,1,1);
glutWireTeapot(0.6);
//myBox.getIt();
SwapBuffers();
glFlush();
//
}
class MyApp: public wxApp
{
virtual bool OnInit();
void onIdle(wxIdleEvent& evt);
time_t lastEvent;
bool slept ;
wxGLCanvas * MyGLCanvas;
wxGLCanvasSubClass * myCanvas;
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
slept = false;
lastEvent = time( &lastEvent);
wxFrame *frame = new wxFrame((wxFrame *)NULL, -1, wxT("Hello GL World"), wxPoint(50,50), wxSize(200,200));
myCanvas = new wxGLCanvasSubClass(frame);
frame->Show(TRUE);
Connect( wxID_ANY, wxEVT_IDLE, wxIdleEventHandler(MyApp::onIdle) );
return TRUE;
}
void MyApp::onIdle(wxIdleEvent& evt)
{
if(slept)
{
slept = false;
cout << "event hit " << lastEvent;
myCanvas->Render();
evt.RequestMore();
} else {
cout << "idleing \n " << lastEvent;
usleep(100000);
slept = true;
evt.RequestMore();
}
}
I'm working on getting a simple animation loop going in a wxWidets openGl app. I am having a problem with the loop iterations not fully drawing the screen before displaying it on each iteration. It seems like .1s is more than enough to fully draw the simple scene.... Can anyone give me an idea of why it might not?
Thanks!
#include <wx/wx.h>
#include <wx/glcanvas.h>
#ifdef __WXMAC__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#ifndef WIN32
#include <unistd.h> // FIXME: ¿This work/necessary in Windows?
//Not necessary, but if it was, it needs to be replaced by process.h AND io.h
#endif
//#include "GlBox.cpp"
#include <iostream>
using namespace std;
class wxGLCanvasSubClass: public wxGLCanvas {
public:
wxGLCanvasSubClass(wxFrame* parent);
void Paintit(wxPaintEvent& event);
void Render();
protected:
DECLARE_EVENT_TABLE()
//GlBox myBox;
};
wxGLCanvasSubClass *thing;
static void timerRender(int count)
{
thing->Render();
cout << "render timeout was called \n";
glutTimerFunc(25, timerRender, 0);
}
static void myIdleFunc()
{
cout << "idleing \n";
cout.flush();
}
static void setRender(wxGLCanvasSubClass *thing2)
{
thing = thing2;
cout << "global thing was set \n";
glutTimerFunc(1100, timerRender, 0);
}
BEGIN_EVENT_TABLE(wxGLCanvasSubClass, wxGLCanvas)
EVT_PAINT (wxGLCanvasSubClass::Paintit)
END_EVENT_TABLE()
wxGLCanvasSubClass::wxGLCanvasSubClass(wxFrame *parent)
:wxGLCanvas(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas")){
int argc = 1;
char* argv[1] = { wxString((wxTheApp->argv)[0]).char_str() };
/*
NOTE: this example uses GLUT in order to have a free teapot model
to display, to show 3D capabilities. GLUT, however, seems to cause problems
on some systems. If you meet problems, first try commenting out glutInit(),
then try comeenting out all glut code
*/
glutInit(&argc, argv);
glutIdleFunc(myIdleFunc);
}
void wxGLCanvasSubClass::Paintit(wxPaintEvent& WXUNUSED(event)){
Render();
}
void wxGLCanvasSubClass::Render()
{
SetCurrent();
wxPaintDC(this);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, (GLint)GetSize().x, (GLint)GetSize().y);
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 1.0);
glVertex2f(-0.5, -0.5);
glVertex2f(-0.5, 0.5);
glVertex2f(0.5, 0.5);
glVertex2f(0.5, -0.5);
glColor3f(0.4, 0.5, 0.4);
glVertex2f(0.0, -0.8);
glEnd();
// using a little of glut
glColor4f(0,0,1,1);
glutWireTeapot(0.4);
glLoadIdentity();
glColor4f(2,0,1,1);
glutWireTeapot(0.6);
//myBox.getIt();
SwapBuffers();
glFlush();
//
}
class MyApp: public wxApp
{
virtual bool OnInit();
void onIdle(wxIdleEvent& evt);
time_t lastEvent;
bool slept ;
wxGLCanvas * MyGLCanvas;
wxGLCanvasSubClass * myCanvas;
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
slept = false;
lastEvent = time( &lastEvent);
wxFrame *frame = new wxFrame((wxFrame *)NULL, -1, wxT("Hello GL World"), wxPoint(50,50), wxSize(200,200));
myCanvas = new wxGLCanvasSubClass(frame);
frame->Show(TRUE);
Connect( wxID_ANY, wxEVT_IDLE, wxIdleEventHandler(MyApp::onIdle) );
return TRUE;
}
void MyApp::onIdle(wxIdleEvent& evt)
{
if(slept)
{
slept = false;
cout << "event hit " << lastEvent;
myCanvas->Render();
evt.RequestMore();
} else {
cout << "idleing \n " << lastEvent;
usleep(100000);
slept = true;
evt.RequestMore();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当涉及到 OpenGL 时,GLUT 并不是必须使用的东西。 GLUT是一个第三方框架,wxWidgets是一个第三方框架。两者都实现了事件循环。
你不应该混合这些。只需使用 wxWidgets,它提供了一个非常精细的 OpenGL 小部件。
GLUT is not a mandatory thing to use when it comes to OpenGL. GLUT is a third party framework, wxWidgets is a third party framework. And both implement a event loop.
You should not mix these. Just use wxWidgets only, which provides a very fine OpenGL widget.