2024年6月6日 星期四

魚鱗☆゚.*・。電腦圖學 Week16

 1. week16-0_sample

(1)安裝freeglut

(2)安裝opencv,重開CodeBlocks --> 詳細去看魚鱗電腦圖學Week05-1

(3)打開新專案,命名為:week16-0_sample


2. 下載課本範例☆゚.*・。

(1)進入網址:https://jsyeh.org/3dcg10/    ☆゚.*・。

(2)下載 win32 和 data ☆゚.*・。

    

(3)去下載,把 windows.zip 和 data.zip 解壓縮☆゚.*・。

(4)下載 -> 把data資料夾挪進windows資料夾中 -> windows -> Projection.exe 點進去

##eye -> 從哪個角度看

##center -> 看的中心在哪裡

##up -> 照片的上方在哪個角度



3. week16-1_glutLookAt

(1)打開新專案,命名為:week16-1_glutLookAt

(2)第28行resize函數的最後要增加1 LookAt 段程式

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);
}

(3)把剛剛那行程式註解掉,現在改成到void key上寫程式,按按鍵時,能夠看不同的地方

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();
}


4. week16-2_glutReshapeFunc_gluPerspective_gluLookAt

(1)先去看課本範例

##gluPerspective 透視投影

##glOrtho 垂直投影

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

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

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

##fovy field of view in y視角

##aspect ratio 長寬比


(2)打開新專案,命名為:week16-2_glutReshapeFunc_gluPerspective_gluLookAt

(3)把11+8行程式貼上

11行:

#include <GL/glut.h>
void display()
{
    
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glutSolidTeapot(0.3);
    glutSwapBuffers();
}
int main(int argc, char*argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
    glutCreateWindow("week16");

    glutDisplayFunc(display);
    
    glutMainLoop();
}


(4)加上reshape函數

#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);  ///model view矩陣
    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");

    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutMainLoop();
}

(5)這樣執行程式後,就能維持視窗和茶壺的長寬比了

(6)再增加一行改變視窗長寬比的程式

#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);
    glutInitWindowSize(300,600);  ///改變視窗長寬比
    glutCreateWindow("week16");

    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutMainLoop();
}

5. week16-3_myTexture_id1_id2_glBindTexture

(1)打開新專案,命名為:week16-3_myTexture_id1_id2_glBindTexture

(2)複製 week05_rotating_earth 的程式碼

(3)把 earth.jpg 放到C槽裡,就能成功執行程式了

(4)去網路上抓一張背景的圖檔,並放到C槽中

(5)加上新增背景的程式

#include <opencv/highgui.h> 
#include <opencv/cv.h>
#include <GL/glut.h>
GLUquadric * quad = NULL; 
int id1, id2; ///要準備兩個整數, 用來存貼圖的代號id
int myTexture(char * filename)
{
    IplImage * img = cvLoadImage(filename);
    cvCvtColor(img,img, CV_BGR2RGB);
    glEnable(GL_TEXTURE_2D); 
    GLuint id;
    glGenTextures(1, &id);
    glBindTexture(GL_TEXTURE_2D, id); ///綁定bind 貼圖ID
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
    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); ///y改
        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("week16");
    glutIdleFunc(display);
    glutDisplayFunc(display);
    id2 = myTexture("c:/background.jpg");
    id1 = myTexture("c:/earth.jpg");

    quad = gluNewQuadric(); 
    gluQuadricTexture(quad, 1);
    glutMainLoop();
}

(6) 執行程式,這樣就有背景了

5. 模型縮放技巧

## glmScale( pmodel, 1.0/24);  ///一行就解決了


6. 上傳Github





沒有留言:

張貼留言