OpenGL编程轻松入门(二)

简介:
OpenGL编程轻松入门(二)
(由同事黄燕创作)
 
1.         使用颜色
通过上一节的例子我们已经知道一些简单的使用颜色的方法。这一节我们进一步讲讲颜色的使用。
例2:本例子使用颜色引索模式绘制8个不同颜色的球体。阅读此例时,请主要关注函数palette和DrawColotFans。
glIndex设置当前颜色索引。参数为当前颜色索引。本例中glIndexd 函数的参数j+1对应palette中auxSetOneColor函数中的i+1,auxSetOneColor函数的后三个函数制定对应的颜色,颜色值由变量rgb[8][3]定义。
#include <GL/glut.h>
#include <GL/glaux.h>
 
void init(void)
{
        glClearColor(1.0,1.0,1.0,1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        glShadeModel(GL_SMOOTH);
}
 
void palette(void)
{
        GLint i;
        static GLfloat rgb[8][3]={{1,0,0},{1,0,0.5},{1,0,1},
        {0,0,1},{0,1,1},{0,1,0},{1,1,0},{1,0.5,0}};
 
        for(i = 0;i<8;i++)
        {
                        auxSetOneColor(i+1,rgb[i][0],rgb[i][1],rgb[i][2]);//设置颜色
        }
}
 
void DrawColorFans(void)
{
        GLint j;
 
        glTranslatef(-15,-15,0);
        for(j = 0;j<8;j++)
        {
                        glIndexd(j+1);//设置当前颜色索引
                       /*在不同位置绘制球体*/
                        glTranslatef(j,j-1,0);
                        glutSolidSphere(1,20,20);
        }
}
 
void CALLBACK display(void)
{
        palette();
        DrawColorFans();
        glFlush();
}
 
void CALLBACK reshape(GLsizei w,GLsizei h)
{
        glViewport(0,0,w,h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(100,1,1,20);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0,0,-15);
}
void main()
{
    /*初始化并设置窗口*/
        auxInitDisplayMode(AUX_SINGLE|AUX_INDEX);
        auxInitPosition(100,100,500,500);
        auxInitWindow("draw the color sphere");
     
     /*绘制及显示*/
        init();
        auxReshapeFunc(reshape);
        auxMainLoop(display);
}
2.         坐标变换
本节中的例子仅仅是将第二节的例子作了一点点改动。将myDisplay函数中画三角型的那一部分提出来写成一个函数drawTriangle。然后在myDisplay函数中用drawTriangle();代替原来的语句。这时例3和例1完成的功能完全一样。而此时我们知道坐标的原点在窗口的中心。我们用glTranslate函数改变坐标的原点。同样glTranslate函数后的f和d表明参数的类型。其参数的含义和glVertex中参数的含义一样。坐标原点改变后,我们再调用一次drawTriangle();可以发现三角型的位置已经发生了变化。
例3:利用坐标变换在不同位置画相同的三角形(部分代码)
void drawTriangle(void)
{
        glBegin(GL_TRIANGLES);//开始画三角形
                        glShadeModel(GL_SMOOTH);//设置为光滑明暗模式
                        
                        glColor3f(1.0,0.0,0.0);//设置第一个顶点点为红色
                        glVertex2f(-1.0,-1.0);//设置第一个顶点的坐标为(-1.0,-1.0)
 
                        glColor3f(0.0,1.0,0.0);//设置第二个顶点点为绿色
                        glVertex2f(0.0,-1.0);//设置第二个顶点的坐标为(0.0,-1.0)
 
                        glColor3f(0.0,0.0,1.0);//设置第三个顶点点为蓝色
                        glVertex2f(-0.5,1.0);//设置第三个顶点的坐标为(-0.5,1.0)
        glEnd();//三角形结束
 
}
 
void myDisplay(void)
{
        glClear(GL_COLOR_BUFFER_BIT);//buffer设置为颜色可写
 
        drawTriangle();
        glTranslatef(1,0,0);//坐标变换
        drawTriangle();
 
        glFlush();//强制OpenGL函数在有限时间内运行
}
glTranslate是对坐标进行平移,glRotate对坐标进行旋转,glScale实际上是对坐标的缩放。还有一些和透视有关的矩阵变换,在以后的例子中我们会接触到一些不同的坐标变换,在这里就不一一例举。
3.         堆栈操作
本节中的例子其结构和例1一样,仅改变myDisplay和myReshape。
例4:利用堆栈绘制三个物体——一个绿色的茶壶,一个蓝色的茶壶,一个红色的立方体(部分代码)
void myDisplay(void)
{
        glClear(GL_COLOR_BUFFER_BIT);
 
        /*蓝色茶壶*/
        glPushMatrix();
                        glColor3f(0.0,0.0,1.0);
                        glutSolidTeapot(1.5);
        glPopMatrix();
 
        /*红色立方体*/
        glPushMatrix();
                        glTranslatef(5.0,0.0,0.0);//坐标变换
                        glColor3f(1.0,0.0,0.0);
                        glutSolidCube(1.0);
        glPopMatrix();
 
        /*绿色茶壶*/
        glPushMatrix();
                        glTranslatef(-5.0,0.0,0.0);//坐标变换
                        glColor3f(0.0,1.0,0.0);
                        glutSolidTeapot(1.0);
        glPopMatrix();
 
        glFlush();
}
 
void myReshape(GLsizei w,GLsizei h)
{
        glViewport(0,0,w,h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(80.0,(GLdouble)w/(GLdouble)h,1.0,20.0);//创建透视投影矩阵
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0.0,0.0,-8.0);
        
}
运行后,我们可以看到左边为一个绿色的茶壶,中间为蓝色的茶壶,右边为红色的立方体。现在我们注释掉所有的glPushMatrix();glPopMatrix();运行后我们会发现两个茶壶重叠在一起。这是因为glPushMatrix();glPopMatrix();使得坐标转换的原始坐标都是最初始的坐标。而将glPushMatrix();      glPopMatrix()注释掉后,glTranslatef(5.0,0.0,0.0); glTranslatef(-5.0,0.0,0.0);两行语句使得绿色茶壶回到了(0,0)就和蓝色的茶壶重叠在一起。
除此之外还有很多堆栈操作,需要用时可以通过查MSDN或网络或有关书籍。
4.         显示例表
    利用显示列表,我们们可以减少重复的劳动。我们可以从例5中得到体会。
例5:绘制六个彩色的三角形。
#include <windows.h>
#include <GL/glut.h>
 
GLuint listName = 1;
 
void myInit(void)
{
        glClearColor(0.0,0.0,0.0,0.0);//设置背景为黑色
 
        glNewList(listName,GL_COMPILE);//创建显示列表
                /*画一个彩色多边形*/
                 glBegin(GL_POLYGON);
                         glColor3f(1.0,0.0,0.0);
                                       glVertex2f(1.0,1.0);
 
                                       glColor3f(0.0,1.0,0.0);
                                       glVertex2f(2.0,2.0);
 
                                       glColor3f(0.0,0.0,1.0);
                                       glVertex2f(1.5,2.5);
 
                                       glTranslatef(0.5,-0.5,0.0);//坐标转换
                        glEnd();
        glEndList();//结束显示列表
 
        glShadeModel(GL_SMOOTH);
}
 
 
void myDisplay(void)
{
        GLuint i;
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 
        /*绘制六个三角型*/
        for(i = 0;i<6;i++)
                        glCallList(listName);
        glFlush();
}
 
void myReshape(GLsizei w,GLsizei h)
{
        glViewport(0,0,w,h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        if(w<=h)
                        glOrtho(-4.0,4.0,-4.0*(GLfloat)h/(GLfloat)w,4.0*(GLfloat)h/(GLfloat)w,-8.0,8.0);
        else
                        glOrtho(-4.0,4.0*(GLfloat)w/(GLfloat)h,-4.0,4.0,-8.0,8.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(-4.0,0.0,-3.0);
}
 
int main(int argc,char ** argv)
{
        /*初始化*/
        glutInit(&argc,argv);
 
        glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
        glutInitWindowSize(500,500);
        glutInitWindowPosition(100,200);
        
         /*创建窗口*/
        glutCreateWindow("display list");
 
        /*绘制显示*/
myInit();
        glutReshapeFunc(myReshape);
        glutDisplayFunc(myDisplay);
 
        glutMainLoop();
        return(0);
}
l         void glNewList(GLuint list,GLenum mode)和glEndList(void)创建或替换一个显示列表。list为列表名称。mode指定编译模式,本例为GL_COMPILE。GL_COMPILE表示仅仅编译。GL_COMPILE_AND_EXECUTE表示当命令被编译到显示列表时执行。显示列表时一个预先存储起来已被将来执行的一组OpenGL命令,使用glNewList函数创建显示列表,并将所有需要执行的命令按照命令发出的顺序放置在显示列表中,直到调用glEndList函数时结束显示列表。本例中所需要执行的命令为画一个多边形。
void glCallList(GLuint list)执行一个显示列表。参数list为所要执行的显示列表的名字,类型为整形。本例中在不同的位置绘制了六个完全一样的三角形。








 本文转自 21cnbao 51CTO博客,原文链接:http://blog.51cto.com/21cnbao/120264,如需转载请自行联系原作者



相关文章
|
vr&ar Android开发 C++
Android OpenGL入门
Android OpenGL入门
Android OpenGL入门
|
Android开发 异构计算
Android OpenGL ES(八)----纹理编程框架(二)
Android OpenGL ES(八)----纹理编程框架(二)
160 0
Android OpenGL ES(八)----纹理编程框架(二)
|
存储 Java API
Android OpenGL ES(八)----纹理编程框架(一)
Android OpenGL ES(八)----纹理编程框架(一)
276 0
Android OpenGL ES(八)----纹理编程框架(一)
|
Android开发
Android OpenGL ES(三)----编程框架(二)
Android OpenGL ES(三)----编程框架(二)
99 0
Android OpenGL ES(三)----编程框架(二)
|
Java API Android开发
Android OpenGL ES(三)----编程框架(一)
Android OpenGL ES(三)----编程框架(一)
99 0
|
iOS开发 异构计算
了解 OpenGL ES实现自定义编程粒子效果 思路
本案例旨在于了解OpenGL ES中自定义编程粒子效果的整体实现思路。
162 0
了解 OpenGL ES实现自定义编程粒子效果 思路
|
存储 缓存 安全
OpenGL ES 入门:GLKit加载图片
OpenGL ES 入门:GLKit加载图片
146 0
OpenGL ES 入门:GLKit加载图片
|
存储 缓存
案例 02、OpenGL入门--正方形键位控制
OpenGL入门--正方形键位控制
126 0
案例 02、OpenGL入门--正方形键位控制
|
缓存 容器
案例 01、OpenGL入门--绘制三角形
OpenGL中三角形的绘制,就类似于学习编程时的Hello world,是一个入门级的使用,重点在于理解图形是如何绘制的
225 0
案例 01、OpenGL入门--绘制三角形
|
C++ 异构计算 Python
OpenGL渲染入门
## 前言 在开始之前,先来看一段图像解码序列(格式为YUV420)的4个渲染结果,这里我分别截了4张图 ![image.png](https://ata2-img.cn-hangzhou.oss-pub.aliyun-inc.com/dca46d1be7dfee07981a7dea14ae3aa1.png) 其中4个渲染效果分别是 左上:直接渲染视频帧并绘制到窗口上 右上:
1749 0