2023年5月24日 星期三

DTang---week15_攝影機

 前置作業

下載上課用檔案

下載位置:https://jsyeh.org/3dcg10/ 

下載檔案及名稱:1. data.zip、2. win32.zip、3. glut32.dll

解壓縮

windows.zip => 獨立解出一個資料夾

data.zip => 將data解壓縮到window資料夾內

選擇porjection.exe

----------------------------------------------------------------------------------------

Topic:CAMERA  攝影機

主要函式:

                                fovy       aspect          zNear          zFar

1. gluPerspective(_______,________,_________,__________);

    fovy:field of view (y方向)  視野的角度

    aspect:aspect ratio 長寬比

2. gluLookAt(_,_,_  --> eye眼睛看/視覺的座標(從哪裡看/從哪裡看過去)  

                        ,_,_,_ --> center視覺的中心點座標(看哪裡/以 (座標處) 為中心看過去)

                        ,_,_,_); --> up 視覺軸的角度(怎麼看/從哪




另外兩個功能類似gluPerspective();的函式

1. glFrustum(_,_,_,_,_,_);

2. glOrtho(_,_,_,_,_,_);


-------------------------------------------------------------------------------------------------------------------

week15_gluLookAt

試做gluLookAt函式


#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); ///視窗裡能看到2p的範圍

    float ar = w/(float) h; /// aspect ratio 長寬比

    glMatrixMode(GL_PROJECTION); /// 先切換到projection矩陣

    glLoadIdentity(); /// 矩陣清空,成為單位矩陣

    gluPerspective(60,ar,0.01,1000);

    glMatrixMode(GL_MODELVIEW); /// 完成後,馬上切回model view矩陣

    glLoadIdentity();/// 矩陣清空

    gluLookAt(0,0,1,  0,0,0,  0,1,0);

    ///在0,0,1處 看著茶壺的0,0,0處  視覺軸是0,1,0

    glutPostRedisplay();

}

int main(int argc, char ** argv){

    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);

    glutCreateWindow("week15");

    glutDisplayFunc(display);

    glutReshapeFunc(reshape);

    glutMainLoop();

}



加入motion函式

.......

float eyeX = 0, eyeY = 0;

void motion(int x, int y){

    eyeX = (x-150.0)/150.0;

    eyeY = (150.0-y)/150.0;

    glMatrixMode(GL_MODELVIEW); /// 完成後,馬上切回model view矩陣

    glLoadIdentity();/// 矩陣清空

    gluLookAt(eyeX,eyeY,1,  0,0,0,  0,1,0);

    glutPostRedisplay();

}

int main(int argc, char ** argv){

    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);

    glutCreateWindow("week15");

    glutMotionFunc(motion);

    glutDisplayFunc(display);

    glutReshapeFunc(reshape);

    glutMainLoop();

}




------------------------------------------------------------------------------------------------------------

回到final project

week15 新增可選擇性轉動關節

#include <stdio.h>

#include <GL/glut.h>

#include "glm.h"

GLMmodel * head = NULL;

GLMmodel * body = NULL;

GLMmodel * uparmR = NULL;

GLMmodel * lowarmR = NULL;

int show[4] = {0,1,1,1};

int ID = 3; /// 0->頭、1->身、2->上手臂、3->下手臂


FILE * fout = NULL;

FILE * fin = NULL;

float teapotx = 0, teapoty = 0;

float angle[20] = {}; /// week15 修改為只旋轉特定關節/部位



void keyboard(unsigned char key, int x, int y){

    if(key=='0') ID = 0;

    if(key=='1') ID = 1;

    if(key=='2') ID = 2;

    if(key=='3') ID = 3;

    glutPostRedisplay();

}



void display(){

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glPushMatrix();

    glScaled(0.2,0.2,0.2);

    if(body == NULL){

            head = glmReadOBJ("Model/head.obj");

            body = glmReadOBJ("Model/wholebody.obj");

            uparmR = glmReadOBJ("Model/uparmR.obj");

            lowarmR = glmReadOBJ("Model/armhandR.obj");

        }

        if(ID == 0) glColor3f(1,0,0);

        else glColor3f(1,1,1);

        if(show[0]) glmDraw(head, GLM_MATERIAL);

        if(ID == 1) glColor3f(1,0,0);

        else glColor3f(1,1,1);

        if(show[1]) glmDraw(body, GLM_MATERIAL);

        glPushMatrix();

            glTranslatef(-1.166666, 0.466667, 0);

            glRotatef(angle[2] ,0 ,0 ,1);/// week15 修改為只旋轉特定關節/部位

            glTranslatef(1.166666, -0.466667, 0);


            if(ID == 2) glColor3f(1,0,0);

            else glColor3f(1,1,1);

            if(show[2]) glmDraw(uparmR, GLM_MATERIAL);


            glPushMatrix();

                glTranslatef(-1.933332, +0.133333, 0);

                glRotatef(angle[3], 0, 0, 1);/// week15 修改為只旋轉特定關節/部位

                glTranslatef(1.933332, -0.133333, 0);

                if(ID == 3) glColor3f(1,0,0);

                else glColor3f(1,1,1);

                if(show[3]) glmDraw(lowarmR, GLM_MATERIAL);

            glPopMatrix();

        glPopMatrix();

    glPopMatrix();

    glColor3f(0,1,0);

    glutSolidTeapot(0.02);

    glutSwapBuffers();

}

int oldX = 0; int oldY = 0;

void motion(int x , int y){

    teapotx += (x - oldX)/150.0;

    teapoty -= (y - oldY)/150.0;

    angle[ID] += (x - oldX);/// week15 修改為只旋轉特定關節/部位

    oldX = x;

    oldY = y;

    printf("glTranslatef(%f, %f, 0);\n", teapotx, teapoty);

    glutPostRedisplay();

}


void mouse(int button, int state, int x, int y){

    if(state==GLUT_DOWN){

        oldX = x;

        oldY = y;

    }

    display();

}


int main(int argc, char** argv){

    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);

    glutCreateWindow("week14");

    glutDisplayFunc(display);

    glutMouseFunc(mouse);

    glutMotionFunc(motion);

    glutKeyboardFunc(keyboard);

    glutMainLoop();

}


儲存/讀取關節位置的檔案

void keyboard(unsigned char key, int x, int y){

    if(key=='0') ID = 0;

    if(key=='1') ID = 1;

    if(key=='2') ID = 2;

    if(key=='3') ID = 3;

    if(key=='s'){

        if(fout == NULL) fout = fopen("motion.txt", "w"); ///week15-2 儲存關節位置

        for(int i=0; i<20 ;i++){

            fprintf(fout, "%.2f ", angle[i]);

        }

        fprintf(fout, "\n");

    }else if(key=='r'){

        if(fin == NULL) fin = fopen("motion.txt", "r");  ///week15-2 讀取關節位置

        for(int i=0; i<20; i++){

            fscanf(fin, "%f", &angle[i]);

        }

    }

    glutPostRedisplay();

}

..................









沒有留言:

張貼留言