顯示具有 08163034_郭瑞瑜 標籤的文章。 顯示所有文章
顯示具有 08163034_郭瑞瑜 標籤的文章。 顯示所有文章

2021年6月16日 星期三

電腦圖學 week17

可以從老師那邊複製程式https://hackmd.io/@jsyeh/opengl

step01_老師新開GLUT專案, 寫出最精簡的程式, 畫出茶壼, 改變 glClearColor() 及 glColor3f() 再加上打光的陣列、打光的函式,光的位置也改了一下,並解釋glEnable(GL_DEPTH_TEST)

 #include <GL/glut.h>

void display()

{

    glClearColor( 1,0,0,0);///用來Clear的Color 用紅色

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glColor3f( 1,1,0 );///讓茶壺變黃色

        glutSolidTeapot( 0.3 );

    glutSwapBuffers();

}

int main( int argc, char ** argv )

{

    glutInit( &argc, argv );

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);

    glutInitWindowSize(500,500);///可以設定大一點

    glutInitWindowPosition(0,0);///位置

    glutCreateWindow("week17");


    glutDisplayFunc(display);

    glutMainLoop();

}


void display()
{
    glClearColor( 1,0,0,0);///用來Clear的Color 用紅色
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glColor3f( 1,1,0 );///讓茶壺變黃色
        glutSolidTeapot( 0.3 );

        glColor3f( 1,0,0 );///紅色
        glutSolidTeapot( 0.1 );
    glutSwapBuffers();
}
打光
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 };///改成-5.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 };


glEnable(GL_DEPTH_TEST);///3D測是要打開
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);
step01-2_老師講解T-R-T的作法, 並回憶之前的教轉動時,用個時鐘、紙片來看如何轉動
void display(){
glClearColor( 1,0,0,0);///用來Clear的Color 用紅色
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glColor3f( 1,1,0 );
glutSolidTeapot( 0.3 );///身體先註解掉身體,只看手臂
glPushMatrix();
glTranslatef();///(3)再把轉動中的手臂,掛到肩上
glRotatef();///(2)再轉動它
glTranslatef(-0.3, 0.1, 0);///(1)移動旋轉中心,放正中心
glutSolidTeapot(0.3);///左手臂
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
}
step02_利用mouse()及motion()來轉動, 其中有用到 angle += x-oldX
老師利用捲尺來示範講解, 同時要把 oldX=x; 設定新的關始點。
別忘了 glutPostRedisplay()重畫畫面,
還有 glutMouseFunc() glutMotionFunc()
float angle=45,oldX,oldY;
void mouse(int button,int state,int x,int y){
oldX = x;
}
void motion(int x,int y){
angle += x - oldX;
oldX = x;
glutPostRedisplay();
}
    glutMouseFunc(mouse);
glutMotionFunc(motion);

