您的位置:首页 > 编程语言

OpenGL学习(三)三维编程基础

2014-08-29 16:30 281 查看
正交投影

viod glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far)
//设定一个正交投影矩阵,并定义了一个形状为直平行六面体的视域体。

void glutWireCube(GLdouble size) //生成一个线框立方体,中心位于原点,边长为size
void glutSolidCube(GLdouble size) //生成一个实立方体

一个简单的画三维立方体的例子:
#include <gl/glut.h>
#include <math.h>
#include <vector>
#include <iostream>

using namespace std;

void init()
{
glClearColor(0.0,0.0,0.0,0.0);      //指定屏幕背景为黑色

glColor3f(1.0,1.0,1.0);             //设置绘制颜色为白色

glShadeModel(GL_FLAT);              //设置颜色插值为平面模式

}

void display()
{
glClear(GL_COLOR_BUFFER_BIT);         //清理屏幕颜色为我们指定的颜色

glutSolidCube(0.5);

glFlush();                       //强制以上绘图操作执行
}

void reshape(int w,int h)
{
glMatrixMode(GL_PROJECTION);       //设置为投影模式
glLoadIdentity();
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);

glViewport(0,0,(GLsizei)w,(GLsizei)h);
}

int main(int argc,char**argv)
{
glutInit(&argc,argv);                           //初始化glut
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);    //设置窗口模式为单缓冲和RGB模式
glutInitWindowSize(500,500);                    //设置窗口大小
init();
glutCreateWindow("test");                       //设置窗口标题
glutDisplayFunc(display);                       //设置绘图回调函数
glutReshapeFunc(reshape);                       //设置窗口回调函数
glutMainLoop();                                 //开始循环,等待响应
return 0;
}
运行得到:



摄影机的定位

上面的例子存在一个问题,即摄像机只朝向该立方体的一个面,所以我们也只能看到该立方体的一个面。如果想看到其他面,必须移动摄像机或者被观察对象。而在OpenGL中,这两个操作时等价的。由视图矩阵来实现。
为了获得所期望的视图,我们可以在对象坐标系中设置摄像机的位置和朝向。我们可以决定摄像机的位置并通过该摄像机所指向的点来指定。其次还需指定一个向上向量。为方便起见,通常将向量取为(0,1,0)或者坐标系中的y轴方向

void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,
GLdouble atx,GLdouble aty,GLdouble atz,
GLdouble upx,GLdouble upy,GLdouble upz)

//确定了一个可用于为摄像机定位和定向的矩阵,涉及的参数包括摄像机的位置(视点eye),被观察点(点at)以及所期望的up方向。

再更改上述代码可以得到
#include <gl/glut.h>
#include <math.h>
#include <vector>
#include <iostream>

using namespace std;

void init()
{
glClearColor(0.0,0.0,0.0,0.0);      //指定屏幕背景为黑色

glColor3f(1.0,1.0,1.0);             //设置绘制颜色为白色

glShadeModel(GL_FLAT);              //设置颜色插值为平面模式

}

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);

glFlush();                       //强制以上绘图操作执行
}

void reshape(int w,int h)
{
glMatrixMode(GL_PROJECTION);       //设置为投影模式
glLoadIdentity();
glOrtho(-2.0,2.0,-2.0,2.0,-2.0,2.0);

glViewport(0,0,(GLsizei)w,(GLsizei)h);
}

int main(int argc,char**argv)
{
glutInit(&argc,argv);                           //初始化glut
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);    //设置窗口模式为单缓冲和RGB模式
glutInitWindowSize(500,500);                    //设置窗口大小
init();
glutCreateWindow("test");                       //设置窗口标题
glutDisplayFunc(display);                       //设置绘图回调函数
glutReshapeFunc(reshape);                       //设置窗口回调函数
glutMainLoop();                                 //开始循环,等待响应
return 0;
}
运行得到:



因为把摄像机的位置放在了(1,1,1)那点,所以得到这样的图像。

