目前,我正在绘制一个大房间,而且一切都很好:
但是,它是蓝色的,所以我想,好吧,我先禁用照明,然后绘制房间,稍后再启用它,效果很好,对吧?
我想不是...它完全失去了它的“深度”。
我不能简单地做:
glDisable(GL_LIGHTING);
glColor3f(51/255.0, 25/255.0,0.0);
drawstuffhere
glEnable(GL_LIGHTING);
还是受初始照明设置的影响?
glClearColor(0.0,0.0,0.0,0.0);
glEnable(GL_DEPTH_TEST); //启用深度测试。
// Turn on OpenGL lighting.
glEnable(GL_LIGHTING);
// Light property vectors.
float lightAmb[] = { 0.0, 0.0, 0.0, 1.0 };
float lightDifAndSpec0[] = { 1.0, 1.0, 1.0, 1.0 };
float lightDifAndSpec1[] = { 1.0, 1.0, 0.0, 1.0 };
float globAmb[] = { 0.2, 0.2, 0.2, 1.0 };
// Light0 properties.
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDifAndSpec0);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightDifAndSpec0);
// Light1 properties.
glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDifAndSpec1);
glLightfv(GL_LIGHT1, GL_SPECULAR, lightDifAndSpec1);
glEnable(GL_LIGHT0); // Enable particular light source.
glEnable(GL_LIGHT1); // Enable particular light source.
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globAmb); // Global ambient light.
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); // Enable local viewpoint
// Cull back faces.
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
编辑:源代码:http://pastebin.com/DKGpWiFB
///////////////////////////////////////////////////////////////////////////////////////////
// main.cpp
//
///////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#ifdef __APPLE__
# include <GLUT/glut.h>
#else
# include <GL/glut.h>
#endif
using namespace std;
//Structures
struct perspectives {
float ex,ey,ez,cx,cy,cz;
int x, y, z;
};
struct coordinates {
float x, y, z;
};
// Globals.
static float a = .1; // Blue ambient reflectance.
static float d = 1.0; // Blue diffuse reflectance.
static float s = 1.0; // White specular reflectance.
static float h = 50.0; // Shininess.
static float e = 0.0; // Blue emittance.
static float t = 0.0; // Quadratic attenuation factor.
static float zMove = 0.0; // z-direction component.
static char theStringBuffer[10]; // String buffer.
static long font = (long)GLUT_BITMAP_8_BY_13; // Font selection.
static bool cameraRotate = false;
struct perspectives camera = {0,0,12,0,0,0,0,1,0};
struct coordinates key = {0,0,11};
// Routine to draw a bitmap character string.
void writeBitmapString(void *font, char *string)
{
char *c;
for (c = string; *c != '\0'; c++) glutBitmapCharacter(font, *c);
}
// Routine to convert floating point to char string.
void floatToString(char * destStr, int precision, float val)
{
sprintf(destStr,"%f",val);
destStr[precision] = '\0';
}
//Routine to draw a ball of light
void drawMoon()
{//TODO
// Light position vectors.
float lightPos[] = { 3, 4, -.2, 1.0 };
glDisable(GL_LIGHTING);
// Light0 and its sphere positioned.
glPushMatrix();
glLightfv(GL_LIGHT1, GL_POSITION, lightPos);
glTranslatef(lightPos[0], lightPos[1], lightPos[2]);
glColor3f(1.0, 1.0, 1.0);
glutSolidSphere(2, 20, 20);
glPopMatrix();
glEnable(GL_LIGHTING);
}
//Routine to draw starry sky
void drawStars()
{
//TODO
}
void drawPumpkin()
{
//TODO
}
void drawKey()
{
//TODO
}
//Routine to draw walls
void drawWalls()
{
//glDisable(GL_LIGHTING);
glColor3f(51/255.0,25/255.0,0);
glPushMatrix();
//glRotatef(0,0,0,1);
glScalef(1,1,3);
glBegin(GL_QUADS);
/* Floor */
glVertex3f(-1,-1,-1);
glVertex3f(-1,-1,1);
glVertex3f(1,-1,1);
glVertex3f(1,-1,-1);
/* Ceiling */
glVertex3f(-1,1,-1);
glVertex3f(1,1,-1);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
/* Walls */
/* front outer */
/* left half */
glVertex3f(-1,-1,1);
glVertex3f(-.45,-1,1);
glVertex3f(-.45,1,1);
glVertex3f(-1,1,1);
/* right half */
glVertex3f(.45,-1,1);
glVertex3f(1,-1,1);
glVertex3f(1,1,1);
glVertex3f(.45,1,1);
/* top half */
glVertex3f(-1,.5,1);
glVertex3f(1,.5,1);
glVertex3f(1,1,1);
glVertex3f(-1,1,1);
/* end front outer */
/* front door */
//TODO
/* end front door */
/* back inner */
/* left half */
glVertex3f(-1,-1,-1);
glVertex3f(-.45,-1,-1);
glVertex3f(-.45,1,-1);
glVertex3f(-1,1,-1);
/* right half */
glVertex3f(.45,-1,-1);
glVertex3f(1,-1,-1);
glVertex3f(1,1,-1);
glVertex3f(.45,1,-1);
/* top half */
glVertex3f(-1,.5,-1);
glVertex3f(1,.5,-1);
glVertex3f(1,1,-1);
glVertex3f(-1,1,-1);
/* end inner */
glVertex3f(1,1,1);
glVertex3f(1,1,-1);
glVertex3f(1,-1,-1);
glVertex3f(1,-1,1);
glVertex3f(-1,1,1);
glVertex3f(-1,-1,1);
glVertex3f(-1,-1,-1);
glVertex3f(-1,1,-1);
glEnd();
glPopMatrix();
//glEnable(GL_LIGHTING);
}
void drawLight()
{
// Light position vectors.
float lightPos0[] = { 0.0, .75, -.5, 1.0 };
glDisable(GL_LIGHTING);
// Light0 and its sphere positioned.
glPushMatrix();
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
glTranslatef(lightPos0[0], lightPos0[1], lightPos0[2]);
glColor3f(1.0, 1.0, 1.0);
glutWireSphere(0.05, 8, 8);
glPopMatrix();
glEnable(GL_LIGHTING);
}
// Initialization routine.
void setup(void)
{
//Set globals
a = 1- abs(camera.ez/15.0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST); // Enable depth testing.
// Turn on OpenGL lighting.
glEnable(GL_LIGHTING);
// Light property vectors.
float lightAmb[] = { 0.0, 0.0, 0.0, 1.0 };
float lightDifAndSpec0[] = { 1.0, 1.0, 1.0, 1.0 };
float lightDifAndSpec1[] = { 1.0, 1.0, 0.0, 1.0 };
float globAmb[] = { 0.2, 0.2, 0.2, 1.0 };
// Light0 properties.
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDifAndSpec0);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightDifAndSpec0);
// Light1 properties.
glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDifAndSpec1);
glLightfv(GL_LIGHT1, GL_SPECULAR, lightDifAndSpec1);
glEnable(GL_LIGHT0); // Enable particular light source.
glEnable(GL_LIGHT1); // Enable particular light source.
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globAmb); // Global ambient light.
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); // Enable local viewpoint
// Cull back faces.
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
// Drawing routine.
void drawScene()
{
// Material property vectors.
float matAmb[] = {0.0, 0.0, a, 1.0};
float matDif[] = {0.0, 0.0, d, 1.0};
float matSpec[] = { s, s, s, 1.0 };
float matShine[] = { h };
float matEmission[] = {0.0, 0.0, e, 1.0};
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// Light quadratic attenuation factor.
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, t);
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, t);
//gluLookAt(0.0, ey, ez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
gluLookAt(camera.ex,camera.ey, camera.ez,
camera.cx,camera.cy,camera.cz,
camera.x,camera.y,camera.z);
//gluLookAt(0,0,0,0,0,0,0,1,0);
// Draw light source spheres after disabling lighting.
drawLight();
// Material properties of sphere.
glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, matDif);
glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);
glMaterialfv(GL_FRONT, GL_SHININESS, matShine);
glMaterialfv(GL_FRONT, GL_EMISSION, matEmission);
// Sphere.
glTranslatef(0.0, 0.0, zMove); // Move the sphere.
//glutSolidCube(1.5);
drawWalls();
drawMoon();
glutSwapBuffers();
}
// OpenGL window reshape routine.
void resize (int w, int h)
{
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (float)w/(float)h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
int mod = glutGetModifiers();
if (mod!=0)
{
switch(mod)
{
//Shift key
case 1 : cameraRotate=true; break;
//ALT key
case 4 : ; break;
mod = 0;
}
}
switch (key)
{
case 27:
exit(0);
break;
case 'a':
if (a > 0.0) a -= 0.05;
glutPostRedisplay();
break;
case 'A':
if (a < 1.0) a += 0.05;
glutPostRedisplay();
break;
case 'd':
if (d > 0.0) d -= 0.05;
glutPostRedisplay();
break;
case 'D':
if (d < 1.0) d += 0.05;
glutPostRedisplay();
break;
case 's':
if (s > 0.0) s -= 0.05;
glutPostRedisplay();
break;
case 'S':
if (s < 1.0) s += 0.05;
glutPostRedisplay();
break;
case 'e':
if (e > 0.0) e -= 0.05;
glutPostRedisplay();
break;
case 'E':
if (e < 1.0) e += 0.05;
glutPostRedisplay();
break;
case 'h':
if (h > 0.0) h -= 1.0;
glutPostRedisplay();
break;
case 'H':
if (h < 128.0) h += 1.0;
glutPostRedisplay();
break;
case 't':
if (t > 0.0) t -= 0.005;
glutPostRedisplay();
break;
case 'T':
t += 0.005;
glutPostRedisplay();
break;
default:
break;
}
}
// Callback routine for non-ASCII key entry.
void specialKeyInput(int key, int x, int y)
{
if (key == GLUT_KEY_UP){
if(camera.ez - .1 >= 0)
{camera.ez += -0.1;
camera.ex += 0;}
}
if (key == GLUT_KEY_DOWN){
camera.ez += 0.1;
camera.ex += 0;
}
if (key == GLUT_KEY_LEFT){
camera.cx -= .1;
}
if (key == GLUT_KEY_RIGHT){
camera.cx += .1;
}
printf("This is my ez %f\n", camera.ez);
a = 1- abs(camera.ez/5.0);
glutPostRedisplay();
}
// Routine to output interaction instructions to the C++ window.
void printInteraction(void)
{
}
// Main routine.
int main(int argc, char **argv)
{
printInteraction();
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (600, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow ("scaryRoom.cpp");
setup();
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(keyInput);
glutSpecialFunc(specialKeyInput);
glutMainLoop();
return 0;
}
最佳答案
OpenGL是基于状态的绘图API。一旦绘制了一些东西,OpenGL就不会记住它。一切都在绘制时发生,如果在绘制时没有照明设置,就是这样。
我不知道你的房间为什么变成蓝色。我必须查看完整的代码。但是,我可以为您提供建议,即您不应尝试在特定时间“初始化”事物,然后再进行“实践”。 OpenGL是一种状态机,意味着可以在您真正需要它之前就设置所有重要的属性。因此,我建议您将照明和颜色设置移到尽可能接近实际图形的位置。
更新资料
您正在drawScene
函数中设置材料状态。这些将影响设置这些状态后绘制的所有内容,直到您更改它们为止。您希望它们仅影响球体,但也会影响其他东西。请注意,除非启用并设置所谓的色料状态,否则glColor
不会对照明的图形产生影响。
但是,我强烈建议您完全不要去使用神秘的固定功能管道。您已经遇到了一些陷阱:)我建议您学习现代的OpenGL,它还可以避免所有这些奇怪的特性。很好的教程可以在http://arcsynthesis.org/gltut上找到
关于c++ - 禁用照明的OpenGL绘图失去了“深度”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19744869/