2024年6月6日 星期四

電腦圖學 Week16

  # Week16

#week16-0_sample

先設定好開發環境

  1. freeglut

  2. OpenCV 2.1 (小心 Add PATH)

  3. Settings Compiler Settings 三個設定

    1. C:\OpenCV2.1\include
    2. C:\OpenCV2.1\lib
    3. cv210 cxcore210 highgui210
  4. 接下來,課本的程式
  5. https://jsyeh.org/3dcg10/點開下載window.zip和data,zip跑Projection檔案

  6. 可以改變角度去看人物
    第一個可以縮放角度還有改變人物大小
    第二個可以左右上下旋轉 鏡頭中心點為人物
    第三個鏡頭左右橫移
    第四個鏡頭去做旋轉

  7. week16-1__sample_gluLookAt
  8. 創glut專案
  9. 要改resize()函式在裡面,加上gluLookAt()函式
  10. 就可以看著左上角的那個圓球

  11. 現在要做另一個修改,想要在按鍵時,看不到的地方
  12. 先把剛剛加上得39行程式碼註解,再到void ()裡改程式
  13. if(key=='1')看左上方
  14. if(key=='2')看上方
  15. if(key=='3')看右上方
  16. 程式碼:
  17. /*
     * GLUT Shapes Demo
     *
     * Written by Nigel Stewart November 2003
     *
     * This program is test harness for the sphere, cone
     * and torus shapes in GLUT.
     *
     * Spinning wireframe and smooth shaded shapes are
     * displayed until the ESC or q key is pressed.  The
     * number of geometry stacks and slices can be adjusted
     * using the + and - keys.
     */

    #ifdef __APPLE__
    #include <GLUT/glut.h>
    #else
    #include <GL/glut.h>
    #endif

    #include <stdlib.h>

    static int slices = 16;
    static int stacks = 16;

    /* GLUT callback Handlers */

    static void resize(int width, int height)
    {
        const float ar = (float) width / (float) height;

        glViewport(0, 0, width, height);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity() ;
        ///gluLookAt(0,0,0,-2.4,1.2,-6,0,1,0);///這裡加上程式碼
    }

    static void display(void)
    {
        const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
        const double a = t*90.0;

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glColor3d(1,0,0);

        glPushMatrix();
            glTranslated(-2.4,1.2,-6);
            glRotated(60,1,0,0);
            glRotated(a,0,0,1);
            glutSolidSphere(1,slices,stacks);
        glPopMatrix();

        glPushMatrix();
            glTranslated(0,1.2,-6);
            glRotated(60,1,0,0);
            glRotated(a,0,0,1);
            glutSolidCone(1,1,slices,stacks);
        glPopMatrix();

        glPushMatrix();
            glTranslated(2.4,1.2,-6);
            glRotated(60,1,0,0);
            glRotated(a,0,0,1);
            glutSolidTorus(0.2,0.8,slices,stacks);
        glPopMatrix();

        glPushMatrix();
            glTranslated(-2.4,-1.2,-6);
            glRotated(60,1,0,0);
            glRotated(a,0,0,1);
            glutWireSphere(1,slices,stacks);
        glPopMatrix();

        glPushMatrix();
            glTranslated(0,-1.2,-6);
            glRotated(60,1,0,0);
            glRotated(a,0,0,1);
            glutWireCone(1,1,slices,stacks);
        glPopMatrix();

        glPushMatrix();
            glTranslated(2.4,-1.2,-6);
            glRotated(60,1,0,0);
            glRotated(a,0,0,1);
            glutWireTorus(0.2,0.8,slices,stacks);
        glPopMatrix();

        glutSwapBuffers();
    }


    static void key(unsigned char key, int x, int y)
    {
        if(key=='1'){
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            gluLookAt(0,0,0,-2.4,1.2,-6,0,1,0);
        }else if(key=='2'){
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            gluLookAt(0,0,0,0,1.2,-6,0,1,0);
        }else if(key=='3'){
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            gluLookAt(0,0,0,+2.4,1.2,-6,0,1,0);
        }

        switch (key)
        {
            case 27 :
            case 'q':
                exit(0);
                break;

            case '+':
                slices++;
                stacks++;
                break;

            case '-':
                if (slices>3 && stacks>3)
                {
                    slices--;
                    stacks--;
                }
                break;
        }

        glutPostRedisplay();
    }

    static void idle(void)
    {
        glutPostRedisplay();
    }

    const GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
    const GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
    const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };

    const GLfloat mat_ambient[]    = { 0.7f, 0.7f, 0.7f, 1.0f };
    const GLfloat mat_diffuse[]    = { 0.8f, 0.8f, 0.8f, 1.0f };
    const GLfloat mat_specular[]   = { 1.0f, 1.0f, 1.0f, 1.0f };
    const GLfloat high_shininess[] = { 100.0f };

    /* Program entry point */

    int main(int argc, char *argv[])
    {
        glutInit(&argc, argv);
        glutInitWindowSize(640,480);
        glutInitWindowPosition(10,10);
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

        glutCreateWindow("GLUT Shapes");

        glutReshapeFunc(resize);
        glutDisplayFunc(display);
        glutKeyboardFunc(key);
        glutIdleFunc(idle);

        glClearColor(1,1,1,1);
        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);

        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LESS);

        glEnable(GL_LIGHT0);
        glEnable(GL_NORMALIZE);
        glEnable(GL_COLOR_MATERIAL);
        glEnable(GL_LIGHTING);

        glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
        glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
        glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
        glLightfv(GL_LIGHT0, GL_POSITION, light_position);

        glMaterialfv(GL_FRONT, GL_AMBIENT,   mat_ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE,   mat_diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR,  mat_specular);
        glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);

        glutMainLoop();

        return EXIT_SUCCESS;
    }


  18. ## week16-2_glutReshape_gluPerspective gluLookAt

  19. 請先看課本 Projection.exe 的範例

  20. gluPerspective 透視投影

  21. glortho 垂直投影

  22. glFrustum 比較奇怪,我們通常不用它的投影法

  23. 左、右、下、上、近、遠共6組參數

  24. gluPerspective(視角,長寬比,z近,z遠)

  25. fovy field of view in y視角

  26. aspect ratio 長寬比

  27. 我們將要寫個程式,11行+8行,做出透視投影
  28. 創新glut專案
  29. 先貼上11行簡單程式碼

  30. 在int main裡加入glutReshapeFunc(reshape) 

  31. 寫自己的void reshape(int w,int h)

  32. 程式碼:#include <GL/glut.h> void display(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glutSolidTeapot(0.3); glutSwapBuffers(); } void reshape(int w,int h){ glViewport(0,0,w,h); float ar=w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60,ar,0.01,100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,-2,0,0,0,0,1,0); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow("week16-2"); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMainLoop(); } 會固定茶壺大小

  33. 茶壺會跟著視窗大小改變
  34. 程式碼: #include <GL/glut.h> void display(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glutSolidTeapot(0.3); glutSwapBuffers(); } void reshape(int w,int h){ glViewport(0,0,w,h); float ar=w/(float)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60,ar,0.01,100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,-2,0,0,0,0,1,0); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowPosition(300,600); glutCreateWindow("week16-2"); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMainLoop(); }
  35.  ##week16-3_myTexture_id1_id2_glBindTexture
  36. 若想要
  37. 從github下載
  38. 程式碼:
  39. ///week05_rotating_earth 專案
    /// 把 week05_opencv_opengl_myTexture 程式拿來改
    #include <opencv/highgui.h> ///使用 OpenCV 2.1 比較簡單, 只要用 High GUI 即可
    #include <opencv/cv.h>
    #include <GL/glut.h>
    GLUquadric * quad = NULL; ///todo: 要有一顆指標
    int id1,id2;
    int myTexture(char * filename)
    {
        IplImage * img = cvLoadImage(filename); ///OpenCV讀圖
        cvCvtColor(img,img, CV_BGR2RGB); ///OpenCV轉色彩 (需要cv.h)
        glEnable(GL_TEXTURE_2D); ///1. 開啟貼圖功能
        GLuint id; ///準備一個 unsigned int 整數, 叫 貼圖ID
        glGenTextures(1, &id); /// 產生Generate 貼圖ID
        glBindTexture(GL_TEXTURE_2D, id); ///綁定bind 貼圖ID
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖T, 就重覆貼圖
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖S, 就重覆貼圖
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /// 貼圖參數, 放大時的內插, 用最近點
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); /// 貼圖參數, 縮小時的內插, 用最近點
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height, 0, GL_RGB, GL_UNSIGNED_BYTE, img->imageData);
        return id;
    }
    ///再貼上10行GLUT程式 (不要貼剛剛的程式)
    float angle = 0;
    void display()
    {
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);
        glBindTexture(GL_TEXTURE_2D,id2);
        glBegin(GL_POLYGON);
            glTexCoord2f(0,0);glVertex2f(-1,+1);
            glTexCoord2f(0,1);glVertex2f(-1,-1);
            glTexCoord2f(1,1);glVertex2f(+1,-1);
            glTexCoord2f(1,0);glVertex2f(+1,+1);
        glEnd();
        glBindTexture(GL_TEXTURE_2D,id1);
        glPushMatrix();
            glRotatef(90, 1, 0, 0);
            glRotatef(angle++, 0, 0, 1);
            gluSphere(quad, 0.5, 30, 30); ///glutSolidTeapot( 0.3 );
        glPopMatrix();
        glutSwapBuffers();
    }
    int main(int argc, char*argv[])
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
        glutInitWindowSize(500,500);
        glutCreateWindow("week05");
        glutIdleFunc(display);
        glutDisplayFunc(display);
        id2=myTexture("c:/background.jpg");
        id1=myTexture("c:/earth.jpg");
        quad = gluNewQuadric(); ///todo:把這顆指標,指好
        gluQuadricTexture(quad, 1);///todo: 做好地球的貼圖
        glutMainLoop();
    }

沒有留言:

張貼留言