【狼】openGL 光照的学习

小狼学习原创,欢迎批评指正

先上代码

#include "stdafx.h"
#include <windows.h>

#include "iostream"

#include "GL/glut.h"
#include "math.h"

#define windowsWidth  500
#define windowsHeight 500

using namespace std;

int preX,preY;
bool leftState=false;
bool rightState=false;
float angleX=0.0;
float angleY=0.0;
float angleY1=0.0;
float angleY2=0.0;
float angleX1=0.0;
float angleX2=0.0;

void init()
{
    GLfloat mat_diffuse[4] = {0.5,0.5,0.5,1};
    GLfloat mat_specular[] = {1,1,1,1};
    GLfloat mat_ambient[] = {1,1,1,1};
    GLfloat light_position[] = {1,1,1,0};

    glClearColor(0,0,0,0);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);//环境光(全局环境光)
    glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);//散射光(很微弱的光,感觉像是从各种的物体反射的光)
    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);//反射光(像高光)
    glMaterialf(GL_FRONT,GL_SHININESS,25.0);
    glLightfv(GL_LIGHT0,GL_POSITION,light_position);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glColorMaterial(GL_FRONT,GL_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);
    glClear(GL_COLOR_BUFFER_BIT);
    glRotatef(angleX1,0.0,1.0,0.0);
    glRotatef(angleY1,-1.0,0.0,0.0);
    glBegin(GL_DIFFUSE);
    glColor3f(0.0f,0.0f,1.0f);
    glutSolidTeapot(0.6f);
    cout<<"init"<<endl;
}
void KeyPressFunc(int key, int x, int y)
{

    if(key==GLUT_KEY_UP)
    {
        angleY1 = 1;
        angleX1 = 0;
        glutPostRedisplay();//重绘图像

    }
    else if(key==GLUT_KEY_DOWN)
    {
        angleY1 = -1;
            angleX1 = 0;
        glutPostRedisplay();
    }
    else if(key==GLUT_KEY_RIGHT)
    {
        angleX1 = 1;
        angleY1 = 0;
        glutPostRedisplay();
    }
    else if(key==GLUT_KEY_LEFT)
    {
        angleX1 =- 1;
            angleY1 = 0;
        glutPostRedisplay();
    }
}
void randerScene()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    init();
    glFlush();
    //ERROR
    cout<<"shuaxin"<<endl;
}
void reshape(int w, int h)
{
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= h)
    {
        glOrtho(-1.5,1.5,-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-10,10);

    }
    else
    {
        glOrtho(-1.5*(GLfloat)w/(GLfloat)h,1.5*(GLfloat)w/(GLfloat)h,-1.5,1.5,-10,10);

    }
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    randerScene();
}

void IdleFunc()
{
    angleY1 = 0;
    angleX1 = 0.1;
    glutPostRedisplay();//重绘图像
}
void setupRc()
{
    glClearColor(0.5f,0.5f,0.5f,1.0f);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );

    glShadeModel (GL_FLAT);//光滑着色
}

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

{

    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH | GLUT_STENCIL );

    glutInitWindowPosition(100, 100);

    glutInitWindowSize(400, 400);

    glutCreateWindow("teapot");
    init();
    glutDisplayFunc(randerScene);
    setupRc();
    glutSpecialFunc(KeyPressFunc);
//  glutIdleFunc(IdleFunc);//空闲状态执行函数(取消注释茶壶自行旋转)
    glutReshapeFunc(&reshape);
    glutMainLoop();

    return 0;

}
        

这是一个受很多光照着Front(前面)的蓝色小茶壶,

分析下代码,从init(初始化)开始,

glShadeModel();这个是选择着色方式的函数,

如果里面的参数是GL_SMOOTH,那就是光滑着色,有渐变的效果,

如果参数是GL_FLAT,那就是平面着色,没有渐变效果,都是一个颜色,

而这只有在定点颜色不同时才有区别,

作为光滑smooth模式,右图为flat平面模式

应用光滑处理模式时,多边形所有点的法向是由内插生成的,具有一定的连续性,因此每个点的颜色也相应内插,故呈现不同色。这种模式下,插值方法采用的是双线性插值法

