1.代码部分
OPenGL.pro
QT += core gui opengl greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = OPenGL12 TEMPLATE = app SOURCES += main.cpp\ openglwidget.cpp HEADERS += \ openglwidget.h LIBS += -lopengl32
OpenglWidget.h
#ifndef OPENGLWIDGET_H #define OPENGLWIDGET_H #include <QtOpenGL> class OpenglWidget : public QGLWidget { public: OpenglWidget(QWidget *parent=0); protected: void initializeGL(); void initWidget(); void paintGL(); void resizeGL(int width, int height); private: GLfloat mx; GLfloat my; GLfloat mz; GLfloat m_rotateTriangle; GLuint *textur; }; #endif // OPENGLWIDGET_H
OpenglWidget.cpp
#include "openglwidget.h" OpenglWidget::OpenglWidget(QWidget *parent):QGLWidget(parent) { mx = 0; my = 0; mz = 0; initWidget(); initializeGL(); } void OpenglWidget::initializeGL() { //加载图片 QImage mpic; QImage newPic; mpic.load("D://Documents//OPenGL12//haha.jpg"); newPic=QGLWidget::convertToGLFormat(mpic); glGenTextures(1,&textur[0]); glBindTexture(GL_TEXTURE_2D,textur[0]); glTexImage2D(GL_TEXTURE_2D,0,3,newPic.width(),newPic.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,newPic.bits()); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); QImage mpic1; QImage newPic1; mpic1.load("D://Documents//OPenGL12//haha1.jpg"); newPic1=QGLWidget::convertToGLFormat(mpic1); glGenTextures(1,&textur[1]); glBindTexture(GL_TEXTURE_2D,textur[1]); glTexImage2D(GL_TEXTURE_2D,0,3,newPic1.width(),newPic1.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,newPic1.bits()); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //启动纹理,负责会全为白色 glEnable(GL_TEXTURE_2D); //设置着色模式,平滑的 glShadeModel(GL_SMOOTH); //清除掉之前的所有颜色 glClearColor(0.0,0.0,0.0,0.5); //深度缓存,设置初始值为1.0,小于1.0的部分是可见的 glClearDepth(1.0); //启动OPenGL的相关功能,由参数决定,这里指 //(启用了之后,OpenGL在绘制的时候就会检查,当前像素前面是否有别的像素,如果别的像素挡道了它,那它就不会绘制,也就是说,OpenGL就只绘制最前面的一层) glEnable(GL_DEPTH_TEST); //制定深度缓存比较值 //这里参数指的是如果输入的深度值小于或者等于参考值则通过 glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); } void OpenglWidget::initWidget() { //从屏幕上(400,400)为起始点,显示一个640*400的界面 setGeometry(400,200,640,480); setWindowTitle("My OPenGL"); } void OpenglWidget::paintGL() { //清除颜色缓冲和深度缓冲 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //将当前点移置屏幕中心,相当于复位的操作 glLoadIdentity(); //平移函数,参数指的是分别从X轴,Y轴,Z轴平移 glTranslatef(-1.5,0.0,-6.0); glRotatef( mx,1.0, 0.0,0.0 ); glRotatef(my,0.0,1.0,0.0 ); glRotatef(mz,0.0,0.0,1.0 ); glBindTexture( GL_TEXTURE_2D, textur[0] ); glBegin( GL_QUADS ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0, 1.0, -1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, -1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 1.0, -1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, -1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0, -1.0, -1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, -1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0, 1.0, 1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 1.0, -1.0 ); glEnd(); glLoadIdentity(); glTranslatef( 1.5, 0.0, -6.0 ); glBindTexture( GL_TEXTURE_2D, textur[1] ); glRotatef( m_rotateTriangle, 0.0, 1.0, 0.0 ); glBegin(GL_TRIANGLES); glTexCoord2f( 1, 1 ); glVertex3f( 0, 1, 0 ); glTexCoord2f( 0, 0 ); glVertex3f( 1, -1, 1 ); glTexCoord2f( 1, 0 ); glVertex3f( -1, -1, 1 ); glTexCoord2f( 1, 1 ); glVertex3f( 0, 1, 0 ); glTexCoord2f( 0, 0 ); glVertex3f( -1.0, -1.0, 1.0 ); glTexCoord2f( 1, 0 ); glVertex3f( -1.0, -1.0, -1.0 ); glTexCoord2f( 1, 1 ); glVertex3f( 0, 1, 0 ); glTexCoord2f( 0, 0 ); glVertex3f( -1.0, -1.0, -1.0 ); glTexCoord2f( 1, 0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 1, 1 ); glVertex3f( 0, 1, 0 ); glTexCoord2f( 0, 0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 1, 0 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 0, 0 ); glVertex3f( -1.0, -1.0, -1.0 ); glTexCoord2f( 1, 0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 1, 1 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 1, 0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 1, 1 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 0, 1 ); glVertex3f( -1.0, -1.0, 1.0 ); glTexCoord2f( 1, 1 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 0, 1 ); glVertex3f( -1.0, -1.0, 1.0 ); glTexCoord2f( 0, 0 ); glVertex3f( -1.0, -1.0, -1.0 ); glEnd(); mx+=70; my+=0; mz+=0; m_rotateTriangle+=10; } void OpenglWidget::resizeGL(int width, int height) { if(0==height) height=1; //告诉绘制到窗体的哪个位置 glViewport(0,0,width,height); // 设置矩阵模式,参数是设置为投影矩阵 glMatrixMode(GL_PROJECTION); //复位操作 glLoadIdentity(); GLdouble aspectRatio=(GLfloat)width/(GLfloat)height; GLdouble rFov=45.0*3.14159265/180.0; GLdouble zNear=0.1; GLdouble zFar=100.0; //调用glFrustum,生成矩阵与当前矩阵相乘,生成透视效果 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); //切回模型视图矩阵 glMatrixMode(GL_MODELVIEW); //复位 glLoadIdentity(); }
2.注意
glTexCoord2f( x, y ); glVertex3f( x, y, z );
glTexCoord2f这个用于表示原图片的坐标,这样更容易理解,就是以 在x,y 轴的平面里面,(0,0)表示图片的左下角, (0,1)表示左上角,(1,1)表示右上角,(1,0)表示右下角。而对应的glVertex3f则对应为 (-1, -1) , (-1, 1) , (1, 1), (1, -1)。我们怎么来理解这种对应关系呢?那就需要贴图的坐标必须一一对应,就是我们如果顺时针写, 对应的坐都要顺时针,如果逆时针写,对应的坐标都要逆时针一一对应。
我们的贴图是一张图片,所以它一定是一个平面。 所以坐标从(0,0)开始,这个容易使用。而我们需要贴图的立体图形,虽然每个面是平面图形,但它在坐标系中,始终以立体图形的中心为坐标原点,所以,它是一个三维坐标,三维坐标与二维的对应,就只有以相同的平面顶点旋转顺序来对应了。