Opengl 照明不工作
Opengl lighting not working
到目前为止,天空盒和立方体以及左右前后移动相机的功能都可以使用。然而,立方体没有被光照遮蔽,甚至没有显示为正确的颜色。从我的角度来看,我已经启用了我被告知要启用的所有内容并创建了一个光源等等,所以我很迷茫。
// ========================================================================
//
// ========================================================================
#include <iostream>
#include <GL/freeglut.h>
#include <cmath>
#include "loadTGA.h"
using namespace std;
#define GL_CLAMP_TO_EDGE 0x812F //To get rid of seams between textures
float theta = 0.0; //Camera rotation
float cdr=3.14159265/180.0; //Conversion from degrees to radians
float eye_x=0.0, eye_z=0.0;
float look_x=eye_x + 100*sin(cdr*theta);
float look_z=eye_z - 100*cos(cdr*theta);
GLuint texId[6];
void loadGLTextures() // Load bitmaps And Convert To Textures
{
glGenTextures(6, texId); // Create texture ids
// *** left ***
glBindTexture(GL_TEXTURE_2D, texId[0]);
loadTGA("alps_rt.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// *** front ***
glBindTexture(GL_TEXTURE_2D, texId[1]);
loadTGA("alps_ft.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// *** right ***
glBindTexture(GL_TEXTURE_2D, texId[2]);
loadTGA("alps_lf.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// *** back***
glBindTexture(GL_TEXTURE_2D, texId[3]);
loadTGA("alps_bk.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// *** top ***
glBindTexture(GL_TEXTURE_2D, texId[4]);
loadTGA("alps_up.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// *** down ***
glBindTexture(GL_TEXTURE_2D, texId[5]);
loadTGA("grass.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
}
//========================================================================================
void temple(){
glColor3f(0, 0, 0);
glPushMatrix();
glTranslatef(20, 10, 0);
glutSolidCube(1);
glPopMatrix();
}
void skybox(){
glEnable(GL_TEXTURE_2D);
////////////////////// LEFT WALL ///////////////////////
glBindTexture(GL_TEXTURE_2D, texId[0]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f(-10000, 0, 10000);
glTexCoord2f(1., 0.);
glVertex3f(-10000, 0., -10000);
glTexCoord2f(1., 1.);
glVertex3f(-10000, 10000., -10000);
glTexCoord2f(0., 1.);
glVertex3f(-10000, 10000, 10000);
glEnd();
////////////////////// FRONT WALL ///////////////////////
glBindTexture(GL_TEXTURE_2D, texId[1]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f(-10000, 0, -10000);
glTexCoord2f(1., 0.);
glVertex3f(10000, 0., -10000);
glTexCoord2f(1., 1.);
glVertex3f(10000, 10000, -10000);
glTexCoord2f(0., 1.);
glVertex3f(-10000, 10000, -10000);
glEnd();
////////////////////// RIGHT WALL ///////////////////////
glBindTexture(GL_TEXTURE_2D, texId[2]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f(10000, 0, -10000);
glTexCoord2f(1., 0.);
glVertex3f(10000, 0, 10000);
glTexCoord2f(1., 1.);
glVertex3f(10000, 10000, 10000);
glTexCoord2f(0., 1.);
glVertex3f(10000, 10000, -10000);
glEnd();
////////////////////// REAR WALL ////////////////////////
glBindTexture(GL_TEXTURE_2D, texId[3]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f( 10000, 0, 10000);
glTexCoord2f(1., 0.);
glVertex3f(-10000, 0, 10000);
glTexCoord2f(1., 1.);
glVertex3f(-10000, 10000, 10000);
glTexCoord2f(0., 1.);
glVertex3f( 10000, 10000, 10000);
glEnd();
/////////////////////// TOP //////////////////////////
glBindTexture(GL_TEXTURE_2D, texId[4]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f(-10000, 10000, -10000);
glTexCoord2f(1., 0.);
glVertex3f(10000, 10000, -10000);
glTexCoord2f(1., 1.);
glVertex3f(10000, 10000, 10000);
glTexCoord2f(0., 1.);
glVertex3f(-10000, 10000, 10000);
glEnd();
/////////////////////// FLOOR //////////////////////////
glBindTexture(GL_TEXTURE_2D, texId[5]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f(-10000, 0., 10000);
glTexCoord2f(100., 0.);
glVertex3f(10000, 0., 10000);
glTexCoord2f(100., 100.);
glVertex3f(10000, 0., -10000);
glTexCoord2f(0., 100.);
glVertex3f(-10000, 0., -10000);
glEnd();
}
//---------------------------------------------------------------------
void initialise(void)
{
float grey[4] = {0.2, 0.2, 0.2, 1.0};
float white[4] = {1.0, 1.0, 1.0, 1.0};
loadGLTextures();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, grey);
glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
glLightfv(GL_LIGHT0, GL_SPECULAR, white);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_NORMALIZE);
glClearColor (0.0, 0.0, 0.0, 0.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(90.0, 1.0, 1.0, 20000.0); //Perspective projection
}
//---------------------------------------------------------------------
void display(void)
{
float outsidelightpos[4] = {1.0f, 1.0f, 1.0f, 1.0f};
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt (eye_x, 10, eye_z, look_x, 10, look_z, 0, 1, 0); //camera rotation
glLightfv(GL_LIGHT0, GL_POSITION, outsidelightpos);
skybox();
temple();
glFlush();
}
//--------------------------------------------------------------
void special(int key, int x, int y)
{
if(key==GLUT_KEY_LEFT) theta-=5; //Turn left
else if(key==GLUT_KEY_RIGHT) theta+=5; //Turn right
else if(key == GLUT_KEY_DOWN)
{ //Move backward
eye_x -= 5*sin(cdr*theta);
eye_z += 5*cos(cdr*theta);
}
else if(key == GLUT_KEY_UP)
{ //Move forward
eye_x += 5*sin(cdr*theta);
eye_z -= 5*cos(cdr*theta);
}
look_x = eye_x + 100*sin(cdr*theta);
look_z = eye_z - 100*cos(cdr*theta);
glutPostRedisplay();
glutSwapBuffers();
}
//-------------------------------------------------------------------
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_DEPTH);
glutInitWindowSize (1024, 800);
glutInitWindowPosition (50, 50);
glutCreateWindow ("Alex Bull's Assignment");
initialise();
glutDisplayFunc(display);
glutSpecialFunc(special);
glutMainLoop();
return 0;
}
所以,你画了这个"temple"立方体
- 当纹理仍然打开时,你的天空盒的最后一个纹理仍然是绑定的。由于
glutSloidCube
不提供任何纹理坐标,因此将在所有地方使用相同的纹理坐标。您可以使用 glDisable(GL_TEXTURE_2D)
来禁用它。
- 颜色为 (0,0,0) 而
glColorMaterial
设置为 GL_AMBIENT_AND_DIFFUSE
,所以你基本上只会得到镜面光照
- 使用 GL 的固定功能,所以你只能得到 gouraud 阴影,而不会得到任何有用的镜面高光,因为光照只是在你的立方体的每个角顶点计算
所以,最后,你会得到一个蹩脚的镜面高光,由你的一些天空盒纹理的一些角纹素颜色调制,插值到你的立方体表面。
您应该注意到,您使用的几乎每一个 GL 函数 已弃用,因为 十年[=31] =] 现在。您的代码完全过时了,固定功能早已从 GPU 中消失了。如果你现在真的想学习 OpenGL,你不应该用 20 年前的方法来学习。
到目前为止,天空盒和立方体以及左右前后移动相机的功能都可以使用。然而,立方体没有被光照遮蔽,甚至没有显示为正确的颜色。从我的角度来看,我已经启用了我被告知要启用的所有内容并创建了一个光源等等,所以我很迷茫。
// ========================================================================
//
// ========================================================================
#include <iostream>
#include <GL/freeglut.h>
#include <cmath>
#include "loadTGA.h"
using namespace std;
#define GL_CLAMP_TO_EDGE 0x812F //To get rid of seams between textures
float theta = 0.0; //Camera rotation
float cdr=3.14159265/180.0; //Conversion from degrees to radians
float eye_x=0.0, eye_z=0.0;
float look_x=eye_x + 100*sin(cdr*theta);
float look_z=eye_z - 100*cos(cdr*theta);
GLuint texId[6];
void loadGLTextures() // Load bitmaps And Convert To Textures
{
glGenTextures(6, texId); // Create texture ids
// *** left ***
glBindTexture(GL_TEXTURE_2D, texId[0]);
loadTGA("alps_rt.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// *** front ***
glBindTexture(GL_TEXTURE_2D, texId[1]);
loadTGA("alps_ft.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// *** right ***
glBindTexture(GL_TEXTURE_2D, texId[2]);
loadTGA("alps_lf.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// *** back***
glBindTexture(GL_TEXTURE_2D, texId[3]);
loadTGA("alps_bk.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// *** top ***
glBindTexture(GL_TEXTURE_2D, texId[4]);
loadTGA("alps_up.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// *** down ***
glBindTexture(GL_TEXTURE_2D, texId[5]);
loadTGA("grass.tga");
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
}
//========================================================================================
void temple(){
glColor3f(0, 0, 0);
glPushMatrix();
glTranslatef(20, 10, 0);
glutSolidCube(1);
glPopMatrix();
}
void skybox(){
glEnable(GL_TEXTURE_2D);
////////////////////// LEFT WALL ///////////////////////
glBindTexture(GL_TEXTURE_2D, texId[0]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f(-10000, 0, 10000);
glTexCoord2f(1., 0.);
glVertex3f(-10000, 0., -10000);
glTexCoord2f(1., 1.);
glVertex3f(-10000, 10000., -10000);
glTexCoord2f(0., 1.);
glVertex3f(-10000, 10000, 10000);
glEnd();
////////////////////// FRONT WALL ///////////////////////
glBindTexture(GL_TEXTURE_2D, texId[1]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f(-10000, 0, -10000);
glTexCoord2f(1., 0.);
glVertex3f(10000, 0., -10000);
glTexCoord2f(1., 1.);
glVertex3f(10000, 10000, -10000);
glTexCoord2f(0., 1.);
glVertex3f(-10000, 10000, -10000);
glEnd();
////////////////////// RIGHT WALL ///////////////////////
glBindTexture(GL_TEXTURE_2D, texId[2]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f(10000, 0, -10000);
glTexCoord2f(1., 0.);
glVertex3f(10000, 0, 10000);
glTexCoord2f(1., 1.);
glVertex3f(10000, 10000, 10000);
glTexCoord2f(0., 1.);
glVertex3f(10000, 10000, -10000);
glEnd();
////////////////////// REAR WALL ////////////////////////
glBindTexture(GL_TEXTURE_2D, texId[3]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f( 10000, 0, 10000);
glTexCoord2f(1., 0.);
glVertex3f(-10000, 0, 10000);
glTexCoord2f(1., 1.);
glVertex3f(-10000, 10000, 10000);
glTexCoord2f(0., 1.);
glVertex3f( 10000, 10000, 10000);
glEnd();
/////////////////////// TOP //////////////////////////
glBindTexture(GL_TEXTURE_2D, texId[4]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f(-10000, 10000, -10000);
glTexCoord2f(1., 0.);
glVertex3f(10000, 10000, -10000);
glTexCoord2f(1., 1.);
glVertex3f(10000, 10000, 10000);
glTexCoord2f(0., 1.);
glVertex3f(-10000, 10000, 10000);
glEnd();
/////////////////////// FLOOR //////////////////////////
glBindTexture(GL_TEXTURE_2D, texId[5]);
glBegin(GL_QUADS);
glTexCoord2f(0., 0.);
glVertex3f(-10000, 0., 10000);
glTexCoord2f(100., 0.);
glVertex3f(10000, 0., 10000);
glTexCoord2f(100., 100.);
glVertex3f(10000, 0., -10000);
glTexCoord2f(0., 100.);
glVertex3f(-10000, 0., -10000);
glEnd();
}
//---------------------------------------------------------------------
void initialise(void)
{
float grey[4] = {0.2, 0.2, 0.2, 1.0};
float white[4] = {1.0, 1.0, 1.0, 1.0};
loadGLTextures();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, grey);
glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
glLightfv(GL_LIGHT0, GL_SPECULAR, white);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_NORMALIZE);
glClearColor (0.0, 0.0, 0.0, 0.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(90.0, 1.0, 1.0, 20000.0); //Perspective projection
}
//---------------------------------------------------------------------
void display(void)
{
float outsidelightpos[4] = {1.0f, 1.0f, 1.0f, 1.0f};
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt (eye_x, 10, eye_z, look_x, 10, look_z, 0, 1, 0); //camera rotation
glLightfv(GL_LIGHT0, GL_POSITION, outsidelightpos);
skybox();
temple();
glFlush();
}
//--------------------------------------------------------------
void special(int key, int x, int y)
{
if(key==GLUT_KEY_LEFT) theta-=5; //Turn left
else if(key==GLUT_KEY_RIGHT) theta+=5; //Turn right
else if(key == GLUT_KEY_DOWN)
{ //Move backward
eye_x -= 5*sin(cdr*theta);
eye_z += 5*cos(cdr*theta);
}
else if(key == GLUT_KEY_UP)
{ //Move forward
eye_x += 5*sin(cdr*theta);
eye_z -= 5*cos(cdr*theta);
}
look_x = eye_x + 100*sin(cdr*theta);
look_z = eye_z - 100*cos(cdr*theta);
glutPostRedisplay();
glutSwapBuffers();
}
//-------------------------------------------------------------------
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_DEPTH);
glutInitWindowSize (1024, 800);
glutInitWindowPosition (50, 50);
glutCreateWindow ("Alex Bull's Assignment");
initialise();
glutDisplayFunc(display);
glutSpecialFunc(special);
glutMainLoop();
return 0;
}
所以,你画了这个"temple"立方体
- 当纹理仍然打开时,你的天空盒的最后一个纹理仍然是绑定的。由于
glutSloidCube
不提供任何纹理坐标,因此将在所有地方使用相同的纹理坐标。您可以使用glDisable(GL_TEXTURE_2D)
来禁用它。 - 颜色为 (0,0,0) 而
glColorMaterial
设置为GL_AMBIENT_AND_DIFFUSE
,所以你基本上只会得到镜面光照 - 使用 GL 的固定功能,所以你只能得到 gouraud 阴影,而不会得到任何有用的镜面高光,因为光照只是在你的立方体的每个角顶点计算
所以,最后,你会得到一个蹩脚的镜面高光,由你的一些天空盒纹理的一些角纹素颜色调制,插值到你的立方体表面。
您应该注意到,您使用的几乎每一个 GL 函数 已弃用,因为 十年[=31] =] 现在。您的代码完全过时了,固定功能早已从 GPU 中消失了。如果你现在真的想学习 OpenGL,你不应该用 20 年前的方法来学习。