通常算法为:先用多边形顶点的光强线性插值出当前扫描线与多边形边交点处的光强,然后再用交点的光强线插值处扫描线位于多边形内区段上每一象素处的光强值。

图中显示出一条扫描线与多边形相交,交线的端点是A点和B点,P点是扫描线上位于多边形内的任一点,多边形三个顶点的光强分别为I1、I2和I3.

取A点的光强Ia为I1和I2的线性插值,B点的光强Ib为I1和I3的线性插值,P点的光强Ip则为Ia和Ib的线性插值。

处理后可以使用多边形表示的曲面光强连续,而且计算量很小。这种算法还可以以增量的形式改进,且能用硬件直接实现算法,从而广泛用于计算机实时图形生成

接下来是光照部分的重点函数,glMaterial(),

他有glMaterialf, glMateriali, glMaterialfv, glMaterialiv。这四种形式,

如果是

void glMaterialf(GLenum face,
                 GLenum pname,
                 GLfloat para)
void glMateriali(GLenum face,
                 GLenum pname,
                 GLint para)

这两个函数pname只能是GL_SHININESS(镜面指数)的属性,因为只有镜面指数是一个值(para)控制的

face
哪一面被刷新. 是 GL_FRONT, GL_BACK, 或GL_FRONT_AND_BACK中的一个
pname
什么光照属性,这里只能是是 GL_SHININESS.
param
 GL_SHININESS 的属性值.
如果是
void glMaterialfv(GLenum face,
                  GLenum pname,
                  const GLfloat *params)
void glMaterialiv(GLenum face,
                  GLenum pname,
                  const GLint *params)

因为函数后缀是v(vectors向量),所以要预先设置glfloat数组的值

face
哪一面被刷新. 是 GL_FRONT, GL_BACK, 或GL_FRONT_AND_BACK中的一个
pname
什么光照属性,这里可以是 GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, GL_SHININESS, GL_AMBIENT_AND_DIFFUSE, 或 GL_COLOR_INDEXES的其中之一
param
属性值(数组)
GL_AMBIENT  环境光的颜色
GL_DIFFUSE  散射光的颜色
GL_SPECULAR  镜面反射光(高光)的颜色
GL_EMISSION  发射颜色(自发光的颜色)
GL_SHININESS  镜面指数(取值范围为[0.0, 128.0],数值越大,高光越小,亮度越高)
GL_AMBIENT_AND_DIFFUSE  环境光和散射光的颜色
GL_COLOR_INDEXES  环境光,散射光,镜面光的颜色索引(index)

这些设置的都是GL_LIGHTn的属性(GL_LIGHT0,GL_LIGHT1,GL_LIGHT2。。。。一个又一个的光源),

GL_LIGHT0属性的默认值与其他不同,需要注意

p.s.只有

【狼】openGL 光照的学习

时间: 2024-08-06 17:41:45

【狼】openGL 光照的学习的相关文章

OpenGL光照3:光源

本文是个人学习记录,学习建议看教程 https://learnopengl-cn.github.io/ 非常感谢原作者JoeyDeVries和多为中文翻译者提供的优质教程 的内容为插入注释,可以先跳过 投光物(光源) 我们目前使用的光照都来自于空间中的一个点,它能给我们不错的效果,但现实世界中,我们有很多种类的光照,每种的表现都不同 将光投射(Cast)到物体的光源叫做投光物(Light Caster),我们将会讨论几种不同类型的投光物,学会模拟不同种类的光源是又一个能够进一步丰富场景的工具 我

清华版CG 实验7 OpenGL光照

一.实验目的: 了解掌握OpenGL程序的光照与材质,能正确使用光源与材质函数设置所需的绘制效果. 二.实验内容: (1)下载并运行Nate Robin教学程序包中的lightmaterial程序,试验不同的光照与材质系数: (2)运行示范代码1,了解光照与材质函数使用. 三.实验原理: 为在场景中增加光照,需要执行以下步骤: (1) 设置一个或多个光源,设定它的有关属性: (2) 选择一种光照模型: (3) 设置物体的材料属性. 具体见教材第8章8.6节用OpenGL生成真实感图形的相关内容.

