OPenGL笔记

您所在的位置:网站首页 opengl纹理映射方式 OPenGL笔记

OPenGL笔记

#OPenGL笔记| 来源: 网络整理| 查看: 265

#include "gl_test.h"

GL_Test::GL_Test(QWidget* parent, bool fs) : QGLWidget(parent){ fullscreen = fs;

xRot = 0.0; yRot = 0.0; zRot = 0.0;

setGeometry(500,500,640,480); //设置窗口大小、位置

setWindowTitle("The first OpenGL Window"); //设置窗口标题

if(fullscreen) { showFullScreen(); }

QTimer* timer = new QTimer(this); connect(timer,&QTimer::timeout,[=]{ updateGL(); }); timer->start(50);}

GL_Test::~GL_Test(){

}

void GL_Test::initializeGL(){ loadGLTextures(); //载入纹理

glEnable(GL_TEXTURE_2D); //启用纹理

glShadeModel(GL_SMOOTH); //启用smooth shading(阴影平滑)

glClearColor(0.0, 0.0, 0.0, 0.5); //清除屏幕时所用的颜色,rgba【0.0(最黑)~1.0(最亮)】

glClearDepth(1.0); //设置深度缓存

glEnable(GL_DEPTH_TEST); //启动深度测试

glDepthFunc(GL_LEQUAL); //所作深度测试的类型

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //真正精细的透视修正,告诉OPenGL我们希望进行最好的透视修正,这会十分轻微的影响性能,但使得透视图看起来好一点}

void GL_Test::paintGL(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存

//----------------------------------------- glLoadIdentity(); //重置当前的模型观察矩阵

glTranslatef(0.0, 0.0, -5.0);

glRotatef(xRot, 1.0, 0.0, 0.0); //绕X轴旋转xRot度 glRotatef(yRot, 0.0, 1.0, 0.0); //绕X轴旋转yRot度 glRotatef(zRot, 0.0, 0.0, 1.0); //绕X轴旋转zRot度

//选择我们使用的纹理 glBindTexture(GL_TEXTURE_2D, texture[0]); //如果您在您的场景中使用多个纹理,您应该使用来 glBindTexture(GL_TEXTURE_2D, texture[所使用纹理对应的数字]) 选择要绑定的纹理; //当您想改变纹理时,应该绑定新的纹理。并且您不能在glBegin()和glEnd()之间绑定纹理,必须在glBegin()之前或glEnd()之后绑定;

//绘制正方形开始 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(); //绘制正方形结束

//----------------------------------------- xRot += 2; yRot += 3; zRot += 4;}

void GL_Test::resizeGL(int w, int h){ if(h == 0) { //防止h为0 h = 1; }

glViewport(0, 0, (GLint)w, (GLint)h); //重置当前的视口(Viewport)

glMatrixMode(GL_PROJECTION); //选择投影矩阵

glLoadIdentity(); //重置投影矩阵

gluPerspective( 45.0, (GLfloat)w/(GLfloat)h, 0.1, 100.0 ); //建立透视投影矩阵

glMatrixMode(GL_MODELVIEW); //选择模型观察矩阵

glLoadIdentity(); //重置模型观察矩阵}

void GL_Test::keyPressEvent(QKeyEvent* e){ switch (e->key()) { case Qt::Key_Q: { fullscreen = !fullscreen; if(fullscreen) { showFullScreen(); }else { showNormal(); setGeometry(500,500,640,480); } updateGL(); break; }//case Qt::Key_Q

case Qt::Key_Escape: { close(); }//Qt::Key_Escape

}//switch (e->key())}

void GL_Test::loadGLTextures(){ QImage tex,buf; if(!buf.load(":/Images/1591561503-gB5rD.jpg")) { //用QImage类载入纹理图片 QImage dummy(128,128,QImage::Format_RGB32); //如果载入不成功,生成一个128*128的32位色的绿色图片 dummy.fill(Qt::green); buf = dummy; } tex = QGLWidget::convertToGLFormat(buf); //QGLWidget的静态函数,专门用来转换图片

glGenTextures(1,&texture[0]); //创建一个纹理

glBindTexture(GL_TEXTURE_2D,texture[0]); //使用来自位图数据生成的典型纹理 /*告诉OPenGL将纹理名字texture[0]绑定到纹理目标上;2D纹理只有高度(在Y轴上)和宽度(在X轴上)*/

//真正的创建纹理 //GL_TEXTURE_2D:告诉 OpenGL 此纹理是一个 2D 纹理; //数字0:代表图像的详细程度; //数字3:是数据的成分数; //tex.width():是纹理的宽度 //tex.height():是纹理的高度; //GL_RGBA:告诉 OpenGL 图像数据由红、绿、蓝三色数据以及 alpha 通道数据组成; //GL_UNSIGNED_BYTE:意味着组成图像的数据是无符号字节类型的; //tex.bits():告诉 OpenGL 纹理数据的来源; glTexImage2D(GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());

//告诉 OpenGL 在显示图像时,当它比放大得原始的纹理大(GL_TEXTURE_MAG_FILTER)或缩小得比原始得纹理小(GL_TEXTURE_MIN_FILTER)时, //OpenGL 采用的滤波方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //我们都采用 GL_LINEAR,这使得纹理从很远处到离屏幕很近时都平滑显示; //使用 GL_LINEAR 需要 CPU 和显卡做更多的运算,如果您的机器很慢,您也许应该采用 GL_NEAREST; //过滤的纹理在放大的时候,看起来斑驳的很,您也可以结合这两种滤波方式: 在近处时使用 GL_LINEAR,远处时 GL_NEAREST;}



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3