[图形学] Chp10 OpenGL三维观察程序示例
10.10节书中给出了一个程序示例,有一个填充正方形,从侧面的角度观察并画到屏幕上。
图0
这里进一步画出一个立方体,将相机放入立方体中心,旋转相机,达到在立方体中旋转看到不同画面的效果。
步骤:
1 使用的是4.9节中的OpenGL顶点数组方法。创建一个立方体100*100*100,坐标范围(0, 0, 0)到(100, 100, 100)。
2 立方体各面使用不同的颜色,调整顶点顺序以确保相机看到的都是填充面而不是线框图。
3 将投影观察点(即观察系原点)设置在矩形中心P0 = (50, 50, 50)。
4 视点Pref为相机朝向的点(注意,这个不是观察点),初始设置为Pref =(0, 50, 0)。
5 修改Pref的坐标,使其绕x=z=50进行逆时针旋转(与y轴平行的旋转公式(9.9)),最终实现相机在立方体中逆时针旋转,看到不同面的效果。
备注:
1 与y轴平行的旋转公式,先将旋转轴平移到与y轴重合,再进行旋转:z' = z * cosθ - x * sinθ, x' = z * sinθ + x * cosθ, y'=y;
2 近平面距离投影观察点不能为0,近平面和远平面的坐标会影响画面的效果,调整范围以确保画面不太离谱(并不真实)
3 之前直接在displayFcn中调用cube,修改使用display list后可以提高cpu的效率,从2%降到1%。
问题:
1 调整dnear和dfar时,会影响投影效果。dnear离P0越近,投影效果强度更大,离得远的点看着更小。见图2。不真实。
2 当调整近裁剪面大小且当立方体旋转时,投影画面会改变宽度,看起来会更奇怪。见图3。不真实。
3 在idleFcn中使用glutPostRedisplay替换直接调用displayFcn,效率有降低,不懂为什么。
#include <GLUT/GLUT.h>
#include <math.h> GLint winWidth = , winHeight = ;
GLfloat x0 = 50.0, y00 = 50.0, z0 = 50.0; // 这是观察参考点,与观察系原点重合
GLfloat xref = 0.0, yref = 50.0, zref = 0.0; // camera要瞄准的点,不是观察参考点
GLfloat Vx = 0.0, Vy = 1.0, Vz = 0.0;
GLfloat xwMin = -40.0, ywMin = -40.0, xwMax = 40.0, ywMax = 40.0;
GLfloat dnear = , dfar = ;
GLdouble radianAngle = 1.0/360.0 * 3.14159;
GLfloat cos1 = cos(radianAngle);
GLfloat sin1 = sin(radianAngle); typedef GLint vertex3 [];
vertex3 pt [] = {{, , }, {, , }, {, , }, {, , },
{, , }, {, , }, {, , }, {, , }}; void init (void)
{
glClearColor(1.0, 1.0, 1.0, 0.0); glMatrixMode(GL_MODELVIEW);
gluLookAt(x0, y00, z0, xref, yref, zref, Vx, Vy, Vz); glMatrixMode(GL_PROJECTION);
glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar); void cube();
cube();
} void quad (GLint n1, GLint n2, GLint n3, GLint n4)
{
glBegin(GL_QUADS);
glVertex3iv(pt[n1]);
glVertex3iv(pt[n2]);
glVertex3iv(pt[n3]);
glVertex3iv(pt[n4]);
glEnd();
} GLuint regHex; void cube ()
{
regHex = glGenLists();
glNewList(regHex, GL_COMPILE); glColor3f(0.0, 1.0, 0.0); // back
quad(, , , );
glColor3f(1.0, 0.0, 0.0); // left
quad(, , , );
glColor3f(0.0, 0.0, 1.0); // top
quad(, , , );
glColor3f(1.0, 1.0, 0.0); // front
quad(, , , );
glColor3f(0.0, 1.0, 1.0); // right
quad(, , , );
glColor3f(1.0, 0.0, 1.0); // bottom
quad(, , , ); glEndList();
} void displayFcn (void)
{
glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0, 1.0, 0.0);
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_LINE);
// glFrontFace(GL_CW); // show the back glCallList(regHex); glutSwapBuffers();
} void reshapeFcn (GLint newWidth, GLint newHeight)
{
glViewport(, , newWidth, newHeight); winWidth = newWidth;
winHeight = newHeight;
} void idleFcn (void)
{
GLfloat xref1, zref1;
xref = xref - x0;
zref = zref - z0;
zref1 = zref * cos1 - xref * sin1 + z0;
xref1 = zref * sin1 + xref * cos1 + x0;
xref = xref1;
zref = zref1; glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x0, y00, z0, xref, yref, zref, Vx, Vy, Vz); glutPostRedisplay();
} int main(int argc, char * argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(winWidth, winHeight);
glutInitWindowPosition(, );
glutCreateWindow("Perspective View of A Square"); init();
glutDisplayFunc(displayFcn);
glutReshapeFunc(reshapeFcn);
glutIdleFunc(idleFcn);
glutMainLoop(); return ;
}
图1
图2
图3
[图形学] Chp10 OpenGL三维观察程序示例的更多相关文章
- 开源免费跨平台opengl opencv webgl gtk blender, opengl贴图程序
三维图形的这是opengl的强项,大型3D游戏都会把它作为首选.图像处理,是opencv的锁定的目标,大多都是C的api,也有少部分是C++的,工业图像表现,图像识别,都会考虑opencv的.webg ...
- 学习基于OpenGL的CAD程序的开发计划(一)
本人目前从事的工作面对的客户中很多来自高端制造业,他们对CAD/CAE/CAM软件的应用比较多.公司现有的软件产品主要是用于渲染展示及交互,但面对诸如CAD方面的应用(比如基于约束的装配.制造工艺的流 ...
- 《Unix 网络编程》05:TCP C/S 程序示例
TCP客户/服务器程序示例 系列文章导航:<Unix 网络编程>笔记 目标 ECHO-Application 结构如下: graph LR; A[标准输入/输出] --fgets--> ...
- 转载--Linux命令top动态观察程序的变化
转载:http://www.cnblogs.com/allen8807/archive/2010/11/10/1874001.html top:动态观察程序的变化 [root@linux ~]# to ...
- Arduino 入门程序示例之一个 LED(2015-06-11)
前言 答应了群主写一些示例程序,一直拖延拖延拖延唉.主要还是害怕在各大高手面前班门弄斧……(这也算是给拖延症找一个美好的理由吧),这几天终于下决心要写出来了,各位高手拍砖敬请轻拍啊. 示例程序 首先是 ...
- WinDBG调试.NET程序示例
WinDBG调试.NET程序示例 好不容易把环境打好了,一定要试试牛刀.我创建了一个极其简单的程序(如下).让我们期待会有好的结果吧,阿门! using System; using System.Co ...
- 现代控制理论习题解答与Matlab程序示例
现代控制理论习题解答与Matlab程序示例 现代控制理论 第三版 课后习题参考解答: http://download.csdn.net/detail/zhangrelay/9544934 下面给出部分 ...
- 第一个Mybatis程序示例 Mybatis简介(一)
在JDBC小结中(可以参阅本人JDBC系列文章),介绍到了ORM,其中Mybatis就是一个不错的ORM框架 MyBatis由iBatis演化而来 iBATIS一词来源于“internet”和“aba ...
- map reduce程序示例
map reduce程序示例 package test2; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop. ...
随机推荐
- malloc与new相关
前言: 通常我们使用数组的时候:必须提前用一个常量来指定数组的长度,同时它的内存空间在编译的时候就已经被分配了.但是有时候数组的长度只有在运行的时候才能知道.因此,一种简单的解决方案就是提前申请一块较 ...
- 写给Android App开发人员看的Android底层知识(7)
(十二)ContentProvider (1)ContentProvider是什么? ContentProvider,简称CP. 做App开发的同学,尤其是电商类App,对CP并不熟悉,对这个概念的最 ...
- 一天搞定HTML----标签语义化04
根据页面里不同的内容,选择最适合它的标签,而不通篇只用一种标签 标签语义化作用: 代码演示 通过比较- - -H5布局和DIV+CSS 布局- - -体现标签语义化 注意: 标签语义化,不仅仅只是指使 ...
- JavaScript设计模式_02_策略模式
在程序设计中,我们常常遇到这种情况,要实现某一个功能我们有很多种算法可以实现.这些算法灵活多样,而且可以随意互相替换.这种解决方案就是所谓的策略模式. /* * pre:策略模式 * 示例:公司计算奖 ...
- Android搞事篇——使用Intent跳转界面
跳转页面基本分为三个步骤: 1.初始化一个intent:(一个intent就够用了): 2.传入intent参数: 3.调用startactivity();实现跳转页面 具体操作如下 首先你需要一个项 ...
- java 1.8 动态代理源码分析
JDK8动态代理源码分析 动态代理的基本使用就不详细介绍了: 例子: class proxyed implements pro{ @Override public void text() { Syst ...
- [Leetcode] Binary search -- 475. Heaters
Winter is coming! Your first job during the contest is to design a standard heater with fixed warm r ...
- 解决Linux下面Firefox无法播放mp3的问题
之前一直使用kali linux ,上班屏蔽噪音都用网易音乐.既然没有Linux客户端,那就网页版吧.不得不说,网易音乐的网页版做的真心赞. 在Kali Linux下面使用Firefox听歌一直都很正 ...
- android6.0搜索蓝牙无法显示问题解决
1.android6.0版本搜索蓝牙需要开启位置信息 需在Manifest中添加权限: <uses-permission android:name="android.permissio ...
- 基于Jmeter的轻量级接口压力测试(一)
一.操作步骤: 1.在测试计划下新增一个线程组,并在线程组下新增一个http请求: 2.读取配置文件中的参数:在添加的http请求下添加配置元件-CSV DATA SET CONFIG 3.配置待测试 ...