step03_利用keyboard()來切換angleID, 再於 display()裡, 依照 angle[0]
angle[1] angle[2]等去畫出正確姿勢的圖, 記得要glutKeyboardFunc()註冊, 同時在 motion()裡用
angle[angleID]來改變特定的關節
#include <stdio.h>
#include <GL/glut.h>
float angle[20]={};///大括號,表示會自己補0
int angleID = 0;///
float oldX,oldY;
void keyboard(unsigned char key, int x, int y){
    if(key=='0') angleID=0;
    if(key=='1') angleID=1;
    if(key=='2') angleID=2;
    if(key=='3') angleID=3;
    if(key=='4') angleID=4;
    if(key=='5') angleID=5;
    if(key=='6') angleID=6;
}
void mouse(int button,int state,int x,int y){
    oldX = x;
}
void motion(int x,int y){
    angle[angleID] += x - oldX;
    oldX = x;
    glutPostRedisplay();
}
void display(){
    glClearColor( 1,0,0,0);///用來Clear的Color 用紅色
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glColor3f( 1,1,0 );
        glutSolidTeapot( 0.3 );///身體先註解掉身體,只看手臂
        glPushMatrix();///左半邊
            glTranslatef(-0.3, 0, 0);///(3)再把轉動中的手臂,掛到肩上
            glRotatef(angle[0], 0,0,1);///(2)再轉動它
            glTranslatef(-0.3,0.1, 0);///(1)移動旋轉中心,放正中心
            glutSolidTeapot(0.3);///左手臂
            glPushMatrix();
                glTranslatef(-0.3, 0, 0);///(3)再把轉動中的手臂,掛到肩上
                glRotatef(angle[1], 0,0,1);///(2)再轉動它
                glTranslatef(-0.3, 0, 0);///(1)移動旋轉中心,放正中心
                glutSolidTeapot(0.3);///左手肘
            glPopMatrix();
        glPopMatrix();
        glPushMatrix();///右半邊
            glTranslatef(+0.3, 0, 0);///(3)再把轉動中的手臂,掛到肩上
            glRotatef(angle[2], 0,0,1);///(2)再轉動它
            glTranslatef(+0.3,0.1, 0);///(1)移動旋轉中心,放正中心
            glutSolidTeapot(0.3);///右手臂
            glPushMatrix();
                glTranslatef(+0.3, 0, 0);///(3)再把轉動中的手臂,掛到肩上
                glRotatef(angle[3], 0,0,1);///(2)再轉動它
                glTranslatef(+0.3, 0, 0);///(1)移動旋轉中心,放正中心
                glutSolidTeapot(0.3);///右手肘
            glPopMatrix();
        glPopMatrix();
    glPopMatrix();
    glutSwapBuffers();
}
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 };
int main( int argc, char ** argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    ///glutInitWindowSize(500,500);///可以設定大一點
    glutInitWindowPosition(0,0);///位置
    glutCreateWindow("week17");

    glutKeyboardFunc(keyboard);///要有這行, 註冊 keyboard()
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutDisplayFunc(display);

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

step04_要進行存檔、讀檔,所以要有 stdio.h 及 FILE 指標 fout=NULL 及 FILE 指標 fin=NULL 小心,不要宣告成 ==NULL哦! 在keyboard()的 save時, if(fout==NULL) fout=fopen()開檔 並用for迴圈把 angle[i]全部寫檔。在 read時, 就for迴圈一次讀一整行,並glutPostRedisplay()更新畫面

if(key=='s'){///save 存檔
if( fout==NULL ) fout = fopen("angle.txt", "w+");///write加檔案
for(int i=0; i<20; i++) fprintf(fout, "%.2f ", angle[i]);
fprintf(fout, "\n");
printf("save angle.txt\n");///幫你確定你有存一行關節
}///程式要整個關掉(or fclose(fout),檔案確定你有存一行關節
    else if(key=='r'){///read 讀檔 (不能和存檔同時做,因angle.txt不能開2次)
if( fin==NULL ) fin = fopen("angle.txt", "r");
for(int i=0; i<20; i++) fscanf(fin, "%f", &angle[i]);
glutPostRedisplay();///重畫畫面
printf("read angle.txt\n");
}
step05_利用上週教的動畫內插法,先按 p 呼叫第1個 glutTimerFunc(0, timer, 0)
接下來 timer()裡,會叫用下一次timer(t+1) 而且每過 t%10==0 時就重讀新舊資料,
angle[i] = alpha乘angleNew[i]+alpha乘angleOld[i] 來進行alpha內插
#include <stdio.h> #include <GL/glut.h> float angle[20]={},angleOld[20],angleNew[20];///大括號,表示會自己補0 int angleID = 0;/// float oldX,oldY; FILE * fout = NULL; FILE * fin = NULL; void timer(int t){ glutTimerFunc(16,timer,t+1); if(t%30==0){ for(int i=0;i<20;i++) angleOld[i]=angleNew[i];///備份資料 if(fin==NULL) fin = fopen("angle.txt","r");///read for(int i=0;i<20;i++) fscanf(fin,"%f",&angleNew[i]);///讀到angleNew } float alpha=(t%30)/30.0; for(int i=0;i<20;i++) angle[i]=alpha*angleNew[i]+(1-alpha)*angleOld[i]; glutPostRedisplay();///重畫畫面 } void keyboard(unsigned char key, int x, int y){ if(key=='0') angleID=0; if(key=='1') angleID=1; if(key=='2') angleID=2; if(key=='3') angleID=3; if(key=='4') angleID=4; if(key=='5') angleID=5; if(key=='6') angleID=6; if(key=='p') glutTimerFunc(0, timer, 0); if(key=='s'){///save 存檔 if(fout==NULL) fout = fopen("angle.txt","w+");///write加檔案 for(int i=0;i<20;i++) fprintf(fout,"%.2f",angle[i]); fprintf(fout,"\n"); printf("save one line\n");///幫你確定你有存一行關節 }///程式要整個關掉(or fclose(fout),檔案確定你有存一行關節 if(key=='r'){///read 讀檔 if(fin==NULL) fin = fopen("angle.txt","r"); for(int i=0;i<20;i++) fscanf(fin,"%f",&angle[i]); glutPostRedisplay();///重畫畫面 } } void mouse(int button,int state,int x,int y){ oldX = x; } void motion(int x,int y){ angle[angleID] += x - oldX; oldX = x; glutPostRedisplay(); } void display(){ glClearColor( 1,0,0,0);///用來Clear的Color 用紅色 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glColor3f( 1,1,0 ); glutSolidTeapot( 0.3 );///身體先註解掉身體,只看手臂 glPushMatrix();///左半邊 glTranslatef(-0.3, 0, 0);///(3)再把轉動中的手臂,掛到肩上 glRotatef(angle[0], 0,0,1);///(2)再轉動它 glTranslatef(-0.3,0.1, 0);///(1)移動旋轉中心,放正中心 glutSolidTeapot(0.3);///左手臂 glPushMatrix(); glTranslatef(-0.3, 0, 0);///(3)再把轉動中的手臂,掛到肩上 glRotatef(angle[1], 0,0,1);///(2)再轉動它 glTranslatef(-0.3, 0, 0);///(1)移動旋轉中心,放正中心 glutSolidTeapot(0.3);///左手肘 glPopMatrix(); glPopMatrix(); glPushMatrix();///右半邊 glTranslatef(+0.3, 0, 0);///(3)再把轉動中的手臂,掛到肩上 glRotatef(angle[2], 0,0,1);///(2)再轉動它 glTranslatef(+0.3,0.1, 0);///(1)移動旋轉中心,放正中心 glutSolidTeapot(0.3);///右手臂 glPushMatrix(); glTranslatef(+0.3, 0, 0);///(3)再把轉動中的手臂,掛到肩上 glRotatef(angle[3], 0,0,1);///(2)再轉動它 glTranslatef(+0.3, 0, 0);///(1)移動旋轉中心,放正中心 glutSolidTeapot(0.3);///右手肘 glPopMatrix(); glPopMatrix(); glPopMatrix(); glutSwapBuffers(); } 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 }; int main( int argc, char ** argv ) { glutInit( &argc, argv ); glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH); ///glutInitWindowSize(500,500);///可以設定大一點 glutInitWindowPosition(0,0);///位置 glutCreateWindow("week17"); glutKeyboardFunc(keyboard);///要有這行, 註冊 keyboard() glutMouseFunc(mouse); glutMotionFunc(motion); glutDisplayFunc(display); 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(); }

2021年6月9日 星期三

電腦圖學 week16

 

step01-1把上週week15的程式拿來用,先開新的GLUT專案,把程式貼上week15的main cpp程式

step01-2利用mouse() motion()來讓angle可以動,記得要加入glutMouseFunc()及glutMotionFunc()


step02-1在motion()時,順便寫檔案,也順便印到小黑畫面。記得小墨關掉後,angle txt 檔才會更新到硬碟
///把新專案 week16 的程式刪掉
///再把 Week15_file 的 main.cpp 拿來用
#include <stdio.h>
#include <GL/glut.h>
float angle[20]={}, diff=2;///Step05 本來只有1個角度,現在有很多個,初始為0
int angleID=0; ///Step05 現在要改第幾個角度!!!
int oldX=0;
FILE * fout = NULL;
void timer( int t ){///Step01-2 不用timer動,改keyboard動
///程式搬家,改用mouse motion來做動作
}
void mouse(int button, int state, int x, int y){
oldX = x;///當mouse按下去時,記下位置
}
void motion(int x, int y){///當我motion動
angle[angleID] += x - oldX;///用x-oldX
oldX = x;///再更新位置
glutPostRedisplay();///現在這個比較好, 以前會用 display()重畫

if(fout==NULL) fout=fopen("angle.txt", "w+");
for(int i=0; i<20; i++) fprintf( fout, "%.1f ", angle[i]);
fprintf( fout, "\n");///以上2行,寫到檔案
for(int i=0; i<20; i++) printf( "%.1f ", angle[i]);
printf( "\n");///以上2行,印到畫面 (讓你知道印了什麼資料)
}
void keyboard( unsigned char key, int x, int y){ ///Step05
if(key=='0') angleID=0; ///Step05
if(key=='1') angleID=1; ///Step05
if(key=='2') angleID=2; ///Step05
if(key=='3') angleID=3; ///Step05
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glutSolidTeapot( 0.3 );///身體
glPushMatrix();///左半邊
glTranslatef(-0.3,0,0);///(3)掛在正確的地方
glRotatef(angle[0], 0,0,1);///(2)旋轉 ///Step05
glTranslatef(-0.3,0,0);///(1)把關節旋轉中心放到畫面中心
glutSolidTeapot( 0.3 );///左手臂(沒有重疊)
glPushMatrix();
glTranslatef(-0.3,0,0);///(3)掛在正確的地方
glRotatef(angle[1], 0,0,1);///(2)旋轉 ///Step05
glTranslatef(-0.3,0,0);///(1)把關節旋轉中心放到畫面中心
glutSolidTeapot( 0.3 );///左手肘(重疊了)
glPopMatrix();
glPopMatrix();
glPushMatrix();///右半邊
glTranslatef(+0.3, 0,0 );
glRotatef(-angle[2], 0,0,1);
glTranslatef(+0.3, 0,0);
glutSolidTeapot( 0.3 );///右手臂
glPushMatrix();
glTranslatef(+0.3, 0,0 );
glRotatef(-angle[3], 0,0,1);
glTranslatef(+0.3, 0,0);
glutSolidTeapot( 0.3 );///右手肘
glPopMatrix();
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week15 file");

glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);///Step05 整合很多關節,會去改angleID
glutTimerFunc(0, timer, 0);///Step04-2 設第1個timer做動畫
glutDisplayFunc(display);
glutMainLoop();
}