顶点数组
void glEnableClientState(GLenum array)
void glDisableClientState(GLenum array)

//启用或禁用数组类型GL_VERTEX_ARRAY、GL_COLOR_ARRAY、GL_INDEX_ARRAY、GL_NORMAL_ARRAY、 GL_TEXTURE_COORD_ARRAY、GL_EDGE_FLAG_ARRAY.

void glVertexPointer(GLint dim,GLenum type,GLsizei stride,GLvoid* array)

void glColorPointer(GLint dim,GLenum type,GLsizei stride,GLvoid* array)

//提供数组中的信息。数据存储在数组array中,dim为数组的维数(2,3,4),type表明数据的存储类 型(GL_SHORT、GL_INT、GL_FLOAT、GL_DOUBLE),stride是相邻两个数据之间的字节数(0意味着时 紧密排列的)

void glDrawElements(GLenum mode,GLsizei n,GLenum type,void* indices)

//使用数组indices中的n个索引来绘制类型为mode的元素,该数组可以为一下类型 (GL_UNSIGEND_BYTE、GL_UNSIGEND_SHORT、GL_UNSIGEND_INT)

消隐

绘制三维图形时,如不使用消隐,即使后面物体被前面物体挡住,OpenGL也会绘制被挡住的物体。
因此OpenGL利用深度缓存算法开启消隐功能.

首先在创建窗口的时候得请求一个深度缓存

glutInitDiaplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
然后开启消隐功能

glEnable(GL_DEPTH_TEST);

清空颜色缓存时,通常将深度缓存清空:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

下面看一个绘制立方体的例子:
#include <gl/glut.h>

GLfloat vertices[]={
-1.0,-1.0,1.0,
-1.0,1.0,1.0,
1.0,1.0,1.0,
1.0,-1.0,1.0,
-1.0,-1.0,-1.0,
-1.0,1.0,-1.0,
1.0,1.0,-1.0,
1.0,-1.0,-1.0
};                              //定义立方体的8个顶点

GLint index[]={
0,3,2,1,
2,3,7,6,
3,0,4,7,
1,2,6,5,
4,5,6,7,
5,4,0,1
};                              //定义每个面所需要那几个顶点

GLfloat colors[]={
1.0,0.0,0.0,
0.0,1.0,1.0,
1.0,1.0,0.0,
0.0,1.0,0.0,
0.0,0.0,1.0,
1.0,0.0,1.0,
1.0,1.0,0.0,
0.0,1.0,1.0
};                             //定义六个面的颜色

void init()
{
glClearColor(0.0,0.0,0.0,0.0);      //指定屏幕背景为黑色
glColor3f(1.0,1.0,1.0);             //设置绘制颜色为白色
glShadeModel(GL_FLAT);              //设置颜色插值为平面模式
}

void display()
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);         //清理屏幕颜色为我们指定的颜色
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.5,0.5,0.5,0.0,0.0,0.0,0.0,1.0,0.0);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glVertexPointer(3,GL_FLOAT,0,vertices);
glColorPointer(3,GL_FLOAT,0,colors);

glDrawElements(GL_QUADS,24,GL_UNSIGNED_INT,index);

glFlush();                       //强制以上绘图操作执行
}

void reshape(int w,int h)
{
glMatrixMode(GL_PROJECTION);       //设置为投影模式
glLoadIdentity();
glOrtho(-2.0,2.0,-2.0,2.0,-2.0,2.0);

glViewport(0,0,(GLsizei)w,(GLsizei)h);
}

int main(int argc,char**argv)
{
glutInit(&argc,argv);                           //初始化glut
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);    //设置窗口模式为单缓冲和RGB模式
glutInitWindowSize(500,500);                    //设置窗口大小
init();
glutCreateWindow("test");                       //设置窗口标题
glutDisplayFunc(display);                       //设置绘图回调函数
glutReshapeFunc(reshape);                       //设置窗口回调函数
glutMainLoop();                                 //开始循环,等待响应
return 0;
}
运行得到如下结果:


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息