opengl 笔记(2)

/*-
 * Opengl Demo Test
 *
 * Fredric  : 2016-7-10
 */

#include <GLUT/GLUT.h>
#include <stdlib.h>

void display_demo01();
void display_demo1_idle();

int main(int argc, const char * argv[]) {

    glutInit(&argc, argv);

    glutCreateWindow("Fredric Practice Demo");

    glutDisplayFunc(display_demo01);

    /*
     * void APIENTRY glutIdleFunc(void (*func)(void))
     * 当没有窗口事件发生时的全局回调函数
     */
    glutIdleFunc(&display_demo1_idle);

    glutMainLoop();

}

//****************************************************************************

static int g_angle = 0;

/*
 *  基础动画及光照效果
 *  3D图形中的四种光源模型:
 *  1、点光源:光源从某一点向四面八方传播,例如太阳
 *  2、无穷远光源:对于被照射的物体而言,光线平行摄入,如无穷远处的阳光;
 *  3、方向光源:沿某个方向在特定角度内摄入,如手电筒、车灯等;
 *  4、环境光源:从各个角度都有投射到场景中的光线
 *  PS:在opengl中还考虑自身发光的光源
 *
 *  光线是会随着距离的增加而衰减的,衰减的程度成为衰减因子k,方向光源在偏离该方向时也会衰减

 *  同时材质需要在光照中考虑反射的情况,分为:
 *  1、慢反射:光线射到物体后,其反射是任意方向的;
 *  2、镜面反射:光线射到物体后,其反射是根据被照射物体的法线方向;
 *
 *  综上,对opengl中的某个3D图像顶点的绘制基于如下公式:
 *  顶点颜色 = 材质自发光颜色项 + ∑(环境光颜色+衰减因子×(漫反射项 + 镜面反射项))
 */
void display_demo01(){

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glShadeModel(GL_SMOOTH);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    gluPerspective(75, 1, 1, 1000);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

    gluLookAt(0, -100, 200, 0, 50, 10, 0, 0, 1);

    glColor3f(0.0f, 0.4f, 0.2f);

    glRotatef(-(g_angle * 10.0f),10.0f,5.0f,0.0f);

    //设置光源
    {
        GLfloat light_position[] = {200.0f, 300.0f, 400.0f, 1.0f};
        GLfloat light_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
        GLfloat light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
        GLfloat light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};

        /*
         *  glLightfv (GLenum light, GLenum pname, const GLfloat *params);
         *  控制光源的位置、强度、颜色等
         *  light:GL_LIGHT0 表示第一个光源 GL_LIGHT1 表示第二个光源
         *  panme: 光源控制的类型
         *      GL_POSITION:光源位置
         *      GL_AMBIENT: 光源中的环境光强度
         *      GL_DIFFUSE: 光源中的散射光强度
         *      GL_SPECULAR: 光源中的镜面反射光强度
         */
        glLightfv(GL_LIGHT0, GL_POSITION, light_position);
        glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
        glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
        glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

        glEnable(GL_LIGHT0);
        glEnable(GL_LIGHTING);
        glEnable(GL_DEPTH_TEST);
    }

    //设置材质
    {
        GLfloat mat_ambient[] = {0.0f, 0.5f, 0.3f, 1.0f};
        GLfloat mat_diffuse[] = {0.0f, 0.3f, 0.2f, 1.0f};
        GLfloat mat_specular[] = {0.0f, 0.8f, 0.2f, 1.0f};
        GLfloat mat_emission[] = {0.5f, 0.0f, 0.0f, 1.0f};
        GLfloat mat_shininess = 68.0f;

        /*
         *  glMaterialfv (GLenum face, GLenum pname, const GLfloat *params)
         *  设置材质
         *  face: 正反面
         *      GL_FRONT:正面
         *      GL_BACK:反面
         *      GL_FRONT_AND_BACK:正反面
         *  pname:材质属性
         *      GL_AMBIENT:材质的环境颜色
         *      GL_DIFFUSE:材质的散射颜色
         *      GL_SPECULAR:材质的镜面反射颜色
         *      GL_EMISSION: 材质的发射光颜色
         *      GL_SHININESS:镜面反射指数,0~128 值越小越粗糙
         */

        glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
        glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
        glMaterialf (GL_FRONT, GL_SHININESS, mat_shininess);
    }

    //glutSolidSphere(100,30,30);
    glutSolidCube(80);

    glFlush();

    glutSwapBuffers();

}

//回调函数
void display_demo1_idle(){

   g_angle += 1;

   display_demo01();
}
时间: 2024-11-05 18:11:56

opengl 笔记(2)的相关文章

OpenGL笔记12

OpenGL入门学习[十二] 片断测试其实就是测试每一个像素,只有通过测试的像素才会被绘制,没有通过测试的像素则不进行绘制.OpenGL提供了多种测试操作,利用这些操作可以实现一些特殊的效果.我们在前面的课程中,曾经提到了“深度测试”的概念,它在绘制三维场景的时候特别有用.在不使用深度测试的时候,如果我们先绘制一个距离较近的物体,再绘制距离较远的物体,则距离远的物体因为后绘制,会把距离近的物体覆盖掉,这样的效果并不是我们所希望的.如 果使用了深度测试,则情况就会有所不同:每当一个像素被绘制,Op

OpenGL笔记2.1 角的顶点vertex