step02-2利用timer()來讀檔案,將angle[i]都讀進來,同時glutPostRedisplay()更新畫面,就可以播放動畫了
#include <stdio.h>///可割可棄
#include <GL/glut.h>
float angle[20]={},diff=2;///本來只有一個角度,現在有很多個,初始為0
int angleID=0;///現在要改第幾個角度
int oldX=0;
void timer(int t){

}
void mouse(int button,int state,int x,int y){
    oldX=x;///當mouse按下去時,記下位置
}
void motion(int x,int y){///當我motion動
    angle[angleID]+= x-oldX;///用-oldX
    oldX = x;///再更新位置
    glutPostRedisplay();///現在這個比較好,以前會用display
}
void keyboard(unsigned char key,int x, int y){
    if(key=='0') angleID=0;
    if(key=='1') angleID=1;
    if(key=='2') angleID=2;
    if(key=='3') angleID=3;
}
void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glutSolidTeapot( 0.3 );///身體
        glPushMatrix();///左半邊
            glTranslatef(-0.3,0,0);///(3)掛在正確的地方
            glRotatef(angle[0],0,0,1);///(2)旋轉
            glTranslatef(-0.3,0,0);///(1)把關節旋轉中心放到畫面中心
            glutSolidTeapot(0.3);///左手臂
            glPushMatrix();
                 glTranslatef(-0.3,0,0);///(3)掛在正確的地方
                glRotatef(angle[1],0,0,1);///(2)旋轉
                glTranslatef(-0.3,0,0);///(1)把關節旋轉中心放到畫面中心
                glutSolidTeapot( 0.3 );///左手臂(重疊了)
            glPopMatrix();
        glPopMatrix();
        glPushMatrix();///右半邊
        glTranslatef(+0.3,0,0);///(3)掛在正確的地方
            glRotatef(-angle[2],0,0,1);///(2)旋轉
            glTranslatef(+0.3,0,0);///(1)把關節旋轉中心放到畫面中心
            glutSolidTeapot(0.3);///右手臂
             glPushMatrix();
                 glTranslatef(+0.3,0,0);///(3)掛在正確的地方
                glRotatef(-angle[3],0,0,1);///(2)旋轉
                glTranslatef(+0.3,0,0);///(1)把關節旋轉中心放到畫面中心
                glutSolidTeapot( 0.3 );///右手臂(重疊了)
            glPopMatrix();
        glPopMatrix();
    glPopMatrix();
    glutSwapBuffers();
}
int main( int argc, char ** argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week16");

    glutKeyboardFunc(keyboard);
    glutTimerFunc(0,timer,0);
    glutDisplayFunc(display);
    glutMainLoop();
}

