编写一个程序,该程序运行时可以用鼠标的一个按键调整立方体的方向,用另一个按键平移立方体,用第三个按键缩放立方体。

这是题目,我的程序不一定完全按照这个来。初学OpenGL,对那一堆坐标系表示十分混乱,慢慢看吧,有点头绪了。

(一)

 #include <gl/glut.h>
#include <math.h>
#define GL_PI 3.1415f GLfloat xRot = -35.0f;
GLfloat yRot = 15.0f;
GLfloat xMov = 0.0f;
GLfloat winW = 0.0f;
GLfloat winH = 0.0f;
GLfloat zoom = 1.0f; void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT); glPushMatrix();
glLoadIdentity();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f); // 底面
glBegin(GL_LINE_LOOP);
glVertex3f(0.0f+xMov, 0.0f, 0.0f);
glVertex3f(1.0f+xMov, 0.0f, 0.0f);
glVertex3f(1.0f+xMov, 0.0f, 1.0f);
glVertex3f(0.0f+xMov, 0.0f, 1.0f);
glEnd(); // 顶面
glBegin(GL_LINE_LOOP);
glVertex3f(0.0f+xMov, 1.0f, 1.0f);
glVertex3f(0.0f+xMov, 1.0f, 0.0f);
glVertex3f(1.0f+xMov, 1.0f, 0.0f);
glVertex3f(1.0f+xMov, 1.0f, 1.0f);
glEnd(); // 背面
glBegin(GL_LINE_LOOP);
glVertex3f(0.0f+xMov, 0.0f, 0.0f);
glVertex3f(1.0f+xMov, 0.0f, 0.0f);
glVertex3f(1.0f+xMov, 1.0f, 0.0f);
glVertex3f(0.0f+xMov, 1.0f, 0.0f);
glEnd(); // 前面
glBegin(GL_LINE_LOOP);
glVertex3f(1.0f+xMov, 0.0f, 1.0f);
glVertex3f(0.0f+xMov, 0.0f, 1.0f);
glVertex3f(0.0f+xMov, 1.0f, 1.0f);
glVertex3f(1.0f+xMov, 1.0f, 1.0f);
glEnd(); // 右面
glBegin(GL_LINE_LOOP);
glVertex3f(1.0f+xMov, 0.0f, 0.0f);
glVertex3f(1.0f+xMov, 0.0f, 1.0f);
glVertex3f(1.0f+xMov, 1.0f, 1.0f);
glVertex3f(1.0f+xMov, 1.0f, 0.0f);
glEnd(); // 左面
glBegin(GL_LINE_LOOP);
glVertex3f(0.0f+xMov, 0.0f, 0.0f);
glVertex3f(0.0f+xMov, 0.0f, 1.0f);
glVertex3f(0.0f+xMov, 1.0f, 1.0f);
glVertex3f(0.0f+xMov, 1.0f, 0.0f);
glEnd(); glPopMatrix();
glFlush();
}
void OnReshape(int w, int h)
{
GLfloat aspectRatio = (GLfloat)w/(GLfloat)h;
winW = w;
winH = h; glViewport(,,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
{
glOrtho(-3.0f*zoom, 3.0f*zoom, -3.0f*zoom/aspectRatio, 3.0f*zoom/aspectRatio, -10.0f*zoom, 10.0f*zoom);
}
else{
glOrtho(-3.0f*zoom*aspectRatio, 3.0f*zoom*aspectRatio, -3.0f*zoom, 3.0f*zoom, -10.0f*zoom, 10.0f*zoom);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void OnMouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
xRot += ;
yRot += ;
glutPostRedisplay();
}
else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
xMov -= 0.1;
glutPostRedisplay();
}
else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
{
zoom += 0.1;
OnReshape(winW,winH);
glutPostRedisplay();
}
}
void OnKeyUpDown(int key, int x, int y)
{
if (key == GLUT_KEY_UP){
zoom -= 0.1;
}
else if (key == GLUT_KEY_DOWN){
zoom += 0.1;
}
OnReshape(winW,winH);
glutPostRedisplay();
} void SetupRC()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
} void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("Cube");
glutDisplayFunc(RenderScene);
glutReshapeFunc(OnReshape);
glutMouseFunc(OnMouse);
glutSpecialFunc(OnKeyUpDown); SetupRC(); glutMainLoop();
}

