画个球

TheBooksofShaders ShaderToy
OpenGL Tutorial
头像
523066680
Administrator
Administrator
帖子: 404
注册时间: 2016年07月19日 12:14
拥有现金: 锁定
储蓄: 锁定
Has thanked: 38 times
Been thanked: 52 times
联系:

画个球

帖子 #1 523066680 » 2016年11月26日 20:02

图片

happy886rr
渐入佳境
渐入佳境
帖子: 45
注册时间: 2016年09月27日 16:11
拥有现金: 锁定
储蓄: 锁定
Has thanked: 14 times
Been thanked: 14 times
联系:

Re: 画个球

帖子 #2 happy886rr » 2016年11月29日 20:49

How do it?

头像
523066680
Administrator
Administrator
帖子: 404
注册时间: 2016年07月19日 12:14
拥有现金: 锁定
储蓄: 锁定
Has thanked: 38 times
Been thanked: 52 times
联系:

Re: 画个球

帖子 #3 523066680 » 2016年11月29日 21:05

happy886rr 写了:How do it?


该球是通过 正二十面体, 细分逼近的。
细分方法是 - 对于每个面上的三角形,求出各个边的中点坐标(向量),然后将这些向量缩放至和正二十面体其他顶点距离中心的长度一致。
重新连结 - 一个三角形变为4个三角形。进一步细分2-3次,不断逼近圆球(我也是看教程学的)

但是光照部分就直接用的现成函数

给出代码,keypress 函数内定义了一些按键操作