step02-3我們把工作執行目錄working_dir改成小數點,以便在同一目錄工作。

再把 freeglut dll 及 angle txt 也從 freeglut bin 複製到專案目錄裡
///把新專案 week16 的程式刪掉
///再把 Week15_file 的 main.cpp 拿來用
#include <stdio.h>
#include <GL/glut.h>
float angle[20]={}, diff=2;///Step05 本來只有1個角度,現在有很多個,初始為0
int angleID=0; ///Step05 現在要改第幾個角度!!!
int oldX=0;
FILE * fout = NULL;
FILE * fin = NULL;///Step02-2 播放動畫,檔案指標fin
void timer( int t ){
glutTimerFunc( 30, timer, t+1 );///Step02-2 播放動畫
if( fin==NULL ) fin = fopen( "angle.txt", "r" );///Step02-2
for(int i=0; i<20; i++) fscanf( fin, "%f", & angle[i] );///Step02-2
glutPostRedisplay();///Step02-2 播放動畫 重畫畫面
}
void mouse(int button, int state, int x, int y){
oldX = x;///當mouse按下去時,記下位置
}
void motion(int x, int y){///當我motion動
angle[angleID] += x - oldX;///用x-oldX
oldX = x;///再更新位置
glutPostRedisplay();///現在這個比較好, 以前會用 display()重畫

if(fout==NULL) fout=fopen("angle.txt", "w+");
for(int i=0; i<20; i++) fprintf( fout, "%.1f ", angle[i]);
fprintf( fout, "\n");///以上2行,寫到檔案
for(int i=0; i<20; i++) printf( "%.1f ", angle[i]);
printf( "\n");///以上2行,印到畫面 (讓你知道印了什麼資料)
}
void keyboard( unsigned char key, int x, int y){ ///Step05
if(key=='0') angleID=0; ///Step05
if(key=='1') angleID=1; ///Step05
if(key=='2') angleID=2; ///Step05
if(key=='3') angleID=3; ///Step05
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glutSolidTeapot( 0.3 );///身體
glPushMatrix();///左半邊
glTranslatef(-0.3,0,0);///(3)掛在正確的地方
glRotatef(angle[0], 0,0,1);///(2)旋轉 ///Step05
glTranslatef(-0.3,0,0);///(1)把關節旋轉中心放到畫面中心
glutSolidTeapot( 0.3 );///左手臂(沒有重疊)
glPushMatrix();
glTranslatef(-0.3,0,0);///(3)掛在正確的地方
glRotatef(angle[1], 0,0,1);///(2)旋轉 ///Step05
glTranslatef(-0.3,0,0);///(1)把關節旋轉中心放到畫面中心
glutSolidTeapot( 0.3 );///左手肘(重疊了)
glPopMatrix();
glPopMatrix();
glPushMatrix();///右半邊
glTranslatef(+0.3, 0,0 );
glRotatef(-angle[2], 0,0,1);
glTranslatef(+0.3, 0,0);
glutSolidTeapot( 0.3 );///右手臂
glPushMatrix();
glTranslatef(+0.3, 0,0 );
glRotatef(-angle[3], 0,0,1);
glTranslatef(+0.3, 0,0);
glutSolidTeapot( 0.3 );///右手肘
glPopMatrix();
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week15 file");

glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);///Step05 整合很多關節,會去改angleID
glutTimerFunc(0, timer, 0);///Step04-2 設第1個timer做動畫
glutDisplayFunc(display);
glutMainLoop();
}


