导航:首页 > 编程语言 > opengl画正方体编程

opengl画正方体编程

发布时间:2022-11-27 18:49:28

1. 在QT环境下用OpenGL绘制一个边长为5的立方体,并为立方体贴上自定义纹理。写出实现该功能的具体

void MyGLWidget::loadGLTexture()
{
QImage image(":/dog.jpg");
image = image.convertToFormat(QImage::Format_RGB888);
image = image.mirrored();
glGenTextures(1, &mTexture[0]);

glBindTexture(GL_TEXTURE_2D,mTexture[0]);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
image.width(), image.height(), 0,
GL_RGB, GL_UNSIGNED_BYTE,
image.bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

void MyGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
glLoadIdentity(); // 重置当前的模型观察矩阵
glTranslatef(0.0f,0.0f,-5.0f); // 移入屏幕 5 个单位
//下面三行使立方体绕X、Y、Z轴旋转。旋转多少依赖于变量 xrot , yrot 和 zrot 的值。
glRotatef(mXRotate,1.0f,0.0f,0.0f); // X轴旋转
glRotatef(mYRotate,0.0f,1.0f,0.0f); // Y轴旋转
glRotatef(mZRotate,0.0f,0.0f,1.0f); // Z轴旋转

//下一行代码选择我们使用的纹理。
//如果您在您的场景中使用多个纹理,您应该使用来 glBindTexture(GL_TEXTURE_2D, texture[ 所使用纹理对应的数字 ]) 选择要绑定的
//纹理。当您想改变纹理时,应该绑定新的纹理。有一点值得指出的是,您不能在 glBegin() 和 glEnd() 之间绑定纹理,必须在 glBegin()
//之前或 glEnd() 之后绑定。注意我们在后面是如何使用 glBindTexture 来指定和绑定纹理的。
glBindTexture(GL_TEXTURE_2D, mTexture[0]); // 选择纹理
//为了将纹理正确的映射到四边形上,您必须将纹理的右上角映射到四边形的右上角,纹理的左上角映射到四边形的左上角,
//纹理的右下角映射到四边形的右下角,纹理的左下角映射到四边形的左下角。
//如果映射错误的话,图像显示时可能上下颠倒,侧向一边或者什么都不是。
//glTexCoord2f 的第一个参数是X坐标。 0.0f 是纹理的左侧。 0.5f 是纹理的中点, 1.0f 是纹理的右侧。
//glTexCoord2f 的第二个参数是Y坐标。 0.0f 是纹理的底部。 0.5f 是纹理的中点, 1.0f 是纹理的顶部。
//所以纹理的左上坐标是 X:0.0f,Y:1.0f ,四边形的左上顶点是 X: -1.0f,Y:1.0f 。其余三点依此类推。
//试着玩玩 glTexCoord2f X, Y坐标参数。把 1.0f 改为 0.5f 将只显示纹理的左半部分,把 0.0f 改为 0.5f 将只显示纹理的右半部分。
glBegin(GL_QUADS);
// 前面
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左上
// 后面
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左下
// 顶面
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
// 底面
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下

// 右面
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下

// 左面
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
glEnd();

}

void MyGLWidget::timerEvent(QTimerEvent *event)
{
//现在增加 xrot , yrot 和 zrot 的值。尝试变化每次各变量的改变值来调节立方体的旋转速度,或改变+/-号来调节立方体的旋转方向。
mXRotate += 0.3f; // X 轴旋转
mYRotate += 0.2f; // Y 轴旋转
mZRotate += 0.4f; // Z 轴旋转

updateGL();

QGLWidget::timerEvent(event);
}

void MyGLWidget::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_F2:
{
mFullScreen = !mFullScreen;
if(mFullScreen) {
showFullScreen();
}
else {
showNormal();
}
updateGL();
break;
}
case Qt::Key_Escape:
{
qApp->exit();
break;
}
}
}

#include "myglwidget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyGLWidget w;
w.show();

return a.exec();

————————————————
版权声

2. OpenGL如何使用固定管线下的着色器渲染一个正方形,并用特殊键控制移动

双缓冲窗口 、 RGBA颜色模式 、 深度测试 、 模板缓冲区 。

GLUT 内部运行着一个本地消息循环,用来调用我们不同时间注册进来的回调函数。我们可以注册2个回调函数:1,为窗口改变大小而设置的一个回调函数;2,包含OpenGL渲染的回调函数。

注册的重塑函数 changeSize 方法的实现,通过 glViewport (GLint x, GLint y, GLsizei width, GLsizei height); 来重新设置窗口的大小,x,y 参数代表窗口中视图的左下角坐标,而宽度、高度是像素,为表示,通常x,y 都是为0。