这个程序略长,显得有点笨。手工实现了平移和放大缩小的功能,值得记录一下。

(二)

 #include <windows.h>
#include<gl/glut.h>
#include <math.h>
#include<stdio.h> GLfloat angle=0.0f;
GLfloat translate_x=0.0f;
GLfloat zoom=1.0f; void myDisplay()
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0f, 1.0f, 1.0f);
glPushMatrix();
{
glMatrixMode(GL_MODELVIEW); //切换到模型视图矩阵
glLoadIdentity();
glRotatef(angle,1.0f,0.0f,0.0f);
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glTranslatef(translate_x,0.0f,0.0f);
glScalef (zoom, zoom, zoom);
glutWireCube(1.5); //画立方体
}
glPopMatrix();
glFlush();
} void reshape(int w,int h)
{
glViewport (, , (GLsizei) w, (GLsizei) h); //调整视口位置和大小
glMatrixMode (GL_PROJECTION);//切换到投影矩阵
glLoadIdentity();//加载单位阵至投影矩阵
if (w <= h){
glOrtho(-3.0f, 3.0f, -3.0f/(w/h), 3.0f/(w/h), -3.0f, 3.0f);
}
else{
glOrtho(-3.0f*w/h, 3.0f*w/h, -3.0f, 3.0f, -3.0f, 3.0f);
} glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
} void OnMouse(int button, int state, int x, int y)
{
//鼠标左键
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
angle += 10.0f;
glutPostRedisplay();
}
//鼠标右键
else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
translate_x+=0.1f;
glutPostRedisplay();
}
//鼠标滚轮
else if (state == GLUT_UP && button == GLUT_WHEEL_DOWN)
{
if(zoom>)
zoom-=0.1f;
glutPostRedisplay();
}
else if(state == GLUT_UP && button == GLUT_WHEEL_UP)
{
zoom+=0.1f;
glutPostRedisplay();
}
} int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(,);
glutInitWindowSize(,);
glutCreateWindow("cube"); glutDisplayFunc(myDisplay);
glutReshapeFunc(reshape);
glutMouseFunc( OnMouse );
glutMainLoop();
return ;
}

采用了OpenGL的一些库函数实现,投影还是采用平行投影,表示对透视投影函数gluPerspective以及视点变化函数gluLookAt不是很清楚。

(三)

 #include <windows.h>
#include<gl/glut.h>
#include <math.h>
#include<stdio.h> GLfloat angle=0.0f;
GLfloat translate_x=0.0f;
GLfloat zoom=1.0f; void myDisplay()
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0f, 1.0f, 1.0f);
glPushMatrix(); glMatrixMode(GL_MODELVIEW); //切换到模型视图矩阵
glLoadIdentity();
gluLookAt (0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); //设置相机参数
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glTranslatef(translate_x,0.0f,0.0f);
glScalef (zoom, zoom, zoom);
glutWireCube(0.5); //画立方体 glPopMatrix();
glFlush();
} void reshape(int w,int h)
{
glViewport (, , (GLsizei) w, (GLsizei) h); //调整视口位置和大小
glMatrixMode (GL_PROJECTION);//切换到投影矩阵
glLoadIdentity();//加载单位阵至投影矩阵
gluPerspective(,w/h,,);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
} void OnMouse(int button, int state, int x, int y)
{
//鼠标左键
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
angle += 10.0f;
glutPostRedisplay();
}
//鼠标右键
else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
//xMov -= 0.1;
translate_x+=0.1f;
glutPostRedisplay();
}
//鼠标滚轮
else if (state == GLUT_UP && button == GLUT_WHEEL_DOWN)
{
if(zoom>)
zoom-=0.1f;
glutPostRedisplay();
}
else if(state == GLUT_UP && button == GLUT_WHEEL_UP)
{
zoom+=0.1f;
glutPostRedisplay();
}
} int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(,);
glutInitWindowSize(,);
glutCreateWindow("cube"); glutDisplayFunc(myDisplay);
glutReshapeFunc(reshape);
glutMouseFunc( OnMouse );
glutMainLoop();
return ;
}

用的是透视投影。我的理解是gluPerspective()和gluLookAt()要配合使用,二者中的相机位置要一致。