step03-1註解掉原本motion()的寫檔、原本timer()的讀檔,改在keyboard()裡利用's'來存檔,'r'來讀檔,末來'p'做播放play,

重開之後按下's',就會出現剛剛的動作
///把新專案 week16 的程式刪掉
///再把 Week15_file 的 main.cpp 拿來用
#include <stdio.h>
#include <GL/glut.h>
float angle[20]={}, diff=2;///Step05 本來只有1個角度,現在有很多個,初始為0
int angleID=0; ///Step05 現在要改第幾個角度!!!
int oldX=0;
FILE * fout = NULL;
FILE * fin = NULL;///Step02-2 播放動畫,檔案指標fin
void timer( int t ){
// glutTimerFunc( 30, timer, t+1 );///Step02-2 播放動畫
// if( fin==NULL ) fin = fopen( "angle.txt", "r" );///Step02-2
// for(int i=0; i<20; i++) fscanf( fin, "%f", & angle[i] );///Step02-2
// glutPostRedisplay();///Step02-2 播放動畫 重畫畫面
}
void mouse(int button, int state, int x, int y){
oldX = x;///當mouse按下去時,記下位置
}
void motion(int x, int y){///當我motion動
angle[angleID] += x - oldX;///用x-oldX
oldX = x;///再更新位置
glutPostRedisplay();///現在這個比較好, 以前會用 display()重畫

// if(fout==NULL) fout=fopen("angle.txt", "w+");
// for(int i=0; i<20; i++) fprintf( fout, "%.1f ", angle[i]);
// fprintf( fout, "\n");///以上2行,寫到檔案
// for(int i=0; i<20; i++) printf( "%.1f ", angle[i]);
// printf( "\n");///以上2行,印到畫面 (讓你知道印了什麼資料)
}
void keyboard( unsigned char key, int x, int y){ ///Step05
if(key=='0') angleID=0; ///Step05
if(key=='1') angleID=1; ///Step05
if(key=='2') angleID=2; ///Step05
if(key=='3') angleID=3; ///Step05
if(key=='s'){///save存檔, 把所有的動作存檔後,要關掉
if(fout==NULL) fout=fopen("angle.txt", "w+");
for(int i=0; i<20; i++) fprintf( fout, "%.1f ", angle[i]);
fprintf( fout, "\n");///以上2行,寫到檔案
for(int i=0; i<20; i++) printf( "%.1f ", angle[i]);
printf( "\n");///以上2行,印到畫面 (讓你知道印了什麼資料)
}
if(key=='r'){///read讀檔, 再開之後,才能讀檔
if( fin==NULL ) fin = fopen( "angle.txt", "r" );///Step02-2
for(int i=0; i<20; i++) fscanf( fin, "%f", & angle[i] );///Step02-2
glutPostRedisplay();///Step02-2 播放動畫 重畫畫面
}
if(key=='p'){///play利用timer整個播放, 再開之後,才能讀檔

}
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glutSolidTeapot( 0.3 );///身體
glPushMatrix();///左半邊
glTranslatef(-0.3,0,0);///(3)掛在正確的地方
glRotatef(angle[0], 0,0,1);///(2)旋轉 ///Step05
glTranslatef(-0.3,0,0);///(1)把關節旋轉中心放到畫面中心
glutSolidTeapot( 0.3 );///左手臂(沒有重疊)
glPushMatrix();
glTranslatef(-0.3,0,0);///(3)掛在正確的地方
glRotatef(angle[1], 0,0,1);///(2)旋轉 ///Step05
glTranslatef(-0.3,0,0);///(1)把關節旋轉中心放到畫面中心
glutSolidTeapot( 0.3 );///左手肘(重疊了)
glPopMatrix();
glPopMatrix();
glPushMatrix();///右半邊
glTranslatef(+0.3, 0,0 );
glRotatef(-angle[2], 0,0,1);
glTranslatef(+0.3, 0,0);
glutSolidTeapot( 0.3 );///右手臂
glPushMatrix();
glTranslatef(+0.3, 0,0 );
glRotatef(-angle[3], 0,0,1);
glTranslatef(+0.3, 0,0);
glutSolidTeapot( 0.3 );///右手肘
glPopMatrix();
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week15 file");

glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);///Step05 整合很多關節,會去改angleID
glutTimerFunc(0, timer, 0);///Step04-2 設第1個timer做動畫
glutDisplayFunc(display);
glutMainLoop();
}