本次课程所要讲的是绘制简单的几何图形,在实际绘制之前,让我们先熟悉一些概念.向量:http://zh.wikipedia.org/wiki/%E7%9F%A2%E9%87%8F 一.点.直线和多边形我们知道数学(具体的说,是几何学)中有点.直线和多边形的概念,但这些概念在计算机中会有所不同. 数学上的点,只有位置,没有大小.但在计算机中,无论计算精度如何提高,始终不能表示一个无穷小的点.另一方面,无论图形输出设备(例如,显示器)如何精 确,始终不能输出一个无穷小的点.一般情况下,OpenGL中的

opengl 笔记(一)

参考<opengl入门教程>.<OpenGL之坐标转换>.<OpenGL绘制管线操作细节>等资料. 复习下留个备忘:) /*- * Opengl Demo Test * * Fredric : 2016-7-8 */ #include <GLUT/GLUT.h> void display_demo01(); void display_demo02(); void display_demo03(); void display_demo04(); /* * Ma

OpenGL笔记10

今天我们先简单介绍Windows中常用的BMP文件格式,然后讲OpenGL的像素操作.虽然看起来内容可能有点多,但实际只有少量几个知识点,如果读者对诸如“显示BMP图象”等内容比较感兴趣的话,可能不知不觉就看完了. 像素操作可以很复杂,这里仅涉及了简单的部分,让大家对OpenGL像素操作有初步的印象. 学过多媒体技术的朋友可能知道,计算机保存图象的方法通常有两种:一是“矢量图”,一是“像素图”.矢量图保存了图象中每一几何物体的位置.形状.大小等信 息,在显示图象时,根据这些信息计算得到完整的图象

OpenGL笔记2.2 镂空

在第二课中,我们学习了如何绘制几何图形,但大家如果多写几个程序,就会发现其实还是有些郁闷之处.例如:点太小,难以看清楚:直线也太细,不舒服:或者想画虚线,但不知道方法只能用许多短直线,甚至用点组合而成. 这些问题将在本课中被解决. 下面就点.直线.多边形分别讨论. 1.关于点 点的大小默认为1个像素,但也可以改变之.改变的命令为glPointSize,其函数原型如下: void glPointSize(GLfloat size); size必须大于0.0f,默认值为1.0f,单位为“像素”. 注

OpenGl笔记 12.1 stencil 模版 缓冲区

在OpenGL中存在着多种缓冲区,这些缓冲区大致分为: 深度缓冲区:存储每个像素的深度值,当启动深度测试时,片段像素深度值和深度缓冲区深度值进行比较,决定片段哪些像素点数据可以替换到颜色缓冲区中. 模板缓冲区(Stencil Buffer):与颜色缓冲区和深度缓冲区类似,模板缓冲区可以为屏幕上的每个像素点保存一个无符号整数值.这个值的具体意义视程序的具体应用而定.在渲染的过程中,可以用这个值与一个预先设定的参考值相比较,根据比较的结果来决定是否更新相应的像素点的颜色值.这个比较的过程被称为模板测

OpenGL笔记15 顶点数据

这次讲的所有内容都装在一个立方体中,呵呵.呵呵,绘制一个立方体,简单呀,我们学了第一课第二课,早就会了.先别着急,立方体是很简单,但是这里只是拿立方体做一个例子,来说明OpenGL在绘制方法上的改进.从原始一点的办法开始一个立方体有六个面,每个面是一个正方形,好,绘制六个正方形就可以了. glBegin(GL_QUADS);     glVertex3f(...);     glVertex3f(...);     glVertex3f(...);     glVertex3f(...); //

OpenGL笔记11

我们在前一课中,学习了简单的像素操作,这意味着我们可以使用各种各样的BMP文件来丰富程序的显示效果,于是我们的OpenGL图形程序也不再像以前总是 只显示几个多边形那样单调了.——但是这还不够.虽然我们可以将像素数据按照矩形进行缩小和放大,但是还不足以满足我们的要求.例如要将一幅世界地图绘制 到一个球体表面,只使用glPixelZoom这样的函数来进行缩放显然是不够的.OpenGL纹理映射功能支持将一些像素数据经过变换(即使是比较不规 则的变换)将其附着到各种形状的多边形表面.纹理映射功能十分强

OpenGL笔记9

今天介绍关于OpenGL混合的基本知识.混合是一种常用的技巧,通常可以用来实现半透明.但其实它也是十分灵活的,你可以通过不同的设置得到不同的混合结果,产生一些有趣或者奇怪的图象.混合是什么呢?混合就是把两种颜色混在一起.具体一点,就是把某一像素位置原来的颜色和将要画上去的颜色,通过某种方式混在一起,从而实现特殊的效果.假设我们需要绘制这样一个场景:透过红色的玻璃去看绿色的物体,那么可以先绘制绿色的物体,再绘制红色玻璃.在绘制红色玻璃的时候,利用“混合”功能,把将要绘制上去的红色和原来的绿色进行混

OpenGL笔记13

前一段时间里,论坛有位朋友问什么是状态机.按我的理解,状态机就是一种存在于理论中的机器,它具有以下的特点: 1. 它有记忆的能力,能够记住自己当前的状态. 2. 它可以接收输入,根据输入的内容和自己的状态,修改自己的状态,并且可以得到输出. 3. 当它进入某个特殊的状态(停机状态)的时候,它不再接收输入,停止工作. 理论说起来很抽象,但实际上是很好理解的. 首先,从本质上讲,我们现在的电脑就是典型的状态机.可以对照理解: 1. 电脑的存储器(内存.硬盘等等),可以记住电脑自己当前的状态(当前安装