我們添加了一個三角形和一個四邊形。也許你認(rèn)為這很簡單,但你已經(jīng)邁出了一大步,要知道任何在OpenGL中繪制的模型都會被分解為這兩種簡單的圖形。
lesson1.h
#ifndef?LESSON1_H #define?LESSON1_H #include#includeclass?QPainter; class?QOpenGLContext; class?QOpenGLPaintDevice; class?Lesson1?:?public?QWindow,?QOpenGLFunctions_1_0 { ????Q_OBJECT public: ????explicit?Lesson1(QWindow?*parent?=?0); ????~Lesson1(); ????virtual?void?render(QPainter?*); ????virtual?void?render(); ????virtual?void?initialize(); public?slots: ????void?renderNow(); protected: ????void?exposeEvent(QExposeEvent?*); ????void?resizeEvent(QResizeEvent?*); private: ????void?myPerspective(?GLdouble?fov,?GLdouble?aspectRatio,?GLdouble?zNear,?GLdouble?zFar?); private: ????QOpenGLContext?*m_context; }; #endif?//?LESSON1_H
lesson1.cpp
#include?"lesson1.h" #include#include#include#includeLesson1::Lesson1(QWindow?*parent)?: ????QWindow(parent) ??,?m_context(0) { ????setSurfaceType(QWindow::OpenGLSurface); } Lesson1::~Lesson1() { } void?Lesson1::render(QPainter?*painter) { ????Q_UNUSED(painter); } void?Lesson1::myPerspective(?GLdouble?fov,?GLdouble?aspectRatio,?GLdouble?zNear,?GLdouble?zFar?) { ????//?使用glu庫函數(shù),需要添加glu.h頭文件 ????//?gluPerspective(fov,?aspectRatio,?zNear,?zFar); ????GLdouble?rFov?=?fov?*?3.14159265?/?180.0; ????glFrustum(?-zNear?*?tan(?rFov?/?2.0?)?*?aspectRatio, ???????????????zNear?*?tan(?rFov?/?2.0?)?*?aspectRatio, ???????????????-zNear?*?tan(?rFov?/?2.0?), ???????????????zNear?*?tan(?rFov?/?2.0?), ???????????????zNear,?zFar?); } void?Lesson1::render() { ????glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); ????glViewport(0,0,(GLint)width(),(GLint)height());?//?重置當(dāng)前視口 ????glMatrixMode(GL_PROJECTION);????????????????????//?選擇投影矩陣 ????glLoadIdentity();???????????????????????????????//?重置投影矩陣為單位矩陣 ????//?glu庫函數(shù)Qt不支持,但是glu庫函數(shù)是對gl庫函數(shù)的封裝,方便使用。因此我們可以自己 ????//?寫一個類似gluPerspective的函數(shù)myPerspective,用于設(shè)置透視。 ????//gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); ????myPerspective(45.0,(GLfloat)width()/(GLfloat)height(),0.1,100.0); ????glMatrixMode(GL_MODELVIEW);//?選擇模型視圖矩陣 ????glLoadIdentity();??????????//?重置模型視圖矩陣為單位矩陣 ????glTranslatef(-1.5f,0.0f,-6.0f); ????glBegin(GL_TRIANGLES); //?繪制三角形 ????glVertex3f(?0.0f,?1.0f,?0.0f); //?上頂點 ????glVertex3f(-1.0f,-1.0f,?0.0f); //?左下 ????glVertex3f(?1.0f,-1.0f,?0.0f); //?右下 ????glEnd();????????????????????????//?三角形繪制結(jié)束 ????glTranslatef(3.0f,0.0f,0.0f); ????glBegin(GL_QUADS); //?繪制正方形 ????glVertex3f(-1.0f,?1.0f,?0.0f); //?左上 ????glVertex3f(?1.0f,?1.0f,?0.0f); //?右上 ????glVertex3f(?1.0f,-1.0f,?0.0f); //?左下 ????glVertex3f(-1.0f,-1.0f,?0.0f); //?右下 ????glEnd(); ????//?正方形繪制結(jié)束 } void?Lesson1::initialize() { ????glShadeModel(GL_SMOOTH);??????????????//?啟用平滑著色 ????glClearColor(0.0f,?0.0f,?0.0f,?0.0f);?//?黑色背景 ????glClearDepth(1.0f);???????????????????//?設(shè)置深度緩存 ????glEnable(GL_DEPTH_TEST);??????????????//?啟用深度測試 ????glDepthFunc(GL_LEQUAL);???????????????//?深度測試類型 ????//?接著告訴OpenGL我們希望進行最好的透視修正。這會十分輕微的影響性能。但使得透視圖看起來好一點。 ????glHint(GL_PERSPECTIVE_CORRECTION_HINT,?GL_NICEST); } void?Lesson1::renderNow() { ????if?(!isExposed()) ????????return; ????bool?needsInitialize?=?false; ????if?(!m_context)?{ ????????m_context?=?new?QOpenGLContext(this); ????????m_context->setFormat(requestedFormat()); ????????m_context->create(); ????????needsInitialize?=?true; ????} ????m_context->makeCurrent(this); ????if?(needsInitialize)?{ ????????initializeOpenGLFunctions(); ????????initialize(); ????} ????render(); ????m_context->swapBuffers(this); } void?Lesson1::exposeEvent(QExposeEvent?*event) { ????Q_UNUSED(event); ????if?(isExposed()) ????????renderNow(); } void?Lesson1::resizeEvent(QResizeEvent?*event) { ????Q_UNUSED(event); ????if?(isExposed()) ????????renderNow(); }
main.cpp
#include#includeint?main(int?argc,?char?*argv[]) { ????QGuiApplication?app(argc,?argv); ????QSurfaceFormat?format; ????format.setSamples(16); ????Lesson1?window; ????window.setFormat(format); ????window.resize(640,?480); ????window.show(); ????return?app.exec(); }
運行效果
源碼中用到的OpenGL庫函數(shù)可以參考:
OpenGL之glViewPort函數(shù)的用法
OpenGL之glLoadIdentity函數(shù)的用法
OpenGL之glMatrixMode函數(shù)的用法
實際上僅用如下代碼就能畫出一個三角形
void?Lesson1::render() { ????glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); ????glViewport(0,0,(GLint)width(),(GLint)height());?//?重置當(dāng)前視口 ????glBegin(GL_TRIANGLES); //?繪制三角形 ????glVertex3f(?0.0f,?1.0f,?0.0f); //?上頂點 ????glVertex3f(-1.0f,-1.0f,?0.0f); //?左下 ????glVertex3f(?1.0f,-1.0f,?0.0f); //?右下 ????glEnd();????????????????????????//?三角形繪制結(jié)束 }