step03-2老師利用timer()來做出動畫的內插,其中
(1)要更新angle[i]再重畫,
(2)利用alpha介於0到1中間,進行alpha乘angleNew[i]+(1-alpha乘angleOld[i],
(3) if(t%10==0)來決定更新新舊的時間
(4)alpha怎麼算
///把新專案 week16 的程式刪掉
///再把 Week15_file 的 main.cpp 拿來用
#include <stdio.h>
#include <GL/glut.h>
float angle[20]={}, diff=2;///angle[i]畫的角度,內插 angleOld[i] angleNew[i]
float angleOld[20]={}, angleNew[20]={};///Step03-2 新舊角度準備內插
int angleID=0; ///Step05 現在要改第幾個角度!!!
int oldX=0;
FILE * fout = NULL;
FILE * fin = NULL;///Step02-2 播放動畫,檔案指標fin
void timer( int t ){
glutTimerFunc( 30, timer, t+1 );///Step02-2 播放動畫
if( t%30==0 ){///Step03-2 每10frame,就讀一筆新資料
for(int i=0; i<20; i++) angleOld[i] = angleNew[i];///Step03-2
///讀新資料之前,要先把資料備份^^^^^^^^^^^^^^^^^^
if( fin==NULL ) fin = fopen( "angle.txt", "r" );///Step03-2
for(int i=0; i<20; i++) fscanf( fin, "%f", & angleNew[i] );///Step03-2
}///再讀入新的資料 angleNew[i] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
float alpha = (t%30)/30.0;
for(int i=0; i<20; i++){
angle[i] = alpha*angleNew[i] + (1-alpha)*angleOld[i];
}
glutPostRedisplay();///Step02-2 播放動畫 重畫畫面
}
void mouse(int button, int state, int x, int y){
oldX = x;///當mouse按下去時,記下位置
}
void motion(int x, int y){///當我motion動
angle[angleID] += x - oldX;///用x-oldX
oldX = x;///再更新位置
glutPostRedisplay();///現在這個比較好, 以前會用 display()重畫

// if(fout==NULL) fout=fopen("angle.txt", "w+");
// for(int i=0; i<20; i++) fprintf( fout, "%.1f ", angle[i]);
// fprintf( fout, "\n");///以上2行,寫到檔案
// for(int i=0; i<20; i++) printf( "%.1f ", angle[i]);
// printf( "\n");///以上2行,印到畫面 (讓你知道印了什麼資料)
}
void keyboard( unsigned char key, int x, int y){ ///Step05
if(key=='0') angleID=0; ///Step05
if(key=='1') angleID=1; ///Step05
if(key=='2') angleID=2; ///Step05
if(key=='3') angleID=3; ///Step05
if(key=='s'){///save存檔, 把所有的動作存檔後,要關掉
if(fout==NULL) fout=fopen("angle.txt", "w+");
for(int i=0; i<20; i++) fprintf( fout, "%.1f ", angle[i]);
fprintf( fout, "\n");///以上2行,寫到檔案
for(int i=0; i<20; i++) printf( "%.1f ", angle[i]);
printf( "\n");///以上2行,印到畫面 (讓你知道印了什麼資料)
}
if(key=='r'){///read讀檔, 再開之後,才能讀檔
if( fin==NULL ) fin = fopen( "angle.txt", "r" );///Step02-2
for(int i=0; i<20; i++) fscanf( fin, "%f", & angle[i] );///Step02-2
glutPostRedisplay();///Step02-2 播放動畫 重畫畫面
}
if(key=='p'){///play利用timer整個播放, 再開之後,才能讀檔

}
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glutSolidTeapot( 0.3 );///身體
glPushMatrix();///左半邊
glTranslatef(-0.3,0,0);///(3)掛在正確的地方
glRotatef(angle[0], 0,0,1);///(2)旋轉 ///Step05
glTranslatef(-0.3,0,0);///(1)把關節旋轉中心放到畫面中心
glutSolidTeapot( 0.3 );///左手臂(沒有重疊)
glPushMatrix();
glTranslatef(-0.3,0,0);///(3)掛在正確的地方
glRotatef(angle[1], 0,0,1);///(2)旋轉 ///Step05
glTranslatef(-0.3,0,0);///(1)把關節旋轉中心放到畫面中心
glutSolidTeapot( 0.3 );///左手肘(重疊了)
glPopMatrix();
glPopMatrix();
glPushMatrix();///右半邊
glTranslatef(+0.3, 0,0 );
glRotatef(-angle[2], 0,0,1);
glTranslatef(+0.3, 0,0);
glutSolidTeapot( 0.3 );///右手臂
glPushMatrix();
glTranslatef(+0.3, 0,0 );
glRotatef(-angle[3], 0,0,1);
glTranslatef(+0.3, 0,0);
glutSolidTeapot( 0.3 );///右手肘
glPopMatrix();
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week15 file");

glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);///Step05 整合很多關節,會去改angleID
glutTimerFunc(0, timer, 0);///Step04-2 設第1個timer做動畫
glutDisplayFunc(display);
glutMainLoop();
}





