OPENGL初学
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OPENGL初学相关的知识,希望对你有一定的参考价值。
一。部分常用的实体绘制函数部分常用的实体绘制函数:
//以下所有函数中,radius表示球体的半径,slices表示球体纵向分割的数目(经线),主要是设置绘制的细密度,stacks表示球体横向分割的数目(纬线),创建了绘制中心在模型坐标原点,半径为radius的球体
void glutWireSphere(GLdouble radius, GLint slices, GLint stacks); //网状球
void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); //实心球
void glutWireCube(GLdouble size); //网状立方体
void glutSolidCube(GLdouble size); //实心立方体
void glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint nsides, GLint rings); //网状圆环
void glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint nsides, GLint rings); //实心圆环
void glutWireCone(GLdouble radius, GLdouble height, GLint slices, GLint stacks); //网状圆锥体
void glutSolidCone(GLdouble radius, GLdouble height, GLint slices, GLint stacks); //实心圆锥体
void glutWireTeapot(GLdouble size); //网状茶壶
void glutSolidTeapot(GLdouble size); //实心茶壶
使用代码实例:
void display(void)
{
glColor3f(0.0f, 1.0f, 0.0f);//绿色
glutSolidSphere(0.5,10,10);//半径r=0.5,细密程度横纵10份,会发现,细密程度越高越精准,这是微积分的体现。但是高精度对性能的要求高,过高则渲染效率会降低,俗话会卡
glFlush();
}
二。视点变换(右为x,上为y,前为z)
OpenGL实用库提供了gluLookAt()函数,该函数有三个变量,分别定义了视点的位置、相机瞄准方向的参考点以及相机的向上方向。
void gluLookAt(
GLdouble eyex,GLdouble eyey,GLdouble eyez,//(eyex,eyey,eyez)视点的位置;
GLdouble centerx,GLdouble centery,GLdouble centerz,//(centerx,centery,centerz)注视的点,和视点之间连线形成注视方向;
GLdouble upx,GLdouble upy,GLdouble upz //(upx,upy,upz)向上的方向,即头顶的方向
);
视点比做人的眼睛,当眼睛看物体时,头朝天时(站立时)看到的物体和头朝地时(倒立时)看到的物体是不一样的.你还可以将头部左右倾斜从不同的角度来看物体.那么,gluLookAt的朝上向量就是用来确定这个方向的.不过在默认情况下,头是朝天的,即朝上向量为(0, 1, 0)。
向上的方向(即头顶方向)一旦确定后,视线的范围就确定了,和人站住不动后,所能看到的角度是有限的一样。还是用代码实例测试来看效果,我们以茶壶为三维实体。屏幕朝外的方向是Z轴正向。
1>默认状态下,头顶方向:(0,1,0)
void display(void)
{
glColor3f(0.0f, 1.0f, 0.0f);//画笔颜色
{
glMatrixMode(GL_MODELVIEW); //gluLookAt函数的作用范围就是模型视图下,这里设置是必要的
glLoadIdentity();//初始化当前矩阵为单位矩阵,不设置默认单位矩阵
gluLookAt(0,0,1, 0,0,0, 0,1,0);//头顶方向:Y轴正向,视点位置是Z轴正向1个单位(屏幕外),沿着Z轴看向原点
glutWireTeapot(0.5);//绘制茶壶
}
glFlush();
}
2>超出视野范围时,看不到物体了
/* 视点在Y轴正向1单位处,而头顶的方向是Y轴正向,这时,视线看不到脚下的原点,除非低头,而低头的话就改变了头顶的方向,所以如下的设置是看不到物体的! */
gluLookAt(0,1,0, 0,0,0, 0,1,0);
1.gluLookAt(0.0,0.0,5.0, 0.0,0.0,0.0, 0.0,1.0,0.0); 相当于我们的脑袋位置在(0.0,0.0,5.0)处,眼睛望向(0.0,0.0,0.0),即原点。后面的三个参数(0.0,1.0,0.0),y轴为1,其余为0,表示脑袋朝上,就是正常的情况。看到的情况如下图:
2.若将gluLookAt的后三个参数设置为(0.0,-1.0,0.0),即y轴为-1,其余为0。这样表示脑袋向下,即人眼倒着看,看到的效果如下图:
3.再次修改gluLookAt的后三个参数为(1.0,0.0,0.0);x轴为1,其余为0.即人的脑袋像右歪90度来看,即顺时针转90度(换个角度思考就是壶逆时针转90度),猜想看到的结果应该是壶嘴在上,壶盖在右,壶底在左,壶柄在下。如下图:
4.其余情况依次类推。再次重述gluLookAt的参数,前三个参数表示的是脑袋的位置,中间三个参数是人眼的朝向,后三个位置表示的是脑袋朝向的方向。
三。模型变换
1.模型平移
void myDisplay(void)
{
glColor3f(0.0f, 1.0f, 0.0f);
{
glMatrixMode(GL_MODELVIEW);
//这是没有平移的时候默认设置,(x,y,z)平移量为0
glTranslatef(0,0,0);
//画一个茶壶:一定要先做变换在绘制,先变换是改变了矩阵栈中的当前矩阵,然后用当前矩阵对要绘制的图形做变换
glutWireTeapot(0.5);//画一个茶壶
}
glFlush();
}
需要注意的是,默认情况下,我们的视点位置在(0,0,1)处(float参数下),所以如果平移的超出视点所能看到的位置,则看不到物体。如glTranslatef(0,0,2):到了视点的后脑勺处,自然看不到物体。
glTranslatef(0.5,0.5,0);//向右上方偏移
2.模型旋转
void myDisplay(void)
{
glColor3f(0.0f, 1.0f, 0.0f);
{
glMatrixMode(GL_MODELVIEW);
glRotatef(45, 0,0,1);//后三个参数确定了一个方向点,和原点连线构成旋转的轴线,这里是Z轴,即绕Z轴旋转45度
glutWireTeapot(0.5);
}
glFlush();
}
3.模型缩放
void myDisplay(void)
{
glColor3f(0.0f, 1.0f, 0.0f);
{
glMatrixMode(GL_MODELVIEW);
glScalef(1,3,0.5);//分别表示x,y,z轴的缩放比例
glutWireTeapot(0.5);
}
glFlush();
}
四。正射投影 glOrtho
void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);
//left和right:矩形视景体的左右平面,之间的距离为“宽”
//bottom和top:矩形视景体的上下平面,之间的距离为“高”
//near和far:矩形视景体的前后平面,之间的距离为“深度
void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top);//同glOrtho一样,只不过物体的Z轴坐标为0,缺省的近远平面距离为-1和1
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0,1,0);
//glMatrixMode(GL_PROJECTION);下面的函数自动做了矩阵变换,这里可以不写
glOrtho(-1,1,-1,1,-1,15);//视点在原点,而物体位移到-10处,为了能够看到物体,视景体就必须包含住物体,所以设置15
//glMatrixMode(GL_MODELVIEW);下面的函数自动做了矩阵变换,这里可以不写
glTranslatef(0,0,-10);
glutWireTeapot(1);
glFlush();
}
五。透视投影 glFrustum
void glFrustum(GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top, GLdouble near,GLdouble far);
eft, right:裁剪窗口左右边界的平面距离,距离(视点与物体连线:中心线)的两侧距离。左右边界决定了视口的宽。
bottom, top:裁剪窗口下上边界的平面距离,距离(视点与物体连线:中心线)的上下距离。上下边界决定了视口的高。
znear, zfar:视点到近、远平面的距离,必须是正的。
void myDisplay(void)
{
glColor3f(0.0f, 1.0f, 0.0f);
{
//透视投影,通过参数GL_PROJECTION,将矩阵转为投影矩阵,然后设置系数,调节投影
glMatrixMode(GL_PROJECTION);
glFrustum(-1,1, -1,1, 0,2);//前四个变量控制棱台的宽高,宽:2,高:2 ,后两个调节远近。
//模型变换,由于默认视点和模型都在原点,所以如果不设置模型移动,则视点在模型内部中心处,投影不能看到模型的整体
glMatrixMode(GL_MODELVIEW);//可以不写,转换函数内部已转换矩阵模式
glTranslatef(0,0,-1);
glutWireSphere(0.5,20,20);
}
glFlush();
}
六。透视投影。gluPerspective
void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear, GLdouble zFar);
//fovy: 指定视景体的视野的角度,以度数为单位,x、z平面张开的角度,比喻人眼的余光的范围。角度变小好比“眯眼”时,视野收缩到正前方,此时看到的物体会变小,距离会拉远。
//aspect:指定你的视景体的宽高比,影响投影图像的宽高比例
//zNear: 指定观察者到视景体的最近的裁剪面的距离(必须为正数)
//zFar: 指定观察者到视景体的最远的裁剪面的距离(必须为正数)
void myDisplay(void)
{
glColor3f(0.0f, 1.0f, 0.0f);
{
//透视投影,通过参数GL_PROJECTION,将矩阵转为投影矩阵,然后设置系数,调节投影
glMatrixMode(GL_PROJECTION);
gluPerspective(150,1,0,100);
//模型变换,由于默认视点和模型都在原点,所以如果不设置模型移动,则视点在模型内部中心处,投影不能看到模型的整体
glMatrixMode(GL_MODELVIEW);
glTranslatef(0,0,-1);
glutWireSphere(0.5,20,20);
}
glFlush();
}
第一个小程序:茶壶
// openglTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <gl/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
void display(void)
{
//清除掉所有像素
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f, 1.0f, 0.0f);
{
glMatrixMode(GL_MODELVIEW);
//这是没有平移的时候默认设置,(x,y,z)平移量为0
glTranslatef(0, 0, 0);
glRotated(45, 0, 0, 1);
//画一个茶壶:一定要先做变换在绘制,先变换是改变了矩阵栈中的当前矩阵,然后用当前矩阵对要绘制的图形做变换
glutWireTeapot(0.5);//画一个茶壶
}
glFlush();
}
void displayMotion(int x, int y)
{
//这里的x,y都是相对于绘制的窗口而言的,窗口的左上角为(0,0),右下角为(250,250)
cout << x << "" << y << endl;
}
void displayMouse(int button, int state, int x, int y)
{
/*
* 这里的x,y都是相对于绘制的窗口而言的,窗口的左上角为(0,0),右下角为(250,250)
* button==0 左键 button==2 右键 state==0 按下 state==1 抬起
*/
cout << "button=" << button << " state=" << state << " x=" << x << " y=" << y << endl;
}
void displayKeyboard(unsigned char key, int x, int y)
{
/*
* 这里的x,y都是相对于绘制的窗口而言的,窗口的左上角为(0,0),右下角为(250,250),是鼠标所在的位置
* key 是按下去的键
*/
cout << "key=" << key << " x=" << x << " y=" << y << endl;
}
void init(void)
{
//设置清除背景的颜色
glClearColor(0.0, 0.0, 0.0, 0.0);
//初始化
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);//设置坐标系 左、右、下、上、近、远
glOrtho(0.5, 0.5, 0.5, 0.5, -1.0, 1.0);
//这个程序画出来的图形,比例会随着窗口大小的变化而自动调整
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//初始化显示模式:单缓冲区,RGB模式
glutInitWindowSize(250, 250);
glutInitWindowPosition(100, 100);
glutCreateWindow("Hello,OpenGL");
init();
/*
* 显示回调函数,当GLUT确定一个窗口的内容重新显示时,通过这个函数注册的回调函数就会执行
* 所以应该把重绘场景所需要的所有代码都放在这个显示回调函数里
*/
glutDisplayFunc(display);
/*
* 当按下鼠标并移动鼠标时调用注册函数 glutMotionFunc(void(*func)(int x, int y))
*/
glutMotionFunc(displayMotion);
/*
* 当按下鼠标时调用注册函数
*/
glutMouseFunc(displayMouse);
/*
* 当按下键盘上的某个键时
*/
glutKeyboardFunc(displayKeyboard);
/*
* 如果程序修改了窗口的内容,有时候可能需要调用 glutPostRedisplay(),则它将会指示下面这个
* 函数调用已注册的显示回调函数。
* 必须调用这个函数来启动程序。已注册的显示回调函数,一旦进入循环永远不会退出
*/
glutMainLoop();
return 0;
}
七。绘制一个点
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
glVertex2f(0.0f,0.0f);
glEnd();
glFinish();
}
使用glVertex2f()的时候, 在他的前后使用了glBegin()和glEnd()包围了他。看看有哪些常用的类型:
GL_POINTS:把每一个顶点作为一个点进行处理,顶点n即定义了点n,共绘制N个点
GL_LINES:把每一个顶点作为一个独立的线段,顶点2n-1和2n之间共定义了n条线段,总共绘制N/2条线段
GL_LINE_STRIP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,第n和n+1个顶点定义了线段n,总共绘制n-1条线段
GL_LINE_LOOP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,然后最后一个顶点和第一个顶点相连,第n和n+1个顶点定义了线段n,总共绘制n条线段
GL_TRIANGLES:把每个顶点作为一个独立的三角形,顶点3n-2、3n-1和3n定义了第n个三角形,总共绘制N/3个三角形
GL_TRIANGLE_STRIP:绘制一组相连的三角形,对于奇数n,顶点n、n+1和n+2定义了第n个三角形;对于偶数n,顶点n+1、n和n+2定义了第n个三角形,总共绘制N-2个三角形
GL_TRIANGLE_FAN:绘制一组相连的三角形,三角形是由第一个顶点及其后给定的顶点确定,顶点1、n+1和n+2定义了第n个三角形,总共绘制N-2个三角形
GL_QUADS:绘制由四个顶点组成的一组单独的四边形。顶点4n-3、4n-2、4n-1和4n定义了第n个四边形。总共绘制N/4个四边形
GL_QUAD_STRIP:绘制一组相连的四边形。每个四边形是由一对顶点及其后给定的一对顶点共同确定的。顶点2n-1、2n、2n+2和2n+1定义了第n个四边形,总共绘制N/2-1个四边形
GL_POLYGON:绘制一个凸多边形。顶点1到n定义了这个多边形。
例如:
直线:
void display()
{
glClear( GL_COLOR_BUFFER_BIT);
glBegin( GL_LINES);
glVertex2f( 0.0f, 0.0f);
glVertex2f( -0.3f, 0.1f);
glVertex2f( 0.1f, 0.3f);
glVertex2f( 0.4f, 0.6f);
glEnd();
glFinish();
}
在openGL里面有这样一系列的函数, 他们以glVertex开头, 没错, 这就是我们需要的绘制点的函数, 来看看有哪些:
WINGDIAPI void APIENTRY glVertex2d (GLdouble x, GLdouble y);
WINGDIAPI void APIENTRY glVertex2dv (const GLdouble *v);
WINGDIAPI void APIENTRY glVertex2f (GLfloat x, GLfloat y);
WINGDIAPI void APIENTRY glVertex2fv (const GLfloat *v);
WINGDIAPI void APIENTRY glVertex2i (GLint x, GLint y);
WINGDIAPI void APIENTRY glVertex2iv (const GLint *v);
WINGDIAPI void APIENTRY glVertex2s (GLshort x, GLshort y);
WINGDIAPI void APIENTRY glVertex2sv (const GLshort *v);
WINGDIAPI void APIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z);
WINGDIAPI void APIENTRY glVertex3dv (const GLdouble *v);
WINGDIAPI void APIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z);
WINGDIAPI void APIENTRY glVertex3fv (const GLfloat *v);
WINGDIAPI void APIENTRY glVertex3i (GLint x, GLint y, GLint z);
WINGDIAPI void APIENTRY glVertex3iv (const GLint *v);
WINGDIAPI void APIENTRY glVertex3s (GLshort x, GLshort y, GLshort z);
WINGDIAPI void APIENTRY glVertex3sv (const GLshort *v);
WINGDIAPI void APIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
WINGDIAPI void APIENTRY glVertex4dv (const GLdouble *v);
WINGDIAPI void APIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
WINGDIAPI void APIENTRY glVertex4fv (const GLfloat *v);
WINGDIAPI void APIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w);
WINGDIAPI void APIENTRY glVertex4iv (const GLint *v);
WINGDIAPI void APIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w);
WINGDIAPI void APIENTRY glVertex4sv (const GLshort *v);
WINGDIAPI void APIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
WINGDIAPI void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
不看不知道,一看吓一跳, 光是绘制点就有这么多函数。 安啦, 我们仔细看一下就会明白: 后面跟的数字表示参数的个数, 字母表示参数的类型
s表示16位整数(GLshort)
i表示32位整数(GLint和GLsizei)
f表示32位浮点数(GLfloat和GLclampf)
d表示64位浮点数(GLdouble和GLclampd)
v表示传递的几个参数将使用指针的方式
虽然他们表现方式不同, 但是功能都是一样的, 就像下面几个, 效果都没差, 小伙伴们可以自己看看:
glVertex2i( 1, 1);
glVertex2f( 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 0.0f);
GLfloat posArr[] = { 1.0f, 1.0f, 0.0f};
glVertex3fv( posArr);
说了这么多, 我们来看看该如何绘制一个点, 直接上代码:
void display()
{
glClear( GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
glVertex2f( 0.0f, 0.0f);
glEnd();
glFinish();
}
将我们原来的display函数替换成现在这样, 运行, 是不是在屏幕的中间出现了一个白色的小亮点啊
在使用glVertex2f()的时候, 在他的前后使用了glBegin()和glEnd()包围了他
我们再来看看有哪些常用的类型:
GL_POINTS:把每一个顶点作为一个点进行处理,顶点n即定义了点n,共绘制N个点
GL_LINES:把每一个顶点作为一个独立的线段,顶点2n-1和2n之间共定义了n条线段,总共绘制N/2条线段
GL_LINE_STRIP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,第n和n+1个顶点定义了线段n,总共绘制n-1条线段
GL_LINE_LOOP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,然后最后一个顶点和第一个顶点相连,第n和n+1个顶点定义了线段n,总共绘制n条线段
GL_TRIANGLES:把每个顶点作为一个独立的三角形,顶点3n-2、3n-1和3n定义了第n个三角形,总共绘制N/3个三角形
GL_TRIANGLE_STRIP:绘制一组相连的三角形,对于奇数n,顶点n、n+1和n+2定义了第n个三角形;对于偶数n,顶点n+1、n和n+2定义了第n个三角形,总共绘制N-2个三角形
GL_TRIANGLE_FAN:绘制一组相连的三角形,三角形是由第一个顶点及其后给定的顶点确定,顶点1、n+1和n+2定义了第n个三角形,总共绘制N-2个三角形
GL_QUADS:绘制由四个顶点组成的一组单独的四边形。顶点4n-3、4n-2、4n-1和4n定义了第n个四边形。总共绘制N/4个四边形
GL_QUAD_STRIP:绘制一组相连的四边形。每个四边形是由一对顶点及其后给定的一对顶点共同确定的。顶点2n-1、2n、2n+2和2n+1定义了第n个四边形,总共绘制N/2-1个四边形
GL_POLYGON:绘制一个凸多边形。顶点1到n定义了这个多边形。
直线:
void display()
{
glClear( GL_COLOR_BUFFER_BIT);
glBegin( GL_LINES);
glVertex2f( 0.0f, 0.0f);
glVertex2f( -0.3f, 0.1f);
glVertex2f( 0.1f, 0.3f);
glVertex2f( 0.4f, 0.6f);
glEnd();
glFinish();
}
多边形:
void display()
{
glClear( GL_COLOR_BUFFER_BIT);
glBegin( GL_LINE_LOOP);
glVertex2f( 0.0f, 0.0f);
glVertex2f( -0.3f, 0.1f);
glVertex2f( 0.1f, 0.3f);
glVertex2f( 0.4f, 0.6f);
glEnd();
glFinish();
}
1.创立opengl窗口
#include <windows.h> // Windows的头文件
#include <gl/glew.h> // 包含最新的gl.h,glu.h库
#include <gl/glut.h> // 包含OpenGL实用库
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // 重置OpenGL窗口大小
{
if (height==0) // 防止被零除
{
height=1; // 将Height设为1
}
glViewport(0, 0, width, height); // 重置当前的视口
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity(); // 重置投影矩阵
// 设置视口的大小
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); //
选择模型观察矩阵
glLoadIdentity(); // 重置模型观察矩阵
}
void InitGL(GLvoid) // 此处开始对OpenGL进行所有设置
{
glShadeModel(GL_SMOOTH); // 启用阴影平滑
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 黑色背景
glClearDepth(1.0f); // 设置深度缓存
glEnable(GL_DEPTH_TEST); // 启用深度测试
glDepthFunc(GL_LEQUAL); // 所作深度测试的类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告诉系统对透视进行修正
}
void DrawGLScene(GLvoid) // 从这里开始进行所有的绘制
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
glLoadIdentity(); // 重置当前的模型观察矩阵
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("第一个OpenGL程序");
InitGL();
glutDisplayFunc(DrawGLScene);
glutReshapeFunc(ReSizeGLScene);
glutMainLoop();
return 0;
}
2.绘制图形
///***********改动部分:
void
DrawGLScene(GLvoid) // 从这里开始进行所有的绘制
{
glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存
glLoadIdentity(); //
重置当前的模型观察矩阵
glTranslatef(-1.5f,0.0f,-6.0f); //
左移 1.5 单位,并移入屏幕 6.0
glBegin(GL_TRIANGLES); //
绘制三角形
glVertex3f( 0.0f,
1.0f, 0.0f); // 上顶点
glVertex3f(-1.0f,-1.0f,
0.0f); // 左下
glVertex3f(
1.0f,-1.0f, 0.0f); // 右下
glEnd(); //
三角形绘制结束
glTranslatef(3.0f,0.0f,0.0f); // 右移3单位
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(); //
正方形绘制结束
}
颜色//改动部分:
void
DrawGLScene(GLvoid) // 从这里开始进行所有的绘制
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存
glLoadIdentity(); // 重置模型观察矩阵
glTranslatef(-1.5f,0.0f,-6.0f); // 左移 1.5 单位,并移入屏幕 6.0
glBegin(GL_TRIANGLES); // 绘制三角形
glColor3f(1.0f,0.0f,0.0f); // 设置当前色为红色
glVertex3f( 0.0f, 1.0f, 0.0f); // 上顶点
glColor3f(0.0f,1.0f,0.0f); // 设置当前色为绿色
glVertex3f(-1.0f,-1.0f, 0.0f); // 左下
glColor3f(0.0f,0.0f,1.0f); // 设置当前色为蓝色
glVertex3f( 1.0f,-1.0f, 0.0f); // 右下
glEnd(); // 三角形绘制结束
glTranslatef(3.0f,0.0f,0.0f); // 右移3单位
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(); // 正方形绘制结束
}
旋转
第二个小程序:
// openglTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h> // Windows的头文件
#include <gl/glew.h> // 包含最新的gl.h,glu.h库
#include <gl/glut.h> // 包含OpenGL实用库
static GLfloat rtri = 0;; // 用于三角形的角度
static GLfloat rquad = 0; // 用于四边形的角度
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // 重置OpenGL窗口大小
{
if (height == 0) // 防止被零除
{
height = 1; // 将Height设为1
}
glViewport(0, 0, width, height); // 重置当前的视口
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity(); // 重置投影矩阵
// 设置视口的大小
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵
glLoadIdentity(); // 重置模型观察矩阵
}
void InitGL(GLvoid) // 此处开始对OpenGL进行所有设置
{
glShadeModel(GL_SMOOTH); // 启用阴影平滑
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 黑色背景
glClearDepth(1.0f); // 设置深度缓存
glEnable(GL_DEPTH_TEST); // 启用深度测试
glDepthFunc(GL_LEQUAL); // 所作深度测试的类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告诉系统对透视进行修正 return TRUE; // 初始化 OK
}
void DrawGLScene(GLvoid) // 从这里开始进行所有的绘制
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存
glLoadIdentity(); // 重置模型观察矩阵
glTranslatef(-1.5f, 0.0f, -6.0f); // 左移 1.5 单位,并移入屏幕 6.0
glRotatef(rtri, 0.0f, 1.0f, 0.0f); // 绕Y轴旋转金字塔
glBegin(GL_TRIANGLES); // 开始绘制金字塔的各个面
glColor3f(1.0f, 0.0f, 0.0f); // 红色
glVertex3f(0.0f, 1.0f, 0.0f); // 三角形的上顶点 (前侧面)
glColor3f(0.0f, 1.0f, 0.0f); // 绿色
glVertex3f(-1.0f, -1.0f, 1.0f); // 三角形的左下顶点 (前侧面)
glColor3f(0.0f, 0.0f, 1.0f); // 蓝色
glVertex3f(1.0f, -1.0f, 1.0f); // 三角形的右下顶点 (前侧面)
glColor3f(1.0f, 0.0f, 0.0f); // 红色
glVertex3f(0.0f, 1.0f, 0.0f); // 三角形的上顶点 (右侧面)
glColor3f(0.0f, 0.0f, 1.0f); // 蓝色
glVertex3f(1.0f, -1.0f, 1.0f); // 三角形的左下顶点 (右侧面)
glColor3f(0.0f, 1.0f, 0.0f); // 绿色
glVertex3f(1.0f, -1.0f, -1.0f); // 三角形的右下顶点 (右侧面)
glColor3f(1.0f, 0.0f, 0.0f); // 红色
glVertex3f(0.0f, 1.0f, 0.0f); // 三角形的上顶点 (后侧面)
glColor3f(0.0f, 1.0f, 0.0f); // 绿色
glVertex3f(1.0f, -1.0f, -1.0f); // 三角形的左下顶点 (后侧面)
glColor3f(0.0f, 0.0f, 1.0f); // 蓝色
glVertex3f(-1.0f, -1.0f, -1.0f); // 三角形的右下顶点 (后侧面)
glColor3f(1.0f, 0.0f, 0.0f); // 红色
glVertex3f(0.0f, 1.0f, 0.0f); // 三角形的上顶点 (左侧面)
glColor3f(0.0f, 0.0f, 1.0f); // 蓝色
glVertex3f(-1.0f, -1.0f, -1.0f); // 三角形的左下顶点 (左侧面)
glColor3f(0.0f, 1.0f, 0.0f); // 绿色
glVertex3f(-1.0f, -1.0f, 1.0f); // 三角形的右下顶点 (左侧面)
glEnd(); // 金字塔绘制结束
glLoadIdentity();
glTranslatef(1.5f, 0.0f, -7.0f); // 先右移再移入屏幕
glRotatef(rquad, 1.0f, 1.0f, 1.0f); // 在XYZ轴上旋转立方体
glBegin(GL_QUADS); // 开始绘制立方体
glColor3f(0.0f, 1.0f, 0.0f); // 颜色改为蓝色
glVertex3f(1.0f, 1.0f, -1.0f); // 四边形的右上顶点 (顶面)
glVertex3f(-1.0f, 1.0f, -1.0f); // 四边形的左上顶点 (顶面)
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左下顶点 (顶面)
glVertex3f(1.0f, 1.0f, 1.0f); // 四边形的右下顶点 (顶面)
glColor3f(1.0f, 0.5f, 0.0f); // 颜色改成橙色
glVertex3f(1.0f, -1.0f, 1.0f); // 四边形的右上顶点(底面)
glVertex3f(-1.0f, -1.0f, 1.0f); // 四边形的左上顶点(底面)
glVertex3f(-1.0f, -1.0f, -1.0f); // 四边形的左下顶点(底面)
glVertex3f(1.0f, -1.0f, -1.0f); // 四边形的右下顶点(底面)
glColor3f(1.0f, 0.0f, 0.0f); // 颜色改成红色
glVertex3f(1.0f, 1.0f, 1.0f); // 四边形的右上顶点(前面)
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左上顶点(前面)
glVertex3f(-1.0f, -1.0f, 1.0f); // 四边形的左下顶点(前面)
glVertex3f(1.0f, -1.0f, 1.0f); // 四边形的右下顶点(前面)
glColor3f(0.0f, 0.0f, 1.0f); // 颜色改成蓝色
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的右上顶点(左面)
glVertex3f(-1.0f, 1.0f, -1.0f); // 四边形的左上顶点(左面)
glVertex3f(-1.0f, -1.0f, -1.0f); // 四边形的左下顶点(左面)
glVertex3f(-1.0f, -1.0f, 1.0f); // 四边形的右下顶点(左面)
glColor3f(1.0f, 0.0f, 1.0f); // 颜色改成紫罗兰色
glVertex3f(1.0f, 1.0f, -1.0f); // 四边形的右上顶点(右面)
glVertex3f(1.0f, 1.0f, 1.0f); // 四边形的左上顶点(右面)
glVertex3f(1.0f, -1.0f, 1.0f); // 四边形的左下顶点(右面)
glVertex3f(1.0f, -1.0f, -1.0f); // 四边形的右下顶点(右面)
glEnd(); // 立方体绘制结束
glutSwapBuffers();
}
void MyIdle()
{
rtri += 0.2f; // 增加三角形的旋转变量
rquad -= 0.15f; // 减少四边形的旋转变量
if (rtri>100)
rtri = 0;
if (rquad<-100)
rquad = 0;
DrawGLScene();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow(" OpenGL程序:3D旋转");
InitGL();
glutDisplayFunc(DrawGLScene);
glutReshapeFunc(ReSizeGLScene);
glutIdleFunc(MyIdle);
glutMainLoop();
return 0;
}
以上是关于OPENGL初学的主要内容,如果未能解决你的问题,请参考以下文章
带有顶点/片段着色器的光。使用不同的变量。 (openGL)