注册的显示函数 void RenderScene(void) 实现,显示函数的具体实现步骤
第一步 : 在该方法中我们需要清除一个或者一组特定的缓存区;
缓存区是一块存着图像信息的存储空间,红色、绿色、蓝色和alpha分量通常一起作为颜色缓存区或像素缓存区引用。OpenGL 中不止一种缓冲区(颜色缓存区、深度缓存区和模板缓存区)清除缓存区对数值进行预置; 参数:指定将要清除的缓存的 GL_COLOR_BUFFER_BIT :指示当前激活的用来进行颜色写入缓冲区 GL_DEPTH_BUFFER_BIT :指示深度缓存区 GL_STENCIL_BUFFER_BIT:指示模板缓冲区。
第二步 :使用一组浮点数来表示红色,设置绘制需要的颜色
第三步 :将设置的颜色传递到存储着色器,即 GLT_SHADER_IDENTITY 着色器,这个着色器只是使用指定颜色以默认笛卡尔坐标第在屏幕上渲染几何图形
第四步 :提交着色器
第五步 :将后台缓冲区进行渲染,然后结束后交换给前台, 在开始的设置openGL 窗口的时候,我们指定要一个双缓冲区的渲染环境。这就意味着将在后台缓冲区进行渲染,渲染结束后交换给前台。这种方式可以防止观察者看到可能伴随着动画帧与动画帧之间的闪烁的渲染过程。缓冲区交换平台将以平台特定的方式进行。

第一步 :设置清屏颜色
第二步 :没有着色器,在OpenGL 核心框架中是无法进行任何渲染的。初始化一个渲染管理器。
第三步 :指定顶点。

3. 怎么用OpenGL画两个立方体

使用压栈和退栈,glPushMatrix压栈,可以存储当前矩阵,glPopMatrix可以弹出上次存储的矩阵,比如你画正方形的代码写成一个DrawCube()函数,每次调用都调用的是同一个画正方形的代码,所以如果你连续调用两次会把第二个正方形覆盖第一个,所以你只能看到一个正方形。如果你把代码改成如下:
glPushMatrix();
DrawCube();// 画第一个正方形
glTranslatef(10,0,0);// 移动坐标,用于绘制第二个正方形
DrawCube();
glPopMatrix();
这样就可以显示两个正方形了。

4. OpenGL 实现正方形绘制,键盘控制移动(三)

其实,在上一次绘制完一个三角形之后,正方形的绘制流程大致是一样,只是需要控制正方形的移动,我们需要多注册一个特殊函数,用于监听方向键的移动,并根据移动方向,平移正方形,首先看一下最后实现的效果,当然gif倍速了,将就看吧😓

首先,我们要实现的是一个可以移动的的正方形,而不在是一个静态的图形,那么图形的顶点数据就不是一个不变的值;那我们应该怎么设置顶点数据? 一开始,我们的正方形有一个初始位置,当每按压一次方向键(上/下/左/右),那么整个正方形上的所有点朝某一个方向移动一个步长(每一次移动的量stepSize),移动后的位置都是原来的坐标值加上一个步长,当然,方向不同,stepSize有正负之分,那么问题可以转化为 :顶点数据 = 初始顶点数据 + 移动量。这样我们就可以先将正方形个顶点的坐标先记录下来,再用两个变量分别记录图形在左右方向、上下方向的移动量记录下来,即可得到我们实时的正方形顶点位置,也就可以绘制移动的正方形;准备以上数据如下:

从以上初始化数据,我们可以得到如下图中的正方形,在窗口中的坐标系中的位置,如下图,图中的A、B、C、D的坐标,对应于正方形的顶点数据,图中的原点O的坐标为(0,0,0),我们将这个点选为我们移动的参照点,及通过它移动后的坐标刚好对应(xPos,yPos, 0);以通过它来做边界碰撞的判断;

接下来看主函数的工作:主函数中我们需要:1、初始化GLUT库;2、设置窗口模式、大小、标题;3.注册需要回调的函数;4、设置渲染环境;5、启动GLUT Roop;

在主函数中注册的三个函数:ChangeSize、RenderScene、SpecialKey会在GLUT Roop收到对应的消息时,触发回调,其流程如下

接下来看一下具体函数的实现,首先看主函数

设置渲染环境的setupRC,这里顶点的链接模式,我们改为了平面链接模式GL_TRIANGLE_FAN,并且顶点为4个

窗口的初始化或大小发生改变的回调函数,ChangeSize函数;

需要渲染时的函数RenderScene的实现

当我们按下方向键时,触发的的时SpecialKeys,当按一次左方向键,图形发生如下改变,很容易得到这个时候的移动量的值,xPos -=stepSize;同理可得到向右移动一次时,xPos += stepSize;我们也同样可以得到向上或向下移动的yPos的变化,向上移动一次 yPos += stepSize;向下移动时 yPos -= stepSize;