2021年6月8日 星期二

電腦圖學 week05

 

用老師給的程式開角度了解以下
glTranslatef(x,y,z);移動
glRotatef(angle,x,y,z);轉動
glScalef(x,y,z);縮放
車可以改成猛男喔
做出可以畫圈的程式

#include <GL/glut.h>

int N=0,vx[3000],vy[3000];

float angle=0;

void display()

{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix();

        glRotatef(angle,0,0,1);

    glBegin(GL_LINE_LOOP);

    for (int i=0;i<N;i++)

    {

        glVertex2f((vx[i]-150)/150.0,-(vy[i]-150)/150.0);

    }

    glEnd();

    glPopMatrix();

    glutSwapBuffers();

}

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

{

    angle++;

    display();

}

void motion(int x,int y)

{

    vx[N]=x; vy[N]=y;

    N++;

    display();

}

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

    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

    glutCreateWindow("08163034");

    glutDisplayFunc ( display );

    glutKeyboardFunc (keyboard);

    glutMotionFunc(motion);

    glutMainLoop();

電腦圖學 week 2

 #include <GL/glut.h>


void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glColor3f(1,0,0);  ///顏色 R G B
    glutSolidTeapot(0.3);
    glutSwapBuffers();
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week02 08163034!");
    glutDisplayFunc(display);
    glutMainLoop();
}



