【狼】openGL 光照的學習

來源:互聯網
上載者:User

標籤:style   blog   http   color   使用   os   

小狼學習原創,歡迎批評指正

先上代碼

#include "stdafx.h"#include <windows.h>#include "iostream"#include "GL/glut.h"#include "math.h"#define windowsWidth  500#define windowsHeight 500using 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.只有

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.