我们想要正方形只在窗口中移动,那么当正方向碰到边时,我们应该让其停下来,我们知道x轴方向和y轴方向的坐标范围都为[-1.0f,1.0f],下图中画出了正方形移动到各端边界时的直观图,当然不一定只在x轴方向、或y轴移动,图示只是为了理解边界碰撞的坐标判断,我们一直以中心点为移动量基准点,所以图中4个红点的位置,即是正方形在各方向的最大移动量的情况,我们想要正方形不超出最左端,那必须xPos>= -1.0 + blockSize,不超出最右端的条件时 xPos <= 1.0 - blockSize;同理,不超出最顶点yPos <= 1.0 - blockSize; 不超出最底端 yPos >= -1.0 + blockSize;

边界效果

SpecialKeys的具体实现:

5. 怎么用OpenGL绘制一个红色的正方形

int DrawGLScene(GLvoid) // 此过程中包括所有的绘制代码 { glColor3f(0.5f,0.5f,1.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(); // 正方形绘制结束 return TRUE; // 继续运行 } if (keys[VK_F1]) { keys[VK_F1]=FALSE; KillGLWindow(); fullscreen=!fullscreen; if (!CreateGLWindow("NeHe"s Color Tutorial",640,480,16,fullscreen)) { return 0; } }

6. android 中opengl画正方体,其顶底坐标还有索引是怎么计算和定义的

opengl es画图形都是通过三角形来画的,当然还可以画直线和点
画图形的时候有两种方法:glDrawArrays( ) 和glDrawElements( )

比如画一个由2个三角形组成的正方形,左上角坐标是l,t,右下角坐标是r,b
使用glDrawArrays绘制时,画2个三角形,需要这样传:
(l,t),(r,t),(l,b)
(r,t),(r,b),(l,b)
也就是说传的顶点数据就是按照顺时针或者逆时针排好顺序的,两个三角形的6个顶点

而用glDrawElements画的话可以这样
float coord[4][2]={{l,t},{r,t},{r,b},{l,b}};
绘制时用索引指定顶点顺序:
0,1,3
1,2,3

也就是说glDrawArrays传输或指定的数据是最终的真实数据,在绘制时效能更好
而glDrawElements指定的是真实数据的调用索引,在内存/显存占用上更节省

7. 如何使用OPENGL绘制立方体可以的话将代码写一下

#include <GL/glut.h>
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0);
glutWireCube(0.5);
glutSwapBuffers();
}
void reshape(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-4.0,4.0,-4.0,4.0,-4.0,4.0);
}
void init()
{
glClearColor(1.0,1.0,1.0,1.0);
glColor3f(0.0,0.0,0.0);
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("cube");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
init();
glutMainLoop();
}

8. 如何使用OPENGL绘制立方体

#include void display() { glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0); glutWireCube(0.5); glutSwapBuffers(); } void reshape(int w,int h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-4.0,4.0,-4.0,4.0,-4.0,4.0); } void init() { glClearColor(1.0,1.0,1.0,1.0); glColor3f(0.0,0.0,0.0); } int main(int argc,char** argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(0,0); glutCreateWindow("cube"); glutReshapeFunc(reshape); glutDisplayFunc(display); init(); glutMainLoop(); }

9. opengl怎么画正方形和园编程

有个专门画矩形的函数,可以实现正方形的绘制。

圆,可以用线来绘制,先确定圆上的点,然后用线把点连接起来,点越多,圆越圆。

10. opengl下怎么画立方体

#include <GL/glut.h>
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0);
glutWireCube(0.5);
glutSwapBuffers();
}
void reshape(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-4.0,4.0,-4.0,4.0,-4.0,4.0);
}
void init()
{
glClearColor(1.0,1.0,1.0,1.0);
glColor3f(0.0,0.0,0.0);
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("cube");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
init();
glutMainLoop();
}

阅读全文

与opengl画正方体编程相关的资料

热点内容
机器人穿越外国电影 浏览:681
赢在龙头主图指标源码 浏览:951
符号加在命令后面 浏览:271
沙漏验机宝检测安卓手机怎么样 浏览:369
非洲电影有哪些好看的 浏览:763
媒介学pdf 浏览:234
推荐一个在线观看 浏览:471
单片机16进制编程图 浏览:490
金刚2迅雷下载 浏览:275
聚优电影卡使用范围 浏览:760
浙江网络卫星授时服务器云空间 浏览:497
宝塔加密方式 浏览:217
linux环境变量的路径 浏览:749
粉笔缓存的视频在手机哪个文件夹 浏览:680
港片尺度大 浏览:373
女主胸大的H电影 浏览:877
小女孩那个电影叫什么 浏览:58
中越战争电影在哪看 浏览:896
成龙电影国语版全部 浏览:199