#include <GL/glut.h>
void display()
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glBegin(GL_LINE_LOOP);

   glColor3f(1.0f, 0.0f, 0.0f);   glVertex2f(0.0f,   1.0f);
   glColor3f(0.0f, 1.0f, 0.0f);   glVertex2f(0.87f,  -0.5f);
   glColor3f(0.0f, 0.0f, 1.0f);   glVertex2f(-0.87f, -0.5f);
  glEnd();
    glColor3f(0.5,1,0.2); ///顏色
  glutSolidTeapot(0.3);
  glutSwapBuffers();
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week02 08163034!");
    glutDisplayFunc(display);
    glutMainLoop();
}

GL_LINE_LOOP

 

改成 glBegin(GL_TRIANGLES);

 

GL_TRIANGLES

#include <GL/glut.h>
#include <math.h> ///數學的外掛cos() sin()
void display()
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glBegin(GL_POLYGON);

   glColor3f(1.0f, 0.0f, 0.0f);
   for(float angle=0; angle<3014159265358979*2; angle+=0.01){
    glVertex2f( 0.5*cos(angle), 0.5*sin(angle) );///Vertex=頂點
   }
  glEnd();
    glColor3f(0.5,1,0.2); ///顏色
  glutSolidTeapot(0.3);
  glutSwapBuffers();
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week02 08163034!");
    glutDisplayFunc(display);
    glutMainLoop();
}



距地表面160 Week11

 #include "glm.h" GLMmodel* pmodel = NULL; void drawmodel(void) {     if (!pmodel) { pmodel = glmReadOBJ("data/porsche.obj...