Code: [全选] [展开/收缩] [Download] (Untitled.c)
  1. #include <GL/freeglut.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <math.h>
  5. #include <time.h>
  6.  
  7. #define SIZE_X 500
  8. #define SIZE_Y 500
  9.  
  10. #define PI 3.1415926
  11. #define PI2 PI*2
  12. int winID;
  13.  
  14. static float rx = 0.0;
  15. static float ry = 0.0;
  16. static float rz = 0.0;
  17. static float gloden = (1.0+sqrt(5.0))/2.0;
  18. static float scale  = 1.0;
  19. static float len;
  20. static float rlx = 0.0, rly = 0.0, rlz = 0.0;
  21.  
  22. void normalize(float v[3])
  23. {
  24.     float d = sqrt(v[0]*v[0] + v[1]*v[1] +v[2]*v[2]);
  25.     v[0] /= d/len;
  26.     v[1] /= d/len;
  27.     v[2] /= d/len;
  28. }
  29.  
  30. void drawTriangle(float *v1, float *v2, float *v3)
  31. {
  32.     glBegin(GL_TRIANGLES);
  33.         glNormal3fv(v1);
  34.         glVertex3fv(v1);
  35.         glNormal3fv(v2);
  36.         glVertex3fv(v2);
  37.         glNormal3fv(v3);
  38.         glVertex3fv(v3);
  39.     glEnd();
  40. }
  41.  
  42. void subdivide(int lv, float *v1, float *v2, float *v3)
  43. {
  44.     float v12[3], v23[3], v31[3];
  45.     for (int i = 0; i < 3; i++)
  46.     {
  47.         v12[i] = (v1[i]+v2[i])/2.0;
  48.         v23[i] = (v2[i]+v3[i])/2.0;
  49.         v31[i] = (v3[i]+v1[i])/2.0;
  50.     }
  51.  
  52.     normalize(v12);
  53.     normalize(v23);
  54.     normalize(v31);
  55.  
  56.     if (lv >= 2)
  57.     {
  58.         //glColor3f(v1[0]/2.0, (float)(rand()%5/5.0), v1[2]/2.0 );
  59.         //glColor3f(v1[0]/2.0, v1[1]/2.0, v1[2]/2.0 );
  60.         drawTriangle(v1, v12, v31);
  61.  
  62.         glColor3f(v2[0]/2.0,v23[1]/2.0,v12[2]/2.0 );
  63.         drawTriangle(v2, v23, v12);
  64.  
  65.         glColor3f(v3[0]/2.0,v3[1]/2.0,v3[2]/2.0 );
  66.         drawTriangle(v3, v31, v23);
  67.  
  68.         glColor3f(v12[0]/2.0,v12[1]/2.0,v12[2]/2.0 );
  69.         drawTriangle(v12, v23, v31);
  70.     }
  71.     else
  72.     {
  73.         subdivide(lv+1, v1, v12, v31);
  74.         subdivide(lv+1, v2, v23, v12);
  75.         subdivide(lv+1, v3, v31, v23);
  76.         subdivide(lv+1, v12, v23, v31 );
  77.     }
  78. }
  79.  
  80. void drawCube(float size)
  81. {
  82.     float half = size/2.0;
  83.     glBegin(GL_QUADS);
  84.         glColor3f(0.3, 0.3, 0.8);
  85.         glNormal3f(1.0, 1.0, 1.0);
  86.         glVertex3f(half, half, half);
  87.         glNormal3f(-1.0, 1.0, 1.0);
  88.         glVertex3f(-half, half, half);
  89.         glNormal3f(-1.0, -1.0, 1.0);
  90.         glVertex3f(-half, -half, half);
  91.         glNormal3f(1.0, -1.0, 1.0);
  92.         glVertex3f(half, -half, half);
  93.  
  94.         glColor3f(0.8, 0.3, 0.8);
  95.         glNormal3f(1.0, 1.0, -1.0);
  96.         glVertex3f(half, half, -half);
  97.         glNormal3f(-1.0, 1.0, -1.0);
  98.         glVertex3f(-half, half, -half);
  99.         glNormal3f(-1.0, -1.0, -1.0);
  100.         glVertex3f(-half, -half, -half);
  101.         glNormal3f(1.0, -1.0, -1.0);
  102.         glVertex3f(half, -half, -half);
  103.  
  104.         glColor3f(0.3, 0.8, 0.3);
  105.         glNormal3f(1.0, 1.0, 1.0);
  106.         glVertex3f(half, half, half);
  107.         glNormal3f(1.0, -1.0, 1.0);
  108.         glVertex3f(half, -half, half);
  109.         glNormal3f(1.0, -1.0, -1.0);
  110.         glVertex3f(half, -half, -half);
  111.         glNormal3f(1.0, 1.0, -1.0);
  112.         glVertex3f(half, half, -half);
  113.  
  114.         glColor3f(0.8, 0.3, 0.3);
  115.         glNormal3f(-1.0, 1.0, 1.0);
  116.         glVertex3f(-half, half, half);
  117.         glNormal3f(-1.0, -1.0, 1.0);
  118.         glVertex3f(-half, -half, half);
  119.         glNormal3f(-1.0, -1.0, -1.0);
  120.         glVertex3f(-half, -half, -half);
  121.         glNormal3f(-1.0, 1.0, -1.0);
  122.         glVertex3f(-half, half, -half);
  123.  
  124.         glColor3f(0.3, 0.6, 0.8);
  125.         glNormal3f(1.0, 1.0, 1.0);
  126.         glVertex3f(half, half, half);
  127.         glNormal3f(-1.0, 1.0, 1.0);
  128.         glVertex3f(-half, half, half);
  129.         glNormal3f(-1.0, 1.0, -1.0);
  130.         glVertex3f(-half, half, -half);
  131.         glNormal3f(1.0, 1.0, -1.0);
  132.         glVertex3f(half, half, -half);
  133.  
  134.         glColor3f(0.8, 0.8, 0.3);
  135.         glNormal3f(1.0, -1.0, 1.0);
  136.         glVertex3f(half, -half, half);
  137.         glNormal3f(-1.0, -1.0, 1.0);
  138.         glVertex3f(-half, -half, half);
  139.         glNormal3f(-1.0, -1.0, -1.0);
  140.         glVertex3f(-half, -half, -half);
  141.         glNormal3f(1.0, -1.0, -1.0);
  142.         glVertex3f(half, -half, -half);
  143.     glEnd();
  144. }
  145.  
  146. void display(void)
  147. {
  148.     char spk[20];
  149.     GLUquadricObj *quad;
  150.     quad = gluNewQuadric();
  151.     // 清理颜色缓冲区
  152.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  153.    
  154.     //glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
  155.     // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  156.  
  157.     float a = 0.9;
  158.     float b = a / gloden * scale;
  159.     len = sqrt( a*a + b*b);
  160.  
  161.     float A[4][3] = {
  162.          a,   b, 0.0,
  163.         -a,   b, 0.0,
  164.         -a,  -b, 0.0,
  165.          a,  -b, 0.0
  166.     };
  167.     float B[4][3] = {
  168.          b, 0.0,  a,
  169.         -b, 0.0,  a,
  170.         -b, 0.0, -a,
  171.          b, 0.0, -a,
  172.     };
  173.  
  174.     float C[4][3] = {
  175.         0.0,  a,  b,
  176.         0.0, -a,  b,
  177.         0.0, -a, -b,
  178.         0.0,  a, -b
  179.     };
  180.  
  181.     float *ico[20][3] =
  182.     {
  183.         A[0], B[0], C[0],
  184.         A[0], B[3], C[3],
  185.         A[1], B[1], C[0],
  186.         A[1], B[2], C[3],
  187.        
  188.         A[2], B[1], C[1],
  189.         A[2], B[2], C[2],
  190.         A[3], B[0], C[1],
  191.         A[3], B[3], C[2],
  192.  
  193.         A[0], A[3], B[0],
  194.         A[0], A[3], B[3],
  195.  
  196.         A[1], A[2], B[1],
  197.         A[1], A[2], B[2],
  198.  
  199.         B[0], B[1], C[0],
  200.         B[0], B[1], C[1],
  201.  
  202.         B[2], B[3], C[2],
  203.         B[2], B[3], C[3],
  204.  
  205.         C[0], C[3], A[0],
  206.         C[0], C[3], A[1],
  207.        
  208.         C[1], C[2], A[2],
  209.         C[1], C[2], A[3],
  210.     };
  211.  
  212.  
  213.  
  214.     glPushMatrix();
  215.    
  216.     glRotatef(ry, 0.0, 1.0, 0.0);
  217.     glRotatef(rx, 1.0, 0.0, 0.0);
  218.     glRotatef(rz, 0.0, 0.0, 1.0);
  219.  
  220.     glColorMaterial(GL_FRONT, GL_DIFFUSE);
  221.     glEnable(GL_COLOR_MATERIAL);
  222.  
  223.     glColor3f(1.0, 1.0, 1.0);
  224.     drawCube(6.0);
  225.  
  226.     glColor4f(0.8, 0.8, 0.6, 0.8);
  227.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  228.     glBegin(GL_TRIANGLES);
  229.  
  230.     for (int i = 0; i<20; i++)
  231.     {
  232.         subdivide(0, ico[i][0], ico[i][1], ico[i][2]);
  233.     }
  234.  
  235.     glEnd();
  236.  
  237.     glPopMatrix();
  238.  
  239.     glPushMatrix();
  240.         glRotatef(rly, 0.0, 1.0, 0.0);
  241.         glRotatef(rlx, 1.0, 0.0, 0.0);
  242.         glRotatef(rlz, 0.0, 0.0, 1.0);
  243.  
  244.         glTranslatef(1.0, 1.0, 1.0);
  245.         glColor3f(1.0, 1.0, 1.0);
  246.         glutSolidSphere(0.1, 20, 20);
  247.     glPopMatrix();
  248.  
  249.     glPushMatrix();
  250.         glRotatef(rly, 0.0, 1.0, 0.0);
  251.         glRotatef(rlx, 1.0, 0.0, 0.0);
  252.         glRotatef(rlz, 0.0, 0.0, 1.0);
  253.         GLfloat light_position[] = { 2.0, 2.0, 2.0, 0.0 };
  254.         glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  255.     glPopMatrix();
  256.  
  257.     glutSwapBuffers();
  258. }
  259.  
  260. void init(void)
  261. {
  262.     glClearColor(0.3, 0.3, 0.3, 0.8);
  263.     glEnable(GL_BLEND);
  264.     glLineWidth( 1.0 );
  265.     glPointSize( 1.0 );
  266.  
  267.     GLfloat mat_ambient[] = { 0.2, 0.0, 0.0, 1.0 };
  268.     GLfloat mat_specular[] = { 0.3, 0.3, 0.7, 1.0 };
  269.     GLfloat mat_shininess[] = { 10.0 };
  270.     GLfloat mat_diffuse[] = {0.5, 0.5, 0.5, 1.0};
  271.     GLfloat light_position[] = { -2.0, -2.0, -2.0, 0.0 };
  272.     GLfloat light_specular[] = { 0.5, 0.5, 1.0, 0.1 };
  273.  
  274.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient );
  275.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse );
  276.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
  277.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
  278.  
  279.     GLfloat spot_direction[] = { 0.0, 0.0, 0.0 };
  280.    
  281.     glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
  282.     glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  283.     glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 120.0);
  284.     glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
  285.  
  286.     GLfloat light_position2[] = { -2.0, -2.0, 1.0, 0.0 };
  287.     glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
  288.     glLightfv(GL_LIGHT1, GL_POSITION, light_position2);
  289.     // glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 90.0);
  290.     glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction);
  291.  
  292.  
  293.     // GLfloat mat_specular2[] = { 1.0, 1.0, 1.0, 1.0 };
  294.     // GLfloat mat_shininess2[] = { 50.0 };
  295.     // GLfloat light_position2[] = { 1.0, 1.0, 1.0, 0.0 };
  296.     // glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular2);
  297.     // glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess2);
  298.     // glLightfv(GL_LIGHT0, GL_POSITION, light_position2);
  299.  
  300.     glEnable(GL_LIGHTING);
  301.     glEnable(GL_LIGHT0);
  302.     glEnable(GL_LIGHT1);
  303.  
  304.     glEnable(GL_POINT_SMOOTH);
  305.     glEnable(GL_LINE_SMOOTH);
  306.     glEnable(GL_DEPTH_TEST);
  307. }
  308.  
  309. void idle(void)
  310. {
  311.     //rx+=0.2;
  312.     usleep(50000);
  313.     glutPostRedisplay();
  314. }
  315.  
  316. void reshape(int Width,int Height)
  317. {
  318.     const float fa = 4.0;
  319.     const float half = 4.0;
  320.  
  321.     glViewport(0, 0, Width, Height);     //视口范围
  322.     glMatrixMode(GL_PROJECTION);              // 投影视图矩阵
  323.     glLoadIdentity();
  324.     //glOrtho(-half, half, -half, half, 0.0, 100.0);
  325.     gluPerspective(60.0, 1.0, 2.0, 100.0);     // 透视投影矩阵(立体视图
  326.     glMatrixMode(GL_MODELVIEW);               // 模型视图矩阵
  327.     glLoadIdentity();
  328.     gluLookAt(0.0,0.0,fa, 0.0,0.0,0.0, 0.0,1.0,fa);  //设置观察点
  329.             // 观察点,   朝向的坐标, 观察点向上坐标
  330. }
  331.  
  332. void keypress(unsigned char key, int mousex, int mousey)
  333. {
  334.     switch (key)
  335.     {
  336.         case 'q':
  337.             glutDestroyWindow(winID);
  338.             exit(0);
  339.             break;
  340.         case 'Q':
  341.             glutDestroyWindow(winID);
  342.             exit(0);
  343.             break;
  344.         case 'w':
  345.             rx += 2.0;
  346.             glutPostRedisplay();
  347.             break;
  348.         case 's':
  349.             rx -= 2.0;
  350.             glutPostRedisplay();
  351.             break;
  352.         case 'a':
  353.             ry += 2.0;
  354.             glutPostRedisplay();
  355.             break;
  356.         case 'd':
  357.             ry -= 2.0;
  358.             glutPostRedisplay();
  359.             break;
  360.         case '[':
  361.             scale += 0.02;
  362.             printf("width scale: %.2f\n", scale);
  363.             glutPostRedisplay();
  364.             break;
  365.         case ']':
  366.             scale -= 0.02;
  367.             printf("width scale: %.2f\n", scale);
  368.             glutPostRedisplay();
  369.             break;
  370.         case '8':
  371.             rly += 2.0;
  372.             glutPostRedisplay();
  373.             break;
  374.         case '2':
  375.             rly -= 2.0;
  376.             glutPostRedisplay();
  377.             break;
  378.     }
  379. }
  380.  
  381. void main(int argc, char *argv[])
  382. {
  383.     glutInit(&argc, argv);
  384.             //显示模式   双缓冲         RGBA  
  385.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE );
  386.     glutInitWindowSize(SIZE_X, SIZE_Y);       //窗口大小
  387.     glutInitWindowPosition(200, 200);         //位置
  388.     winID = glutCreateWindow("LIGHT_ICO");  //窗口句柄
  389.     init();
  390.     glutDisplayFunc(display);          //显示
  391.     glutKeyboardFunc(keypress);        //按键事件响应
  392.     glutReshapeFunc(reshape);          //窗口事件响应
  393.     glutIdleFunc(idle);                //闲时回调函数
  394.     glutMainLoop();                    //开始主循环
  395. }