【OpenGL】画立方体的更多相关文章

  1. OpenGL 画出雷达动态扫描效果(二) 非底图

    OpenGL 画出雷达动态扫描效果(一)中给出了已一张图片作为底图的雷达扫面程序 如果有漂亮的雷达底图的话,效果应该非常不错的,另外也可以直接手绘雷达框架 效果如下 雷达主体代码 glLineWidt ...

  2. 46.Qt 使用OpenGL绘制立方体

    main.cpp #include <QApplication> #include <iostream> #include "vowelcube.h" in ...

  3. opengl画不出直线 线段 坐标轴 却能画出其他图形的坑

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/12054507.html 好多次都是画坐标轴的三条直线画不出来,虽然最后都解决了  但是还是耽误 ...

  4. opengl画圆

    通过这个例子可以更加深刻的了解割圆术的原理,明白如何的化曲为直,且看代码: #include <windows.h> //#include <GLUT/glut.h> #inc ...

  5. 用OpenGL进行立方体表面纹理贴图

    一.目的 掌握OpenGL中纹理对象的创建.绑定与使用方法. 二.简单介绍 1,连接静态库 #pragma comment(lib, "glut32.lib") #pragma c ...

  6. OpenGL 画出雷达动态扫描效果(一)

    最终效果如下所示 Demo下载  http://files.cnblogs.com/xd-jinjian/Debug.zip 源代码下载 http://download.csdn.net/detail ...

  7. 【转】【OPenGL】OPenGL 画图板-- 中点算法画圆

    为了能以任意点为圆心画圆,我们可以把圆心先设为视点(相当于于将其平移到坐标原点),然后通过中点法扫描转换后,再恢复原来的视点(相当于将圆心平移回原来的位置). 圆心位于原点的圆有四条对称轴x=0,y= ...

  8. 用OpenGL画线

    . 两点之间的连线称之为线段,在屏幕上显示线段放在现在已经不是稀奇的事情,大多数高级图形API都可以轻松实现,我尝试用OpenGL画线,在这里记录一下收获. . OpenGL这个级别的图形API,通常 ...

  9. OpenGL 画高斯随机函数

    高斯函数代码 const float CFFTOceanShader::_getGaussianRandomFloat() const { float u1 = rand() / (float)RAN ...

随机推荐

  1. 【leetcode】Dungeon Game (middle)

    The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...

  2. CentOS 报no acceptable C compiler found in $PATH的解决办法

    CentOS 6.2下安装tcpreplay工具的时候,先安装libpcap-1.3.0,configure libpcap时出错. #./configure 提示没有GCC编译器环境) config ...

  3. DJANGO中filter_horizontal和raw_id_fields的作用

    在作多项选择的操作方便性,及单项选择太多时,会有好一点的体验... class UserAuthorAdmin(admin.ModelAdmin): # raw_id_fields = ('group ...

  4. linux更改shell

    1.查看机器安装了哪些shell? 有两种方法可以查看. 第一种: 使用env命令查看环境变量里面的shell信息第二种: $ cat /etc/shells 2.查看当前正在使用的shell是哪个? ...

  5. C++ 通过对象方式 、指针方式两种方式去访问成员变量(属性或者方法)

    准备 1.在VS中新建一个项目-Viscal C++ ---常规--空项目 2.建立一个.h的头文件 定义一个类 声明其成员(C#中的属性和方法) #include<iostream> # ...

  6. Flex Array内置排序方法的使用

    在Array类中,提供内置的排序方法.排序是在软件开发的过程中,经常遇到的问题.通过这些内置的方法,可以快速轻便的进行排序操作. Array类提供sort方法对Array实例进行排序.sort方法没有 ...

  7. Unicode汉字编码表

    U+  0   1  2  3  4   5  6   7   8   9   A  B  C  D  E  F  ------------------------------------------ ...

  8. 【HDOJ】2459 Maximum repetition substring

    后缀数组+RMQ. /* 2459 */ #include <iostream> #include <sstream> #include <string> #inc ...

  9. poj2886Who Gets the Most Candies? (约瑟夫环)

    http://poj.org/problem?id=2886 单点更新 初始位置都是1 如果这个人出去 位置变为0 利用线段树求区间k值 k值的计算如下 如果这个数值是负的 那么下一个人的就是((k- ...

  10. 最小生成树(kruskal模版 模板)

    题目:http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2144&cid=1186 #include<stdio.h> #incl ...