wxWidgets中OpenGL渲染环境的配置,主要解决不能显示物体阴影问题
2015-05-12 13:01
495 查看
在使用wxWidgets图形库之前,一直在使用GLUT库来为OpenGL程序提供图形界面,但其毕竟只能算是一个中间过渡,想要有更完整的图形的库,那么选择之一便是wxWidgets库。
目前本人所使用的wxWidgets版本号是"wxWidgets-3.0.2",想要有使用其它版本,请参考官网。
下面主要分享一下在wxCanvas中如何设置OpenGL渲染上下文,解决物体阴影不能显示的问题,给出一个wxGLCanvas初始化的例子。
直接上代码:
1.头文件main.h
#include "wx/wx.h"
#include "wx/glcanvas.h"
class BasicGLPane : public wxGLCanvas
{
wxGLContext* m_context;
public:
BasicGLPane(wxFrame* parent, int* args);
virtual ~BasicGLPane();
void resized(wxSizeEvent& evt);
int getWidth();
int getHeight();
void render(wxPaintEvent& evt);
void prepare3DViewport(int topleft_x, int topleft_y, int bottomrigth_x, int bottomrigth_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
2.cpp文件main.cpp
#include <gl\glew.h>
#include "wx/wx.h"
#include "wx/sizer.h"
#include "wx/glcanvas.h"
#include "main.h"
#include "shadowGenerator.h"
// include OpenGL
#ifdef __WXMAC__
#include "OpenGL/glu.h"
#include "OpenGL/gl.h"
#else
#include <GL/glu.h>
#include <GL/gl.h>
#endif
class MyApp : public wxApp
{
virtual bool OnInit();
wxFrame *frame;
BasicGLPane * glPane;
public:
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
//wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
frame = new wxFrame((wxFrame *)NULL, -1, wxT("Hello GL World"), wxPoint(50, 50), wxSize(400, 400));
<span style="color:#000099;"><span style="white-space:pre"> </span>//很重要的一个参数集,下面正文会有讲到
int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 32, 0 };
</span>
glPane = new BasicGLPane((wxFrame*)frame, args);
//sizer->Add(glPane, 1, wxEXPAND);
//frame->SetSizer(sizer);
//frame->SetAutoLayout(true);
frame->Show();
InitGLObjects();
return true;
}
BEGIN_EVENT_TABLE(BasicGLPane, wxGLCanvas)
EVT_MOTION(BasicGLPane::mouseMoved)
EVT_LEFT_DOWN(BasicGLPane::mouseDown)
EVT_LEFT_UP(BasicGLPane::mouseReleased)
EVT_RIGHT_DOWN(BasicGLPane::rightClick)
EVT_LEAVE_WINDOW(BasicGLPane::mouseLeftWindow)
EVT_SIZE(BasicGLPane::resized)
EVT_KEY_DOWN(BasicGLPane::keyPressed)
EVT_KEY_UP(BasicGLPane::keyReleased)
EVT_MOUSEWHEEL(BasicGLPane::mouseWheelMoved)
EVT_PAINT(BasicGLPane::render)
END_EVENT_TABLE()
// some useful events to use
void BasicGLPane::mouseMoved(wxMouseEvent& event) {}
void BasicGLPane::mouseDown(wxMouseEvent& event) {}
void BasicGLPane::mouseWheelMoved(wxMouseEvent& event) {}
void BasicGLPane::mouseReleased(wxMouseEvent& event) {}
void BasicGLPane::rightClick(wxMouseEvent& event) {}
void BasicGLPane::mouseLeftWindow(wxMouseEvent& event) {}
void BasicGLPane::keyPressed(wxKeyEvent& event) {}
void BasicGLPane::keyReleased(wxKeyEvent& event) {}
BasicGLPane::BasicGLPane(wxFrame* parent, int* args) :
wxGLCanvas(parent, wxID_ANY, args, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
{
1、一开始想在wxWigets中也用GLUT来显示设备、显示模式等。
结论:愚拙的想法,外来人(GLUT)想来套近乎?只是“我”太高冷。
2、采用wxGLCanvas默认的上下文设置,即使用SetCurrent(),而非SetCurrent(*m_context)。
结论:SetCurrent():我不想梳妆打扮就去相亲。等我,Shadow。
Shadow: 你太不符合我的胃口了,我也是有节操的,我是不会跟你一起的出现的。
SetCurrent():真任性。我回去重新包装一下,看你还傲娇不。
3、定义一个窗体参数集 int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE,
16 /*32*/, 0 };完成自定义风格的绘制设置。
结论:SetCurrent():Hi,Shadow我又来了,这次怎么样?
Shadow: 你就想用16(深度缓冲精度)分的妆容来见我?
SetCurrent():你还想我怎样?就配你还不够?
Shadow: 就我吧,起码你得32分才可以。。(事实上,24就可以,毕竟傲娇嘛。)
SetCurrent():我也是有原则的,最多24,给你,爱要不要。
Shadow: 来吧,我们结婚吧。!!
小注:深度缓存的位数是衡量深度缓存精度的参数。深度缓存位数越高,则精确度越高,目前的显卡一般都可支持16位的Z
Buffer,一些高级的显卡已经可以支持32位的Z Buffer,但一般用24位Z Buffer就已经足够了。更加详细说明,请查
阅Z-BUFFER相关内容。
最后,基本上自己所用到的所有绘制功能都可以在这种配置上正确运行,但请不要忘了glewInit()的初始化,这个是必不可少的。
大家若是有其他更高的需求,请参考他人的文章。
PS:上面用到的代码示例,摘取自https://wiki.wxwidgets.org/WxGLCanvas。
目前本人所使用的wxWidgets版本号是"wxWidgets-3.0.2",想要有使用其它版本,请参考官网。
下面主要分享一下在wxCanvas中如何设置OpenGL渲染上下文,解决物体阴影不能显示的问题,给出一个wxGLCanvas初始化的例子。
直接上代码:
1.头文件main.h
#include "wx/wx.h"
#include "wx/glcanvas.h"
class BasicGLPane : public wxGLCanvas
{
wxGLContext* m_context;
public:
BasicGLPane(wxFrame* parent, int* args);
virtual ~BasicGLPane();
void resized(wxSizeEvent& evt);
int getWidth();
int getHeight();
void render(wxPaintEvent& evt);
void prepare3DViewport(int topleft_x, int topleft_y, int bottomrigth_x, int bottomrigth_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
2.cpp文件main.cpp
#include <gl\glew.h>
#include "wx/wx.h"
#include "wx/sizer.h"
#include "wx/glcanvas.h"
#include "main.h"
#include "shadowGenerator.h"
// include OpenGL
#ifdef __WXMAC__
#include "OpenGL/glu.h"
#include "OpenGL/gl.h"
#else
#include <GL/glu.h>
#include <GL/gl.h>
#endif
class MyApp : public wxApp
{
virtual bool OnInit();
wxFrame *frame;
BasicGLPane * glPane;
public:
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
//wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
frame = new wxFrame((wxFrame *)NULL, -1, wxT("Hello GL World"), wxPoint(50, 50), wxSize(400, 400));
<span style="color:#000099;"><span style="white-space:pre"> </span>//很重要的一个参数集,下面正文会有讲到
int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 32, 0 };
</span>
glPane = new BasicGLPane((wxFrame*)frame, args);
//sizer->Add(glPane, 1, wxEXPAND);
//frame->SetSizer(sizer);
//frame->SetAutoLayout(true);
frame->Show();
InitGLObjects();
return true;
}
BEGIN_EVENT_TABLE(BasicGLPane, wxGLCanvas)
EVT_MOTION(BasicGLPane::mouseMoved)
EVT_LEFT_DOWN(BasicGLPane::mouseDown)
EVT_LEFT_UP(BasicGLPane::mouseReleased)
EVT_RIGHT_DOWN(BasicGLPane::rightClick)
EVT_LEAVE_WINDOW(BasicGLPane::mouseLeftWindow)
EVT_SIZE(BasicGLPane::resized)
EVT_KEY_DOWN(BasicGLPane::keyPressed)
EVT_KEY_UP(BasicGLPane::keyReleased)
EVT_MOUSEWHEEL(BasicGLPane::mouseWheelMoved)
EVT_PAINT(BasicGLPane::render)
END_EVENT_TABLE()
// some useful events to use
void BasicGLPane::mouseMoved(wxMouseEvent& event) {}
void BasicGLPane::mouseDown(wxMouseEvent& event) {}
void BasicGLPane::mouseWheelMoved(wxMouseEvent& event) {}
void BasicGLPane::mouseReleased(wxMouseEvent& event) {}
void BasicGLPane::rightClick(wxMouseEvent& event) {}
void BasicGLPane::mouseLeftWindow(wxMouseEvent& event) {}
void BasicGLPane::keyPressed(wxKeyEvent& event) {}
void BasicGLPane::keyReleased(wxKeyEvent& event) {}
BasicGLPane::BasicGLPane(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
<span style="color:#000099;"><span style="white-space: pre;"> </span>//原文上设置为,wxBG_STYLE_CUSTOM,但是在这个版本中,已声明为predicated,请使用wxBG_STYLE_PAIT </span> SetBackgroundStyle(wxBG_STYLE_PAINT);
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>//SetCurrent( ),默许设置,还是算了。 SetCurrent(*m_context); if (glewInit() != GLEW_OK) { int i = 0; } } BasicGLPane::~BasicGLPane() { delete m_context; } void BasicGLPane::resized(wxSizeEvent& evt) { wxGLCanvas::OnSize(evt); //if (getHeight()== 0) //h = 1; glViewport(0.0, 0.0, getWidth(), getHeight()); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLdouble)getWidth() / getHeight(), 0.01f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0f, 0.0, 10.0f, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0f); //Refresh(); //取消注释,则在本人电脑上会出现闪烁的问题 } /** Inits the OpenGL viewport for drawing in 3D. */ void BasicGLPane::prepare3DViewport(int topleft_x, int topleft_y, int bottomrigth_x, int bottomrigth_y) { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black Background glClearDepth(1.0f); // Depth Buffer Setup glEnable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //glEnable(GL_COLOR_MATERIAL); glViewport(topleft_x, topleft_y, bottomrigth_x - topleft_x, bottomrigth_y - topleft_y); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float ratio_w_h = (float)(bottomrigth_x - topleft_x) / (float)(bottomrigth_y - topleft_y); gluPerspective(45 /*view angle*/, ratio_w_h, 0.1 /*clip close*/, 100 /*clip far*/); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int BasicGLPane::getWidth() { return GetSize().x; } int BasicGLPane::getHeight() { return GetSize().y; } void BasicGLPane::render(wxPaintEvent& evt) { if (!IsShown()) return; wxGLCanvas::SetCurrent(*m_context); wxPaintDC(this); // only to be used in paint events. use wxClientDC to paint outside the paint event glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // ------------- draw some 3D ---------------- prepare3DViewport(getWidth() / 2, 0, getWidth(), getHeight()); glLoadIdentity();
<span style="white-space:pre"> </span>//to draw something
SwapBuffers(); }程序中遇到的问题:
1、一开始想在wxWigets中也用GLUT来显示设备、显示模式等。
结论:愚拙的想法,外来人(GLUT)想来套近乎?只是“我”太高冷。
2、采用wxGLCanvas默认的上下文设置,即使用SetCurrent(),而非SetCurrent(*m_context)。
结论:SetCurrent():我不想梳妆打扮就去相亲。等我,Shadow。
Shadow: 你太不符合我的胃口了,我也是有节操的,我是不会跟你一起的出现的。
SetCurrent():真任性。我回去重新包装一下,看你还傲娇不。
3、定义一个窗体参数集 int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE,
16 /*32*/, 0 };完成自定义风格的绘制设置。
结论:SetCurrent():Hi,Shadow我又来了,这次怎么样?
Shadow: 你就想用16(深度缓冲精度)分的妆容来见我?
SetCurrent():你还想我怎样?就配你还不够?
Shadow: 就我吧,起码你得32分才可以。。(事实上,24就可以,毕竟傲娇嘛。)
SetCurrent():我也是有原则的,最多24,给你,爱要不要。
Shadow: 来吧,我们结婚吧。!!
小注:深度缓存的位数是衡量深度缓存精度的参数。深度缓存位数越高,则精确度越高,目前的显卡一般都可支持16位的Z
Buffer,一些高级的显卡已经可以支持32位的Z Buffer,但一般用24位Z Buffer就已经足够了。更加详细说明,请查
阅Z-BUFFER相关内容。
最后,基本上自己所用到的所有绘制功能都可以在这种配置上正确运行,但请不要忘了glewInit()的初始化,这个是必不可少的。
大家若是有其他更高的需求,请参考他人的文章。
PS:上面用到的代码示例,摘取自https://wiki.wxwidgets.org/WxGLCanvas。
相关文章推荐
- 解决jsp验证码在以下环境不能显示的问题(jdk1.4+tomcat5.0+linux)
- Ophone2.0开发环境搭建配置及模拟器显示不全问题的解决
- 使用cygwin在windows上模拟unix环境,解决不能显示中文的问题
- OpenGL禁用深度测试 解决正投影贴图模式下集显电脑不能显示文字问题。
- 使用cygwin在windows上模拟unix环境,解决不能显示中文的问题
- linux环境weblogic & tomcat 下报表里报出的图表类不能显示和乱码的错误-java.lang.NoClassDefFoundError: sun/awt/X11 问题解决
- Mac环境下的React-Native环境配置流程(主要解决问题Could not install the app on the device)
- 解决 win10+pycharm 环境 Matplotlib图表不能在Pycharm中显示的等问题
- ls command not found,vim都不能使用,环境变量配置错误 的解决办法
- 解决Picasso占用内存,使用Picasso在加载超过2M左右的图片时完全不能显示图片问题(不同的手机可能不同)
- phpstorm 下配置 apache服务器的方法(解决 post不能正确提交到php的问题)
- 解决Windows环境下Git Bash 不能输入中文的问题
- Android 6.0 解决recyclerview 在 scrollview 中不能全部显示,高度不正常的问题
- slf4j使用xml配置日志不能显示的问题
- windows 环境下Tensorboard 不能显示的解决办法
- 通过 spring 的 EL 表达式解决不同环境的部署参数配置问题
- [Git配置]Git本地中文文件名问题解决 linux环境
- maven环境搭建以、在eclipse中如何配置、maven库遇到问题解决方法
- win7下,QT 及 QGLViewer 环境配置总结 | 版本匹配问题 | 解决debug模式下无法打开窗口
- Tomcat的环境配置(一闪而过问题解决)