编译示例
gcc -std=c11 "%1" -o "%~n1" ^
-ID:\Lib\freeglut-MinGW-3.0.0-1.mp\include ^
-LD:\Lib\freeglut-MinGW-3.0.0-1.mp\lib\x64 ^
-lfreeglut -lopengl32 -lglu32

正二十面体的构造和黄金比例的关系
MinGW+OpenGL+freeglut+glew+glfw 环境配置

happy886rr
渐入佳境
渐入佳境
帖子: 45
注册时间: 2016年09月27日 16:11
拥有现金: 锁定
储蓄: 锁定
Has thanked: 14 times
Been thanked: 14 times
联系:

Re: 画个球

帖子 #4 happy886rr » 2016年11月29日 23:55

523066680 写了:该球是通过 正二十面体, 细分逼近的。

十分不错,但是细分的太小了,看不到砖石面的闪耀,太像球体了就会失去棱角的闪耀。光照效果不太好,要能做成那种淡蓝色透明钻石面就好了。

头像
523066680
Administrator
Administrator
帖子: 404
注册时间: 2016年07月19日 12:14
拥有现金: 锁定
储蓄: 锁定
Has thanked: 38 times
Been thanked: 52 times
联系:

Re: 画个球

帖子 #5 523066680 » 2016年11月30日 10:37

happy886rr 写了:
523066680 写了:该球是通过 正二十面体, 细分逼近的。

十分不错,但是细分的太小了,看不到砖石面的闪耀,太像球体了就会失去棱角的闪耀。光照效果不太好,要能做成那种淡蓝色透明钻石面就好了。


应该也是可以做的很璀璨的,知识不够了,继续学 :shy


回到 “OpenGL”

在线用户

用户浏览此论坛: 没有注册用户 和 1 访客