OpenGL光照和颜色

OpenGL光照和颜色 转自:http://www.cnblogs.com/kekec/archive/2011/08/16/2140789.html OpenGL场景中模型颜色的产生,大致为如下的流程图所描述:++ ++++++  ++++++  ++++++  ++++++ (1)当不开启光照时,使用顶点颜色来产生整个表面的颜色. 用glShadeModel可以设置表面内部像素颜色产生的方式.GL_FLAT/GL_SMOOTH. ++ (2)一般而言,开启光照后,在场景中至少需要有一个光源(

OpenGL光照设置

1.设置光源 (1)光源的种类 环境光 环境光是一种无处不在的光.环境光源放出的光线被认为来自任何方向.因此,当你仅为场景指定环境光时,所有的物体无论法向量如何,都将表现为同样的明暗程度. 点光源 由这种光源放出的光线来自同一点,且方向辐射向四面八方. 平行光 平行光又称镜面光,这种光线是互相平行的.从手电筒.太阳等物体射出的光线都属于平行光. 聚光灯 这种光源的光线从一个锥体中射出,在被照射的物体上产生聚光的效果.使用这种光源需要指定光的射出方向以及锥体的顶角α. (2)光的成分 对于每一种光

OpenGL光照2:材质

本文是个人学习记录,学习建议看教程 https://learnopengl-cn.github.io/ 非常感谢原作者JoeyDeVries和多为中文翻译者提供的优质教程 的内容为插入注释,可以先跳过 前言 在现实世界里,每个物体会对光产生不同的反应,钢看起来通常会比陶瓷花瓶更闪闪发光,木头箱子也不会像钢制箱子那样对光产生很强的反射 每个物体对镜面高光也有不同的反应,有些物体反射光的时候不会有太多的散射(Scatter),因而产生一个较小的高光点,而有些物体则会散射很多,产生一个有着更大半径的高

第07课 OpenGL 光照和键盘(1)

光照和键盘控制: 在这一课里,我们将添加光照和键盘控制,它让程序看起来更美观. 这一课我会教您如何使用三种不同的纹理滤波方式.教您如何使用键盘来移动场景中的对象,还会教您在OpenGL场景中应用简单的光照.这一课包含了很多内容,如果您对前面的课程有疑问的话,先回头复习一下.进入后面的代码之前,很好的理解基础知识十分重要.我们还是在第一课的代码上加以修改.跟以前不一样的是,只要有任何大的改动,我都会写出整段代码.程序开始,我们先加上几个新的变量. 下面几行是新的.我们增加三个布尔变量. light

Unity预计算全局光照的学习(速度优化,LightProbe,LPPV)

1.基本参数与使用 1.1 常规介绍 使用预计算光照需要在Window/Lighting面板下找到预计算光照选项,保持勾选预计算光照并保证场景中有一个光照静态的物体 此时在编辑器内构建后,预计算光照开始生效. 相关的文章有很多,unity官方有一系列文章不错: https://unity3d.com/cn/learn/tutorials/topics/graphics/introduction-precomputed-realtime-gi 在Lighting面板的Scene页签下可以设置全局光

openGl超级宝典学习笔记 (1)第一个三角形

执行效果 代码及解析: // // Triangle.cpp // Triangle // // Created by fengsser on 15/6/20. // Copyright (c) 2015年 fengsser. All rights reserved. // #include <GLTools.h>//用作掩盖不同平台的差异,建立窗体等工作 #include <GLShaderManager.h> #ifdef __APPLE__ #include <glut

openGl超级宝典学习笔记 (2) 7个基本的几何图元

点(GL_POINTS): 点总是正方形的像素,默认情况下,点的大小不受透视除法影响.即不管与视点的距离如何,它的大小都不改变.为了获得圆点,必须在抗锯齿模式下绘制点. 可以用glPointSize改变点的大小. //点 //建立批次 GLBatch pointBatch; GLfloat vCoast[24][3] = {{2.80, 1.20, 0.0 }, {2.0, 1.20, 0.0 }, {2.0, 1.08, 0.0 }, {2.0, 1.08, 0.0 }, {0.0, 0.80