OpenGL diffuse/specular 光不在多边形上渲染(仅环境光)
OpenGL diffuse/specular light not rendering (only ambient) on polygons
我已经尽我所能设置了照明,但所有呈现的都是环境照明。它似乎适用于 glutSolidSphere 和 glutSolidCube 等内置形状,但不适用于我手动编码的多边形。
我花了几个小时查看教程和 Whosebug,但无法自行解决。
我错过了什么?我正在使用 Netbeans (Windows)、C++、FreeGlut。
图片:3D Airplane
#include <GL/glut.h>
#include <GL/glext.h>
GLfloat pos0 [] = {0,1,0,0},
white[] = {1,1,1};
void render(){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glNormal3f(0,1,0);
glScaled(4,4,4);
glRotated(30,1,0,0);
glRotated(60,0,1,0);
glRotated(10,0,0,-1);
glTranslated(0,0,-.2);
glBegin(GL_QUADS);
#define V glVertex3f
// body
glColor3f(.7,.5,.3);
V(0, 0, 0); V( 1,.06,.05); V( 1,.10,.05); V(0, .15, 0);
V(0, 0, 0); V( 1,.06,.05); V( 1,.05,.10); V(0,-.03,.1);
V(0,-.03,.1); V( 1,.05,.10); V( 1,.06,.15); V(0, 0,.2);
V(0, 0,.2); V( 1,.06,.15); V( 1,.10,.15); V(0, .15,.2);
V(0, .15,.2); V( 1,.10,.15); V( 1,.11,.10); V(0, .17,.1);
V(0, .17,.1); V( 1,.11,.10); V( 1,.10,.05); V(0, .15, 0);
V(0, 0, 0); V(-.5,.03,.07); V(-.5,.06,.07); V(0, .15, 0);
V(0, 0, 0); V(-.5,.03,.07); V(-.5,.02,.10); V(0,-.03,.1);
V(0,-.03,.1); V(-.5,.02,.10); V(-.5,.03,.13); V(0, 0,.2);
V(0, 0,.2); V(-.5,.03,.13); V(-.5,.06,.13); V(0, .15,.2);
V(0, .15,.2); V(-.5,.06,.13); V(-.5,.07,.10); V(0, .17,.1);
V(0, .17,.1); V(-.5,.07,.10); V(-.5,.06,.07); V(0, .15, 0);
// wings
glColor3f(.5,.5,.5);
V(-.1,.06, .1); V(.3,.06, .1); V(.4,.10, .7); V( .2,.10, .7);
V(-.1,.10, .1); V(.3,.10, .1); V(.4,.11, .7); V( .2,.11, .7);
V(-.1,.06, .1); V(.2,.10, .7); V(.2,.11, .7); V(-.1,.10, .1);
V( .3,.06, .1); V(.4,.10, .7); V(.3,.10, .1); V( .4,.11, .7);
V( .4,.10, .7); V(.2,.10, .7); V(.4,.11, .7); V( .2,.11, .7);
V(-.1,.06, .1); V(.3,.06, .1); V(.4,.10,-.5); V( .2,.10,-.5);
V(-.1,.10, .1); V(.3,.10, .1); V(.4,.11,-.5); V( .2,.11,-.5);
V(-.1,.06, .1); V(.2,.10,-.5); V(.2,.11,-.5); V(-.1,.10, .1);
V( .3,.06, .1); V(.4,.10,-.5); V(.3,.10, .1); V( .4,.11,-.5);
V( .4,.10,-.5); V(.2,.10,-.5); V(.4,.11,-.5); V( .2,.11,-.5);
// tail
V(.6,.06, .10); V(.8,.06, .10); V(.9,.10, .40); V(.8,.10, .40);
V(.6,.10, .10); V(.8,.10, .10); V(.9,.11, .40); V(.8,.11, .40);
V(.6,.06, .10); V(.8,.10, .40); V(.8,.11, .40); V(.6,.10, .10);
V(.8,.06, .10); V(.9,.10, .40); V(.9,.11, .40); V(.8,.10, .10);
V(.9,.10, .40); V(.8,.10, .40); V(.8,.11, .40); V(.9,.11, .40);
V(.6,.06, .10); V(.8,.06, .10); V(.9,.10,-.20); V(.8,.10,-.20);
V(.6,.10, .10); V(.8,.10, .10); V(.9,.11,-.20); V(.8,.11,-.20);
V(.6,.06, .10); V(.8,.10,-.20); V(.8,.11,-.20); V(.6,.10, .10);
V(.8,.06, .10); V(.9,.10,-.20); V(.9,.11,-.20); V(.8,.10, .10);
V(.9,.10,-.20); V(.8,.10,-.20); V(.8,.11,-.20); V(.9,.11,-.20);
V(.7,.10, .09); V(.9,.10, .09); V( 1,.30, .09); V(.9,.30, .09);
V(.7,.10, .11); V(.9,.10, .11); V( 1,.30, .11); V(.9,.30, .11);
V(.7,.10, .09); V(.9,.30, .09); V(.9,.10, .11); V(.7,.10, .11);
V(.9,.10, .09); V( 1,.30, .09); V( 1,.30, .11); V(.9,.10, .11);
V( 1,.30, .09); V(.9,.30, .09); V(.9,.30, .11); V( 1,.30, .11);
glEnd();
glFlush();
}
int main(int argc,char** argv){
// setup window
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH|GLUT_MULTISAMPLE);
glutInitWindowSize(800,600);
glutCreateWindow("3D Airplane");
glClearColor(0,0,0,1);
// setup perspective
glMatrixMode(GL_PROJECTION);
glFrustum(-2,2, -1.5,1.5, 3,25);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0,0,4, 0,0,0, 0,1,0);
glViewport(0,0,800,600);
glEnable(GL_DEPTH_TEST);
// setup lighting
glLightfv(GL_LIGHT0,GL_POSITION,pos0 );
glLightfv(GL_LIGHT0,GL_DIFFUSE ,white);
glEnable (GL_LIGHT0);
glEnable (GL_LIGHTING);
glEnable (GL_COLOR_MATERIAL);
glutDisplayFunc(render);
glutMainLoop();
}
编辑:我编写了一个名为 calcNormal 的法线计算函数,并将我的 glVertex 调用转换为四边形顶点数组...
GLfloat* calcNormal(GLfloat* a,GLfloat* b,GLfloat* c){
// define target plane
GLfloat u[] = {b[0]-a[0], b[1]-a[1], b[2]-a[2]};
GLfloat v[] = {c[0]-a[0], c[1]-a[1], c[2]-a[2]};
// calculate cross product
static GLfloat cp[] = { u[1]*v[2] - u[2]*v[1],
u[2]*v[0] - u[0]*v[2],
u[0]*v[1] - u[1]*v[0] };
// normalize
GLfloat length = sqrt(cp[0]*cp[0] + cp[1]*cp[1] + cp[2]*cp[2]);
for(int i=0;i<3;i++) cp[i] /= length;
return cp;
}
render(){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(.7,.5,.3);
glPushMatrix();
glScaled(3,3,3);
glRotated(30,1,0,0);
glRotated(60,0,1,0);
glRotated(10,0,0,-1);
glTranslatef(x,y,z);
for(GLint* quad:planeQuads){
#define PV planeVertices
glNormal3fv(calcNormal(PV[quad[0]],PV[quad[1]],PV[quad[2]]));
glBegin(GL_QUADS);
glVertex3fv(PV[quad[0]]);
glVertex3fv(PV[quad[1]]);
glVertex3fv(PV[quad[2]]);
glVertex3fv(PV[quad[3]]);
glEnd();
}
glPopMatrix();
glFlush();
}
...但它仍然没有渲染漫射光,即使我现在为每个多边形设置 glNormal。
我的 poly/vertex 结构现在看起来像这样:
// polygon arrays
GLint planeQuads[37][4] = {
{ 9,15,17,11}, { 9,15,14, 8}, { 8,14,16,10}, {10,16,18,12}, {12,18,19,13}, {13,19,17,11}, // rear body
{ 9, 1, 3,11}, { 9, 1, 0, 8}, { 8, 0, 2,10}, {10, 2, 4,12}, {12, 4, 5,13}, {13, 5, 3,11}, // front body
{ 6,17,20,14}, { 7,19,22,16}, { 6,14,16, 7}, {17,20,19,22}, {20,14,22,16}, // left wing
{ 6,17,23,18}, { 7,19,21,15}, { 6,18,17, 7}, {17,23,19,21}, {23,18,21,15}, // right wing
{24,28,37,31}, {25,30,39,33}, {24,31,33,25}, {28,37,39,30}, {37,31,33,39}, // left fin
{24,28,34,29}, {25,30,38,32}, {24,29,32,25}, {28,34,38,30}, {34,29,32,38}, // right fin
{26,35,48,40}, {27,36,49,41}, {26,40,36,27}, {35,48,49,36}, {48,40,41,49} // tail
};
// vertex arrays
GLfloat planeVertices[50][3] = {
{-.5,0.02,0.10}, {-.5,0.03,0.07}, {-.5,0.03,0.13}, {-.5,0.06,0.07}, {-.5,0.06,0.13},
{-.5,0.07,0.10}, {-.1,0.06,0.10}, {-.1,0.10,0.10}, {0.0,-.03,0.10}, {0.0,0.00,0.00},
{0.0,0.00,0.20}, {0.0,0.15,0.00}, {0.0,0.15,0.20}, {0.0,0.17,0.10}, {0.2,0.10,-.50},
{0.2,0.10,0.70}, {0.2,0.11,-.50}, {0.2,0.11,0.70}, {0.3,0.06,0.10}, {0.3,0.10,0.10},
{0.4,0.10,-.50}, {0.4,0.10,0.70}, {0.4,0.11,-.50}, {0.4,0.11,0.70}, {0.6,0.06,0.10},
{0.6,0.10,0.10}, {0.7,0.10,0.09}, {0.7,0.10,0.11}, {0.8,0.06,0.10}, {0.8,0.10,-.20},
{0.8,0.10,0.10}, {0.8,0.10,0.40}, {0.8,0.11,-.20}, {0.8,0.11,0.40}, {0.9,0.10,-.20},
{0.9,0.10,0.09}, {0.9,0.10,0.11}, {0.9,0.10,0.40}, {0.9,0.11,-.20}, {0.9,0.11,0.40},
{0.9,0.30,0.09}, {0.9,0.30,0.11}, {1.0,0.05,0.10}, {1.0,0.06,0.05}, {1.0,0.06,0.15},
{1.0,0.10,0.05}, {1.0,0.10,0.15}, {1.0,0.11,0.10}, {1.0,0.30,0.09}, {1.0,0.30,0.11}
};
如果将唯一的法向量形式 glNormal3f(0,1,0)
更改为 glNormal3f(0,-1,0)
,这会使场景变暗,您可以看到您的设置总体上有效。
但是,您必须设置垂直于几何体的面(甚至顶点)的法向量。所以你必须为每个面或顶点坐标设置一个法向量。
漫射光是通过Dot product的光向量和mesh的法向量属性计算出来的。对于定向光,整个场景的光向量是相同的。如果法向量对于整个几何体是恒定的,那么点积的结果对于整个几何体也是恒定的,因此光也是。
另见 GLSL fixed function fragment program replacement
您的代码中存在一个基本错误。静态变量只初始化一次:
static GLfloat cp[] = { u[1]*v[2] - u[2]*v[1],
u[2]*v[0] - u[0]*v[2],
u[0]*v[1] - u[1]*v[0] };
每次调用函数时都必须为变量赋值:
static GLfloat cp[3];
cp[0] = u[1]*v[2] - u[2]*v[1];
cp[1] = u[2]*v[0] - u[0]*v[2];
cp[2] = u[0]*v[1] - u[1]*v[0];
计算法向量时,必须确保法向量指向网格外。
反转法向量以查看向量的方向如何影响光线。
GLfloat* calcNormal(GLfloat* a,GLfloat* b,GLfloat* c){
// define target plane
GLfloat u[] = {b[0]-a[0], b[1]-a[1], b[2]-a[2]};
GLfloat v[] = {c[0]-a[0], c[1]-a[1], c[2]-a[2]};
// calculate cross product
static GLfloat cp[3];
cp[0] = u[1]*v[2] - u[2]*v[1];
cp[1] = u[2]*v[0] - u[0]*v[2];
cp[2] = u[0]*v[1] - u[1]*v[0];
// normalize
GLfloat length = sqrt(cp[0]*cp[0] + cp[1]*cp[1] + cp[2]*cp[2]);
for(int i=0;i<3;i++) cp[i] /= -length; // <- invert the normal vector
return cp;
}
由于法向量是通过三角形图元两条边的叉积计算的,法向量的方向取决于图元的缠绕顺序。这意味着所有基元的缠绕顺序必须相同。
如果缠绕顺序不同,这意味着一些原语是顺时针的而另一些是逆时针的,那么你可以尝试通过设置来补偿这个(参见glLightModel
)
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
在这种情况下,正面和背面的 material 参数必须相等。 (参见 glMaterial
)。
我已经尽我所能设置了照明,但所有呈现的都是环境照明。它似乎适用于 glutSolidSphere 和 glutSolidCube 等内置形状,但不适用于我手动编码的多边形。
我花了几个小时查看教程和 Whosebug,但无法自行解决。
我错过了什么?我正在使用 Netbeans (Windows)、C++、FreeGlut。
图片:3D Airplane
#include <GL/glut.h>
#include <GL/glext.h>
GLfloat pos0 [] = {0,1,0,0},
white[] = {1,1,1};
void render(){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glNormal3f(0,1,0);
glScaled(4,4,4);
glRotated(30,1,0,0);
glRotated(60,0,1,0);
glRotated(10,0,0,-1);
glTranslated(0,0,-.2);
glBegin(GL_QUADS);
#define V glVertex3f
// body
glColor3f(.7,.5,.3);
V(0, 0, 0); V( 1,.06,.05); V( 1,.10,.05); V(0, .15, 0);
V(0, 0, 0); V( 1,.06,.05); V( 1,.05,.10); V(0,-.03,.1);
V(0,-.03,.1); V( 1,.05,.10); V( 1,.06,.15); V(0, 0,.2);
V(0, 0,.2); V( 1,.06,.15); V( 1,.10,.15); V(0, .15,.2);
V(0, .15,.2); V( 1,.10,.15); V( 1,.11,.10); V(0, .17,.1);
V(0, .17,.1); V( 1,.11,.10); V( 1,.10,.05); V(0, .15, 0);
V(0, 0, 0); V(-.5,.03,.07); V(-.5,.06,.07); V(0, .15, 0);
V(0, 0, 0); V(-.5,.03,.07); V(-.5,.02,.10); V(0,-.03,.1);
V(0,-.03,.1); V(-.5,.02,.10); V(-.5,.03,.13); V(0, 0,.2);
V(0, 0,.2); V(-.5,.03,.13); V(-.5,.06,.13); V(0, .15,.2);
V(0, .15,.2); V(-.5,.06,.13); V(-.5,.07,.10); V(0, .17,.1);
V(0, .17,.1); V(-.5,.07,.10); V(-.5,.06,.07); V(0, .15, 0);
// wings
glColor3f(.5,.5,.5);
V(-.1,.06, .1); V(.3,.06, .1); V(.4,.10, .7); V( .2,.10, .7);
V(-.1,.10, .1); V(.3,.10, .1); V(.4,.11, .7); V( .2,.11, .7);
V(-.1,.06, .1); V(.2,.10, .7); V(.2,.11, .7); V(-.1,.10, .1);
V( .3,.06, .1); V(.4,.10, .7); V(.3,.10, .1); V( .4,.11, .7);
V( .4,.10, .7); V(.2,.10, .7); V(.4,.11, .7); V( .2,.11, .7);
V(-.1,.06, .1); V(.3,.06, .1); V(.4,.10,-.5); V( .2,.10,-.5);
V(-.1,.10, .1); V(.3,.10, .1); V(.4,.11,-.5); V( .2,.11,-.5);
V(-.1,.06, .1); V(.2,.10,-.5); V(.2,.11,-.5); V(-.1,.10, .1);
V( .3,.06, .1); V(.4,.10,-.5); V(.3,.10, .1); V( .4,.11,-.5);
V( .4,.10,-.5); V(.2,.10,-.5); V(.4,.11,-.5); V( .2,.11,-.5);
// tail
V(.6,.06, .10); V(.8,.06, .10); V(.9,.10, .40); V(.8,.10, .40);
V(.6,.10, .10); V(.8,.10, .10); V(.9,.11, .40); V(.8,.11, .40);
V(.6,.06, .10); V(.8,.10, .40); V(.8,.11, .40); V(.6,.10, .10);
V(.8,.06, .10); V(.9,.10, .40); V(.9,.11, .40); V(.8,.10, .10);
V(.9,.10, .40); V(.8,.10, .40); V(.8,.11, .40); V(.9,.11, .40);
V(.6,.06, .10); V(.8,.06, .10); V(.9,.10,-.20); V(.8,.10,-.20);
V(.6,.10, .10); V(.8,.10, .10); V(.9,.11,-.20); V(.8,.11,-.20);
V(.6,.06, .10); V(.8,.10,-.20); V(.8,.11,-.20); V(.6,.10, .10);
V(.8,.06, .10); V(.9,.10,-.20); V(.9,.11,-.20); V(.8,.10, .10);
V(.9,.10,-.20); V(.8,.10,-.20); V(.8,.11,-.20); V(.9,.11,-.20);
V(.7,.10, .09); V(.9,.10, .09); V( 1,.30, .09); V(.9,.30, .09);
V(.7,.10, .11); V(.9,.10, .11); V( 1,.30, .11); V(.9,.30, .11);
V(.7,.10, .09); V(.9,.30, .09); V(.9,.10, .11); V(.7,.10, .11);
V(.9,.10, .09); V( 1,.30, .09); V( 1,.30, .11); V(.9,.10, .11);
V( 1,.30, .09); V(.9,.30, .09); V(.9,.30, .11); V( 1,.30, .11);
glEnd();
glFlush();
}
int main(int argc,char** argv){
// setup window
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH|GLUT_MULTISAMPLE);
glutInitWindowSize(800,600);
glutCreateWindow("3D Airplane");
glClearColor(0,0,0,1);
// setup perspective
glMatrixMode(GL_PROJECTION);
glFrustum(-2,2, -1.5,1.5, 3,25);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0,0,4, 0,0,0, 0,1,0);
glViewport(0,0,800,600);
glEnable(GL_DEPTH_TEST);
// setup lighting
glLightfv(GL_LIGHT0,GL_POSITION,pos0 );
glLightfv(GL_LIGHT0,GL_DIFFUSE ,white);
glEnable (GL_LIGHT0);
glEnable (GL_LIGHTING);
glEnable (GL_COLOR_MATERIAL);
glutDisplayFunc(render);
glutMainLoop();
}
编辑:我编写了一个名为 calcNormal 的法线计算函数,并将我的 glVertex 调用转换为四边形顶点数组...
GLfloat* calcNormal(GLfloat* a,GLfloat* b,GLfloat* c){
// define target plane
GLfloat u[] = {b[0]-a[0], b[1]-a[1], b[2]-a[2]};
GLfloat v[] = {c[0]-a[0], c[1]-a[1], c[2]-a[2]};
// calculate cross product
static GLfloat cp[] = { u[1]*v[2] - u[2]*v[1],
u[2]*v[0] - u[0]*v[2],
u[0]*v[1] - u[1]*v[0] };
// normalize
GLfloat length = sqrt(cp[0]*cp[0] + cp[1]*cp[1] + cp[2]*cp[2]);
for(int i=0;i<3;i++) cp[i] /= length;
return cp;
}
render(){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(.7,.5,.3);
glPushMatrix();
glScaled(3,3,3);
glRotated(30,1,0,0);
glRotated(60,0,1,0);
glRotated(10,0,0,-1);
glTranslatef(x,y,z);
for(GLint* quad:planeQuads){
#define PV planeVertices
glNormal3fv(calcNormal(PV[quad[0]],PV[quad[1]],PV[quad[2]]));
glBegin(GL_QUADS);
glVertex3fv(PV[quad[0]]);
glVertex3fv(PV[quad[1]]);
glVertex3fv(PV[quad[2]]);
glVertex3fv(PV[quad[3]]);
glEnd();
}
glPopMatrix();
glFlush();
}
...但它仍然没有渲染漫射光,即使我现在为每个多边形设置 glNormal。
我的 poly/vertex 结构现在看起来像这样:
// polygon arrays
GLint planeQuads[37][4] = {
{ 9,15,17,11}, { 9,15,14, 8}, { 8,14,16,10}, {10,16,18,12}, {12,18,19,13}, {13,19,17,11}, // rear body
{ 9, 1, 3,11}, { 9, 1, 0, 8}, { 8, 0, 2,10}, {10, 2, 4,12}, {12, 4, 5,13}, {13, 5, 3,11}, // front body
{ 6,17,20,14}, { 7,19,22,16}, { 6,14,16, 7}, {17,20,19,22}, {20,14,22,16}, // left wing
{ 6,17,23,18}, { 7,19,21,15}, { 6,18,17, 7}, {17,23,19,21}, {23,18,21,15}, // right wing
{24,28,37,31}, {25,30,39,33}, {24,31,33,25}, {28,37,39,30}, {37,31,33,39}, // left fin
{24,28,34,29}, {25,30,38,32}, {24,29,32,25}, {28,34,38,30}, {34,29,32,38}, // right fin
{26,35,48,40}, {27,36,49,41}, {26,40,36,27}, {35,48,49,36}, {48,40,41,49} // tail
};
// vertex arrays
GLfloat planeVertices[50][3] = {
{-.5,0.02,0.10}, {-.5,0.03,0.07}, {-.5,0.03,0.13}, {-.5,0.06,0.07}, {-.5,0.06,0.13},
{-.5,0.07,0.10}, {-.1,0.06,0.10}, {-.1,0.10,0.10}, {0.0,-.03,0.10}, {0.0,0.00,0.00},
{0.0,0.00,0.20}, {0.0,0.15,0.00}, {0.0,0.15,0.20}, {0.0,0.17,0.10}, {0.2,0.10,-.50},
{0.2,0.10,0.70}, {0.2,0.11,-.50}, {0.2,0.11,0.70}, {0.3,0.06,0.10}, {0.3,0.10,0.10},
{0.4,0.10,-.50}, {0.4,0.10,0.70}, {0.4,0.11,-.50}, {0.4,0.11,0.70}, {0.6,0.06,0.10},
{0.6,0.10,0.10}, {0.7,0.10,0.09}, {0.7,0.10,0.11}, {0.8,0.06,0.10}, {0.8,0.10,-.20},
{0.8,0.10,0.10}, {0.8,0.10,0.40}, {0.8,0.11,-.20}, {0.8,0.11,0.40}, {0.9,0.10,-.20},
{0.9,0.10,0.09}, {0.9,0.10,0.11}, {0.9,0.10,0.40}, {0.9,0.11,-.20}, {0.9,0.11,0.40},
{0.9,0.30,0.09}, {0.9,0.30,0.11}, {1.0,0.05,0.10}, {1.0,0.06,0.05}, {1.0,0.06,0.15},
{1.0,0.10,0.05}, {1.0,0.10,0.15}, {1.0,0.11,0.10}, {1.0,0.30,0.09}, {1.0,0.30,0.11}
};
如果将唯一的法向量形式 glNormal3f(0,1,0)
更改为 glNormal3f(0,-1,0)
,这会使场景变暗,您可以看到您的设置总体上有效。
但是,您必须设置垂直于几何体的面(甚至顶点)的法向量。所以你必须为每个面或顶点坐标设置一个法向量。
漫射光是通过Dot product的光向量和mesh的法向量属性计算出来的。对于定向光,整个场景的光向量是相同的。如果法向量对于整个几何体是恒定的,那么点积的结果对于整个几何体也是恒定的,因此光也是。
另见 GLSL fixed function fragment program replacement
您的代码中存在一个基本错误。静态变量只初始化一次:
static GLfloat cp[] = { u[1]*v[2] - u[2]*v[1], u[2]*v[0] - u[0]*v[2], u[0]*v[1] - u[1]*v[0] };
每次调用函数时都必须为变量赋值:
static GLfloat cp[3];
cp[0] = u[1]*v[2] - u[2]*v[1];
cp[1] = u[2]*v[0] - u[0]*v[2];
cp[2] = u[0]*v[1] - u[1]*v[0];
计算法向量时,必须确保法向量指向网格外。 反转法向量以查看向量的方向如何影响光线。
GLfloat* calcNormal(GLfloat* a,GLfloat* b,GLfloat* c){
// define target plane
GLfloat u[] = {b[0]-a[0], b[1]-a[1], b[2]-a[2]};
GLfloat v[] = {c[0]-a[0], c[1]-a[1], c[2]-a[2]};
// calculate cross product
static GLfloat cp[3];
cp[0] = u[1]*v[2] - u[2]*v[1];
cp[1] = u[2]*v[0] - u[0]*v[2];
cp[2] = u[0]*v[1] - u[1]*v[0];
// normalize
GLfloat length = sqrt(cp[0]*cp[0] + cp[1]*cp[1] + cp[2]*cp[2]);
for(int i=0;i<3;i++) cp[i] /= -length; // <- invert the normal vector
return cp;
}
由于法向量是通过三角形图元两条边的叉积计算的,法向量的方向取决于图元的缠绕顺序。这意味着所有基元的缠绕顺序必须相同。
如果缠绕顺序不同,这意味着一些原语是顺时针的而另一些是逆时针的,那么你可以尝试通过设置来补偿这个(参见glLightModel
)
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
在这种情况下,正面和背面的 material 参数必须相等。 (参见 glMaterial
)。