• [图形学] Chp10 OpenGL三维观察程序示例


      10.10节书中给出了一个程序示例,有一个填充正方形,从侧面的角度观察并画到屏幕上。

      图0

      这里进一步画出一个立方体,将相机放入立方体中心,旋转相机,达到在立方体中旋转看到不同画面的效果。

    步骤:

      1 使用的是4.9节中的OpenGL顶点数组方法。创建一个立方体100*100*100,坐标范围(0, 0, 0)到(100, 100, 100)。

      2 立方体各面使用不同的颜色,调整顶点顺序以确保相机看到的都是填充面而不是线框图。

      3 将投影观察点(即观察系原点)设置在矩形中心P0 = (50, 50, 50)。

      4 视点Pref为相机朝向的点(注意,这个不是观察点),初始设置为Pref =(0, 50, 0)。

      5 修改Pref的坐标,使其绕x=z=50进行逆时针旋转(与y轴平行的旋转公式(9.9)),最终实现相机在立方体中逆时针旋转,看到不同面的效果。

    备注:

      1 与y轴平行的旋转公式,先将旋转轴平移到与y轴重合,再进行旋转:z' = z * cosθ - x * sinθ, x' = z * sinθ + x * cosθ, y'=y;

      2 近平面距离投影观察点不能为0,近平面和远平面的坐标会影响画面的效果,调整范围以确保画面不太离谱(并不真实)

      3 之前直接在displayFcn中调用cube,修改使用display list后可以提高cpu的效率,从2%降到1%。

    问题:

      1 调整dnear和dfar时,会影响投影效果。dnear离P0越近,投影效果强度更大,离得远的点看着更小。见图2。不真实。

      2 当调整近裁剪面大小且当立方体旋转时,投影画面会改变宽度,看起来会更奇怪。见图3。不真实。

      3 在idleFcn中使用glutPostRedisplay替换直接调用displayFcn,效率有降低,不懂为什么。

      1 #include <GLUT/GLUT.h>
      2 #include <math.h>
      3 
      4 GLint winWidth = 600, winHeight = 600;
      5 GLfloat x0 = 50.0, y00 = 50.0, z0 = 50.0; // 这是观察参考点,与观察系原点重合
      6 GLfloat xref = 0.0, yref = 50.0, zref = 0.0; // camera要瞄准的点,不是观察参考点
      7 GLfloat Vx = 0.0, Vy = 1.0, Vz = 0.0;
      8 GLfloat xwMin = -40.0, ywMin = -40.0, xwMax = 40.0, ywMax = 40.0;
      9 GLfloat dnear = 25, dfar = 75;
     10 GLdouble radianAngle = 1.0/360.0 * 3.14159;
     11 GLfloat cos1 = cos(radianAngle);
     12 GLfloat sin1 = sin(radianAngle);
     13 
     14 typedef GLint vertex3 [3];
     15 vertex3 pt [8] = {{0, 0, 0}, {0, 100, 0}, {100, 0, 0}, {100, 100, 0},
     16                 {0, 0, 100}, {0, 100, 100}, {100, 0, 100}, {100, 100, 100}};
     17 
     18 void init (void)
     19 {
     20     glClearColor(1.0, 1.0, 1.0, 0.0);
     21     
     22     glMatrixMode(GL_MODELVIEW);
     23     gluLookAt(x0, y00, z0, xref, yref, zref, Vx, Vy, Vz);
     24     
     25     glMatrixMode(GL_PROJECTION);
     26     glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar);
     27     
     28     void cube();
     29     cube();
     30 }
     31 
     32 void quad (GLint n1, GLint n2, GLint n3, GLint n4)
     33 {
     34     glBegin(GL_QUADS);
     35     glVertex3iv(pt[n1]);
     36     glVertex3iv(pt[n2]);
     37     glVertex3iv(pt[n3]);
     38     glVertex3iv(pt[n4]);
     39     glEnd();
     40 }
     41 
     42 GLuint regHex;
     43 
     44 void cube ()
     45 {
     46     regHex = glGenLists(1);
     47     glNewList(regHex, GL_COMPILE);
     48     
     49     glColor3f(0.0, 1.0, 0.0); // back
     50     quad(0, 2, 3, 1);
     51     glColor3f(1.0, 0.0, 0.0); // left
     52     quad(0, 1, 5, 4);
     53     glColor3f(0.0, 0.0, 1.0); // top
     54     quad(1, 3, 7, 5);
     55     glColor3f(1.0, 1.0, 0.0); // front
     56     quad(4, 5, 7, 6);
     57     glColor3f(0.0, 1.0, 1.0); // right
     58     quad(2, 6, 7, 3);
     59     glColor3f(1.0, 0.0, 1.0); // bottom
     60     quad(0, 4, 6, 2);
     61     
     62     glEndList();
     63 }
     64 
     65 void displayFcn (void)
     66 {
     67     glClear(GL_COLOR_BUFFER_BIT);
     68     
     69     glColor3f(0.0, 1.0, 0.0);
     70     glPolygonMode(GL_FRONT, GL_FILL);
     71     glPolygonMode(GL_BACK, GL_LINE);
     72 //    glFrontFace(GL_CW); // show the back
     73 
     74     glCallList(regHex);    
     75 
     76     glutSwapBuffers();
     77 }
     78 
     79 void reshapeFcn (GLint newWidth, GLint newHeight)
     80 {
     81     glViewport(0, 0, newWidth, newHeight);
     82     
     83     winWidth = newWidth;
     84     winHeight = newHeight;
     85 }
     86 
     87 void idleFcn (void)
     88 {
     89     GLfloat xref1, zref1;
     90     xref = xref - x0;
     91     zref = zref - z0;
     92     zref1 = zref * cos1 - xref * sin1 + z0;
     93     xref1 = zref * sin1 + xref * cos1 + x0;
     94     xref = xref1;
     95     zref = zref1;
     96     
     97     glMatrixMode(GL_MODELVIEW);
     98     glLoadIdentity();
     99     gluLookAt(x0, y00, z0, xref, yref, zref, Vx, Vy, Vz);
    100     
    101     glutPostRedisplay();
    102 }
    103 
    104 int main(int argc, char * argv[])
    105 {
    106     glutInit(&argc, argv);
    107     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    108     glutInitWindowSize(winWidth, winHeight);
    109     glutInitWindowPosition(50, 50);
    110     glutCreateWindow("Perspective View of A Square");
    111     
    112     init();
    113     glutDisplayFunc(displayFcn);
    114     glutReshapeFunc(reshapeFcn);
    115     glutIdleFunc(idleFcn);
    116     glutMainLoop();
    117     
    118     return 0;
    119 }
    View Code
    图1  图2  图3
  • 相关阅读:
    JNA 简单示例
    WPF中使用VisiFire制作chart报表
    ActiveMQ CMS 开发环境编译
    c# 程序打包发布
    WPF 程序未处理异常 的捕获
    制作简易浏览器
    C#.NET 支持文件拖放
    C/S代码一例
    Delphi 2010 TStreamReader 和TStreamWriter
    Json数据使用及学习方法
  • 原文地址:https://www.cnblogs.com/p0e0o0p0l0e0/p/6978225.html
Copyright © 2020-2023  润新知