本人做了一个三围随机算法的程序,在一个圆锥面上随机生成点高度,点数量由用户控制,为2的s次方乘以2的s次方,s由用户输入,输入1则对面分2次输入2则对面分4次,3分8次,把面分成相等的正方形(先是在一个平面上分,然后再加上圆锥控制面),小弟明明把山设成绿色,但程序运行出来是白色,好象是光照太强了,但实在看不出有什么毛病,还请高手指点下,另外请看下我的第2种算法为什么画出来不对,谢谢了!急啊! 下面附上程序: #include <GL/glut.h> #include <stdlib.h> #include <math.h>
#define sf 0.05//材质粗糙系数 #define R 0.270//随机数
int idepth=1,s; float v[65][65][3],theta=0.0;//v[x][y][0]=点的x坐标,v[x][y][1]=点的y坐标,v[x][y][2]=点的z坐标
float RandomGaussian(float mean, float stddev)//高斯随机数 { float factor; float radiussq; float value1, value2;
do { value1 = 2.0 * (float)rand() / RAND_MAX - 1.0; value2 = 2.0 * (float)rand() / RAND_MAX - 1.0; radiussq = value1 * value1 + value2 * value2; } while ((radiussq >= 1.0) || ((radiussq - 0.000001) < 0.0));
factor = sqrt(-2.0 * log(radiussq) / radiussq);
return value1 * factor * stddev + mean; }
float Control(float x, float y)//控制面 { float z; float r2=x*x+y*y;
if(r2>=1.0) z=0.0; else z=2.0*(1.0-sqrt(r2));
return z; }
void RanMid(float *v)//把控制面加到实际面上 { float a, b;
a=Control(v[0],v[1])-v[2]; b=R*fabs(a);
v[2]+=RandomGaussian(a, b); }
void Ground(void)//随机中点算法算出面的坐标 { int i,j,k,step,step2; float sepa;
s=pow(2,idepth);
// Initialize the data v[s][0][0]=v[s][s][0]=1.0; v[0][0][0]=v[0][s][0]=-1.0; v[0][s][1]=v[s][s][1]=1.0; v[0][0][1]=v[s][0][1]=-1.0; v[0][0][2]=v[0][s][2]=v[s][0][2]=v[s][s][2]=0.0;
for(k=0; k<idepth; k++) { step=pow(2,idepth-k); step2=step/2; sepa=2.0/step;
for(i=0; i<=s; i+=step) { // use step1 for(j=step2;j<s;j+=step) { v[i][j][0] = (v[i][j-step2][0]+v[i][j+step2][0])/2.0; v[i][j][1] = (v[i][j-step2][1]+v[i][j+step2][1])/2.0; v[i][j][2] = (v[i][j-step2][2]+v[i][j+step2][2])/2.0;
v[i][j][2]+=sf*RandomGaussian(0.0, 1.0)*fabs(sepa);
RanMid(&v[i][j][0]); } // use step2 if(i<s) for(j=0;j<=s;j+=step) { v[i+step2][j][0] = (v[i][j][0]+v[i+step][j][0])/2.0; v[i+step2][j][1] = (v[i][j][1]+v[i+step][j][1])/2.0; v[i+step2][j][2] = (v[i][j][2]+v[i+step][j][2])/2.0;
v[i+step2][j][2]+=sf*RandomGaussian(0.0, 1.0)*fabs(sepa);
RanMid(&v[i+step2][j][0]);
if(j<s) { v[i+step2][j+step2][0] = (v[i][j][0]+v[i+step][j][0])/2.0; v[i+step2][j+step2][1] = (v[i][j][1]+v[i][j+step][1])/2.0; v[i+step2][j+step2][2] = (v[i][j][2]+v[i+step][j][2]+v[i][j+step][2]+v[i+step][j+step][2])/4.0;
v[i+step2][j][2]+=sf*RandomGaussian(0.0, 1.0)*fabs(sepa);
RanMid(&v[i+step2][j+step2][0]); } } } } /*int i,j,n,ds,midp;另一种算法,但是不行,请大家看下吧! float cs,dcs; s=pow(2,idepth); cs=1.0/s; for(i=0;i<s+1;i++) { for(j=0;j<s+1;j++) { v[i][j][0]=2*i*cs-1; v[i][j][1]=2*j*cs-1; } } v[0][0][2]=v[s][s][2]=v[0][s][2]=v[s][0][2]=0.0;
for(n=idepth;n>0;n--) { ds=pow(2,n); midp=s/2; dcs=2.0/s; for(i=midp;i<=s;i+=ds) { for(j=0;j<=s;j+=ds) { v[i][j][2]=(v[i-midp][j][2]+v[i+midp][j][2])/2.0; v[i][j][2]+=sf*RandomGaussian(0.0,1.0)*fabs(dcs); RanMid(&v[i][j][0]); } } for(i=0;i<=s;i+=ds) { for(j=midp;j<=s;j+=ds) { v[i][j][2]=(v[i][j-midp][2]+v[i][j+midp][2])/2.0; v[i][j][2]+=sf*RandomGaussian(0.0,1.0)*fabs(dcs); RanMid(&v[i][j][0]); } } for(i=midp;i<=s;i+=ds) { for(j=midp;j<=s;j+=ds) { v[i][j][2]=(v[i-midp][j-midp][2]+v[i+midp][j-midp][2]+v[i+midp][j+midp][2]+v[i-midp][j+midp][2])/4.0; v[i][j][2]+=sf*RandomGaussian(0.0,1.0)*fabs(dcs); RanMid(&v[i][j][0]); } }
}*/ }
void normalize(float v[3])//法线相关 { GLfloat d=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); v[0]/=d;v[1]/=d;v[2]/=d; }
void normcrossprod(float v1[3], float v2[3], float out[3])//法线相关 { out[0] = v1[1]*v2[2] - v1[2]*v2[1]; out[1] = v1[2]*v2[0] - v1[0]*v2[2]; out[2] = v1[0]*v2[1] - v1[1]*v2[0]; normalize(out); }
void drawtriangle(float *v1, float *v2, float *v3)//根据算法画三围图形 { int j;GLfloat d1[3], d2[3], norm[3]; for (j = 0; j < 3; j++) { d1[j] = v[j] - v[j]; d2[j] = v[j] - v[j]; } normcrossprod(d1, d2, norm); glNormal3fv(norm);
glBegin(GL_TRIANGLES); //glNormal3fv(v1); glVertex3fv(v1); //glNormal3fv(v2); glVertex3fv(v2); //glNormal3fv(v3); glVertex3fv(v3); glEnd(); }
void display(void) { int i,j; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(0.0,1.0,0.0); glPushMatrix();//读入锯阵,这个和下面那个还原语句影响旋转 glRotatef(theta, 0.0, 0.0, 1.0); for (i=0;i<=s-1;i++) { for(j=0;j<=s-1;j++) { drawtriangle(&v[i][j][0], &v[i+1][j][0], &v[i][j+1][0]); drawtriangle(&v[i][j+1][0], &v[i+1][j][0], &v[i+1][j+1][0]); } } glPopMatrix();//锯阵还原 glutSwapBuffers();//glFlush (); }
void init(void) { // GLfloat mat_specular[] = { 0.0, 0.0, 1.0, 1.0 }; // GLfloat mat_shininess[] = { 50.0 }; // GLfloat light_position[] = { 1.0, -1.0, 1.0, 0.0 };
// GLfloat light_position[] = { 1.0, -1.0, 1.0, 0.0 }; // GLfloat ambient[] = { 0.2, 0.2, 0.2, 1.0 }; // GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT);
// glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); // glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); // glLightfv(GL_LIGHT0, GL_POSITION, light_position);
// glLightfv(GL_LIGHT0, GL_POSITION, light_position); // glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); // glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); // glEnable(GL_LIGHTING); // glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glEnable(GL_DEPTH_TEST); Ground(); }
void reshape (int w, int h) { GLfloat light_position[] = { 1.0, -1.0, 1.0, 0.0 }; GLfloat ambient[] = { 0.2, 0.2, 0.2, 1.0 }; GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 10.0);//① glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt (-1.5, -2.5, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0);//②
glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // glEnable(GL_COLOR_MATERIAL); // glEnable(GL_DEPTH_TEST); // Ground();
}
void keyboard(unsigned char key, int x, int y) { switch (key) { case 49: case 50: case 51: case 52: case 53: case 54: idepth=key-48; Ground(); glutPostRedisplay(); break;
case 27: exit(0); break; } }
void specialkey (int key, int x, int y) { switch (key) { case GLUT_KEY_LEFT: theta-=5.0; if(idepth<0) theta+=360; glutPostRedisplay(); break;
case GLUT_KEY_RIGHT: theta+=5.0; if(theta>360) theta-=360; glutPostRedisplay(); break;
default: break; } }
int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow ("endless"); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutSpecialFunc(specialkey); glutMainLoop(); return 0; }
[此贴子已经被作者于2005-1-9 20:28:43编辑过]