声明:
由于之前看了opengl编程基础第三版的中文版,遇到很多无关紧要的勘误,其中也有少数致命的错误.浪费了一些时间.所以把自己遇到的错误都帖出来,给后来者作为参考之用.
不保证我觉得是错误的就一定是错误的,很可能是历史原因造成,也可能是方法不同,看到的人还请辩证看待.同时希望发现我错了的或者发现了本书其他错误的朋友能不惜吝啬提出来.
以下为内容:
从第四章开始.
1.P80(4.3观察一个立方体)
函数void display()最后一行用到glutSwapBuffers();但是函数void main(int argc,char**argv)中初始化为glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
改:glFlush();
或者把初始化改为:GLUT_DOUBLE
2.P85(4.5.1数组的使用)
底部函数void polygon(int a,int b,int c,int d)用到了函数glVertex3f(vertices[*]);
参数是数组
改:所以应该是glVertex3fv(vertices[*]);
3.P87(4.5.2顶点数组)
位置;
for(i =0 ;i<6;i++)
glDrawElements(GL_POLYGON,4,GL_UNSIGNED_BYTE,cubeIndices);
错误内容:cubeIndices:这是一个永远指向数组第一个元素的指针
改:glDrawElements(GL_POLYGON,4,GL_UNSIGNED_BYTE,(cubeIndices+4*i));
4.P130(6.6旋转立方体的明暗计算)
位置:
我们将法线信息存放在一个数组中:
GLfloat normals[][3] = {{0.0,0.0,-1.0},{0.0,1.0,0.0},
{-1.0,0.0,0.0},{1.0,0.0,0.0},
{0.0,0.0,1.0},{0.0,-1.0,0.0}};
错误内容:根据P85图4.7立方体各顶点的编号的立方体模型,我们可以知道法线数组顺序有问题.
改:
GLfloat normals[][3] =
{
{0.0,0.0,1.0},{1.0,0.0,0.0},
{0.0,-1.0,0.0},{0.0,1.0,0.0},
{0.0,0.0,-1.0},{-1.0,0.0,0.0}
};
5.P138(6.10透明度)
位置:函数
void polygon(int a,int b,int c,int d)
{
glColor4fv(color[a]);
if(color[a][4]!=1.0)
....
}
错误:color[a][4]
改:color[a][3]
6.P144(7.2.1位图的显示)
位置:GLubyte wb[2] = 0x00,0xff;
改:GLubyte wb[2] = {0x00,0xff};
7.P157(7.7PPM图像的显示)
位置:所有的fscanf(fd,"%[^\n]",b);
说明:中文版有勘误,源代码是没有问题的.
修正为:
fscanf(fd,"%[^\n] ",b);//异地你敢咬注意后引号之前的哪个空格,可以忽略掉'\n'
其他方法:
fscanf(fd,"%c",&c);之前加:while(c=='\n')fscanf(fd,"%c",&c);
或者:
将fscanf(fd,"%[^\n]",b);改为fscanf(fd,"%[^\n]%*",b);
8.P161(7.7PPM图像的显示)位置:函数int main(int argc,char* argv)中
image = malloc(3*sizeof(Gluint)*nm);
说明:书和代码这里都有问题
改:
image = (GLuint*)malloc(3*sizeof(GLuint)*nm);
9.P162(7.7PPM图像的显示)
位置:
glPixelTransferf(GL_BLUE_SCALE,s);
glClearColor(1.0,1.0,1.0,1.0);
说明:没有正确显示图象
改:
glPixelTransferf(GL_BLUE_SCALE,s);
glPixel(Storei(GL_UPACK_SWAP_BYTES,GL_TRUE);
glClearColor(1.0,1.0,1.0,1.0);
10.P164(7.10像素的缩放)
位置:
for(i=0;i<nm;i++)
{
fscanf(fd,"%d %d %d",&red,&green,&blue);
image[3*i] = red;
image[3*i +1] = green;
image[3*1 +2]= blue;
}
改为:
for(i=0;i<nm;i++)
{
fscanf(fd,"%d %d %d",&red,&green,&blue);
image[3*1] = red;
image[3*1 +1] = green;
image[3*i +2]= blue;
}
11.P165(7.10像素的缩放)
位置:
该函数将接收一副winXhout的图像imagein,....,类型为type,...
改为:该函数将接收一副winXhin的图像imagein,....,类型为typein,...
12.P185(8.9纹理坐标的自动生成)
位置:
所以,对于上例,我们应该进行如下的四次函数调用:
GLfloat planes[] = [0.5,0.0,0.0,0.5};
GLfloat planes[] = {0.0,0.5,0.0,0.5};
...
(下面的文字说明)
就可以如图8.6(c)...的圆柱体..
改:
GLfloat planes[] = [0.5,0.0,0.0,0.5};
GLfloat planet[] = {0.0,0.5,0.0,0.5};
...
(下面的文字说明)
就可以如图8.6(c)...的圆锥体..
13.P227(10.5建立与应用程序之间的接口)
位置:
GLuint myVertexObj ,myFragObj;
...
myFragObj=glCreate(GL_FRAGMENT_SHADER);
改:
myFragObj=glCreateShader(GL_FRAGMENT_SHADER);
14.P228(10.5.2着色器的读取和编译)
位置:
glShaderSource(myVertexObj,1,vSource,NULL);
glShaderSource(myVertexObj,1,fSource,NULL);
改:
glShaderSource(myVertexObj,1,&vSource,NULL);
glShaderSource(myFragObj,1,&fSource,NULL);//glShaderSource(GLuint obj,...,const GLchar **source,...)
15.P229(10.5.4错误检查)
位置:
如果返回的状态值非零,则表明发生了一个错误,此时我们可以从应用程序退出
改:
如果返回的状态值为零,则表明发生了一个错误,此时我们可以从应用程序退出
说明:
其实可以直接用函数判断错误是什么:
比如如下代码:
glCompileShader(myVertexObj);
//4.1编译的错误检查,返回非0,则发生了错误
glGetShaderiv(myVertexObj, GL_COMPILE_STATUS, &status);
if (status == 0)
{
GLchar shaderlog[1024];
printf("VertexShader compile failed!\n");
glGetShaderInfoLog(myVertexObj, sizeof(shaderlog), NULL, shaderlog);
printf("%s\n", shaderlog);
}
位置:
GLfloat time_id;
time_if= glGetUniformLocation(myProgObj,"v_time");
改:
GLfloat time_id;
time_id= glGetUniformLocation(myProgObj,"v_time");
17.P230(10.5.5将数据送入着色器)位置:
attribute vec 3 vertex_vel;
改:
attribute vec3 vertex_vel;
18.Position31(10.6弟弟年着色器示例)
位置:
static void myIdle()
{
glUnifor1f(timeParam,glutGet(GLUT_ELAPSED_TIME);
...
改:
static void myIdle()
{
glUniform1f(timeParam,glutGet(GLUT_ELAPSED_TIME));
...
19.P234(10.7片段着色器示例)
位置:
理由之一是虽然瓜果能源的位置是在物体坐标系中用glLight定义的.
改:
理由之一是虽然光源的位置是在物体坐标系中用glLight定义的.