[C :: OpenGL] 프로젝션을 사용하지 않은 그림자 생성

simpled 2013.08.05 21:10 조회 수 : 4398

Debug.zip



CODE 설명.

 

1. 중간 사각형.

- 회전 함수를 만들어서 사용함.

- 회전 방향을 조정 할 수 있지만, 사각형의 축 방향 이동은 불가능.

- 전체 Matrix의 회전을 통해, 세계관(?)을 움직일 수 있음.

- 시간이 흐르면서 육면체의 색이 변함.

 

2. 광원

- (하얀점)광원의 위 아래, 위치를 변형할 수 있으며, 이에 따른 그림자의 크기도 변화함.

- 광원이 빛을 발산하는 효과 따위는 이 코드에 없음. 그림자 크기에 대한 효과를 보고자 간단히 코드를 조합해 본 것임.

- 6면체의 모든 면을 하나의 z축으로 짜부 시켜서 그림자를 생성함. 단, 그림자 크기는 광원, 중간 사각형, 바닥의 x,y,z 비율에 따라 변화하게 하였음.

- 제 3번 항목에 따라서 광원의 위치를 이동시키면 그림자의 크기가 변화함.

 

실행파일은 업로드 하였음.


008.png 009.png


#include <opengl.h>

#include <math.h>
#include <stdio.h>

#define DRAW1 glColor3f ( color[0],  color[2],  color[4] );    glVertex3f ( x[0], y[0], z[0]);
#define DRAW2 glColor3f ( color[3],  color[1],  color[2] );    glVertex3f ( x[1], y[1], z[1]);
#define DRAW3 glColor3f ( color[4],  color[2],  color[3] );    glVertex3f ( x[2], y[2], z[2]);
#define DRAW4 glColor3f ( color[1],  color[3],  color[2] );    glVertex3f ( x[3], y[3], z[3]);
#define DRAW5 glColor3f ( color[0],  color[4],  color[1] );    glVertex3f ( x[4], y[4], z[4]);
#define DRAW6 glColor3f ( color[3],  color[0],  color[4] );    glVertex3f ( x[5], y[5], z[5]);
#define DRAW7 glColor3f ( color[1],  color[4],  color[3] );    glVertex3f ( x[6], y[6], z[6]);
#define DRAW8 glColor3f ( color[2],  color[3],  color[1] );    glVertex3f ( x[7], y[7], z[7]);

#define BASE_BLOCK1 glColor3f ( 1,   0.3, 0.1 );  glVertex3f (  600,  600, -301);
#define BASE_BLOCK2 glColor3f ( 0.2, 0.2, 0.1 );  glVertex3f (  600, -600, -301);
#define BASE_BLOCK3 glColor3f ( 0.3, 0.4, 0.3 );  glVertex3f ( -600, -600, -301);
#define BASE_BLOCK4 glColor3f ( 0.2, 0.5, 0.5 );  glVertex3f ( -600,  600, -301);
#define BASE_BLOCK5 glColor3f ( 1,   0.1, 0.1 );  glVertex3f ( -600,  600, -351);
#define BASE_BLOCK6 glColor3f ( 0.2, 0.8, 0.3 );  glVertex3f ( -600, -600, -351);
#define BASE_BLOCK7 glColor3f ( 0.5, 0.3, 0.3 );  glVertex3f (  600, -600, -351);
#define BASE_BLOCK8 glColor3f ( 0.1, 0.7, 0.1 );  glVertex3f (  600,  600, -351);

#define ligHt1 glColor3f ( 1, 1, 1 ); glVertex3f ( LP_x[0], LP_y[0], LP_z[0]);
#define ligHt2 glColor3f ( 1, 1, 1 ); glVertex3f ( LP_x[1], LP_y[1], LP_z[1]);
#define ligHt3 glColor3f ( 1, 1, 1 ); glVertex3f ( LP_x[2], LP_y[2], LP_z[2]);
#define ligHt4 glColor3f ( 1, 1, 1 ); glVertex3f ( LP_x[3], LP_y[3], LP_z[3]);
#define ligHt5 glColor3f ( 1, 1, 1 ); glVertex3f ( LP_x[4], LP_y[4], LP_z[4]);
#define ligHt6 glColor3f ( 1, 1, 1 ); glVertex3f ( LP_x[5], LP_y[5], LP_z[5]);
#define ligHt7 glColor3f ( 1, 1, 1 ); glVertex3f ( LP_x[6], LP_y[6], LP_z[6]);
#define ligHt8 glColor3f ( 1, 1, 1 ); glVertex3f ( LP_x[7], LP_y[7], LP_z[7]);

#define shaDow1 glColor3f ( 0.1, 0.1, 0.1 ); glVertex3f ( sqx[0], sqy[0], -300);
#define shaDow2 glColor3f ( 0.1, 0.1, 0.1 ); glVertex3f ( sqx[1], sqy[1], -300);
#define shaDow3 glColor3f ( 0.1, 0.1, 0.1 ); glVertex3f ( sqx[2], sqy[2], -300);
#define shaDow4 glColor3f ( 0.1, 0.1, 0.1 ); glVertex3f ( sqx[3], sqy[3], -300);
#define shaDow5 glColor3f ( 0.1, 0.1, 0.1 ); glVertex3f ( sqx[4], sqy[4], -300);
#define shaDow6 glColor3f ( 0.1, 0.1, 0.1 ); glVertex3f ( sqx[5], sqy[5], -300);
#define shaDow7 glColor3f ( 0.1, 0.1, 0.1 ); glVertex3f ( sqx[6], sqy[6], -300);
#define shaDow8 glColor3f ( 0.1, 0.1, 0.1 ); glVertex3f ( sqx[7], sqy[7], -300);

 GLsizei choiceX,choiceY,choiceZ;
 GLfloat TimeSwitch,TimeSaver,CliPingSize=1000,arc=0.052,color_black;
 GLfloat color[5]={0.1, 0.2, 0.3, 0.4, 0.5};
 GLfloat color_counter[5];
 GLfloat xRot,zRot;
 GLsizei START_auto,k=0;;

 GLfloat x[8]={50, 50,-50,-50,-50,-50, 50, 50};
 GLfloat y[8]={50,-50,-50, 50, 50,-50,-50, 50};
 GLfloat z[8]={50, 50, 50, 50,-50,-50,-50,-50};

 GLfloat LP_x[8]={5, 5,-5,-5,-5,-5, 5, 5};
 GLfloat LP_y[8]={5,-5,-5, 5, 5,-5,-5, 5};
 GLfloat LP_z[8]={5, 5, 5, 5,-5,-5,-5,-5};

 GLfloat sqx[8]={50, 50,-50,-50,-50,-50, 50, 50};
 GLfloat sqy[8]={50,-50,-50, 50, 50,-50,-50, 50};
 GLfloat sqz[8]={50, 50, 50, 50,-50,-50,-50,-50};

void move_matrix(GLsizei p,GLsizei q){
    GLfloat A[4]={LP_x[p], LP_y[p], LP_z[p], 1};
    GLfloat B[4][4]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
    GLfloat C[4]={0,0,0,1};
    GLsizei i,j;
    if(q==8){
        B[3][2]=4;
        }
    if(q==2){
        B[3][2]=-4;
        }
    for(i=0; i<4; i++) for (j=0;j<4;j++) C[i]+=A[j]*B[j][i];
    LP_x[p]=C[0];
    LP_y[p]=C[1];
    LP_z[p]=C[2];
    }
void ShadowMask(GLsizei p, GLsizei div){
    GLfloat lightx,lightz,pointx,pointz,aimx,aimz;
    lightx=0;
    lightz=(LP_z[0]+LP_z[1]+LP_z[2]+LP_z[3]+LP_z[4]+LP_z[5]+LP_z[6]+LP_z[7])/8;
    if(div==0)pointx=x[p];
    if(div==1)pointx=y[p];
    pointz=z[p];
    aimx=0;
    aimz=-300;
    aimx=((lightz-aimz)*pointx)/(lightz-pointz);
    if(div==0)sqx[p]=aimx;
    if(div==1)sqy[p]=aimx;
    }

void ScaleMatrix(GLsizei p, GLsizei S){
    GLfloat A[4]={x[p], y[p], z[p], 1};
    GLfloat B[4][4]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
    GLfloat C[4]={0,0,0,1};
    GLsizei i,j;
    if(S==1) for(i=0; i<4; i++) B[i][i]=1.01;
    if(S==3) for(i=0; i<4; i++) B[i][i]=0.99;
    for(i=0; i<4; i++) for (j=0;j<4;j++) C[i]+=A[j]*B[j][i];
    x[p]=C[0];y[p]=C[1];z[p]=C[2];
    }

void X_Matrix(GLsizei p){
    GLfloat A[4]={x[p], y[p], z[p], 1};
    GLfloat B[4][4]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
    GLfloat C[4]={0,0,0,1};
    GLsizei i,j;
    if(choiceX==2){
      for(i=0; i<4; i++)if(i==1||i==2) B[i][i]=cos(arc);
   B[1][2]=-sin(arc);
   B[2][1]=sin(arc);
        }
    if(choiceX==8){
        for(i=0; i<4; i++)if(i==1||i==2)B[i][i]=cos(arc);
        B[1][2]=sin(arc);
        B[2][1]=-sin(arc);
        }
    for(i=0; i<4; i++) for (j=0;j<4;j++) C[i]+=A[j]*B[j][i];
    x[p]=C[0];
    y[p]=C[1];
    z[p]=C[2];
    }
void Y_Matrix(GLsizei P){
    GLfloat A[4]={x[P], y[P], z[P], 1};
    GLfloat B[4][4]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
    GLfloat C[4]={0,0,0,1};
    GLsizei i,j;
    if(choiceY==6){
        for(i=0; i<4; i++)if(i==0||i==2)B[i][i]=cos(arc);
            B[0][2]=sin(arc);
            B[2][0]=-sin(arc);
        }
    if(choiceY==4){
        for(i=0; i<4; i++)if(i==0||i==2)B[i][i]=cos(arc);
            B[0][2]=-sin(arc);
            B[2][0]=sin(arc);
        }
    for(i=0; i<4; i++) for (j=0;j<4;j++) C[i]+=A[j]*B[j][i];
    x[P]=C[0];
    y[P]=C[1];
    z[P]=C[2];
    }
void Z_Matrix(GLsizei p){
    GLfloat A[4]={x[p], y[p], z[p], 1};
    GLfloat B[4][4]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
    GLfloat C[4]={0,0,0,1};
    GLsizei i,j;
    if(choiceZ==7){
        for(i=0; i<4; i++)if(i==0||i==1)B[i][i]=cos(arc);
            B[0][1]=sin(arc);
            B[1][0]=-sin(arc);
            }
    if(choiceZ==9){
        for(i=0; i<4; i++)if(i==0||i==1)B[i][i]=cos(arc);
            B[0][1]=-sin(arc);
            B[1][0]=sin(arc);
            }
        for(i=0; i<4; i++) for (j=0;j<4;j++) C[i]+=A[j]*B[j][i];
        x[p]=C[0];
        y[p]=C[1];
        z[p]=C[2];
    }
void RenderScene(void){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 색과 깊이에 대한 버퍼를 초기화한다.
    glPushMatrix();
    glRotatef(xRot,1,0,0);
    glRotatef(zRot,0,0,1);
    glBegin(GL_POLYGON); DRAW1 DRAW2 DRAW3 DRAW4 glEnd();
    glBegin(GL_POLYGON); DRAW4 DRAW3 DRAW6 DRAW5 glEnd();
    glBegin(GL_POLYGON); DRAW5 DRAW6 DRAW7 DRAW8 glEnd();
    glBegin(GL_POLYGON); DRAW8 DRAW7 DRAW2 DRAW1 glEnd();
    glBegin(GL_POLYGON); DRAW1 DRAW4 DRAW5 DRAW8 glEnd();
    glBegin(GL_POLYGON); DRAW2 DRAW7 DRAW6 DRAW3 glEnd();
    glBegin(GL_POLYGON); BASE_BLOCK1 BASE_BLOCK2 BASE_BLOCK3 BASE_BLOCK4 glEnd();
    glBegin(GL_POLYGON); BASE_BLOCK4 BASE_BLOCK3 BASE_BLOCK6 BASE_BLOCK5 glEnd();
    glBegin(GL_POLYGON); BASE_BLOCK5 BASE_BLOCK6 BASE_BLOCK7 BASE_BLOCK8 glEnd();
    glBegin(GL_POLYGON); BASE_BLOCK8 BASE_BLOCK7 BASE_BLOCK2 BASE_BLOCK1 glEnd();
    glBegin(GL_POLYGON); BASE_BLOCK1 BASE_BLOCK4 BASE_BLOCK5 BASE_BLOCK8 glEnd();
    glBegin(GL_POLYGON); BASE_BLOCK2 BASE_BLOCK7 BASE_BLOCK6 BASE_BLOCK3 glEnd();
    glBegin(GL_POLYGON); ligHt1 ligHt2 ligHt3 ligHt4 glEnd();
    glBegin(GL_POLYGON); ligHt4 ligHt3 ligHt6 ligHt5 glEnd();
    glBegin(GL_POLYGON); ligHt5 ligHt6 ligHt7 ligHt8 glEnd();
    glBegin(GL_POLYGON); ligHt8 ligHt7 ligHt2 ligHt1 glEnd();
    glBegin(GL_POLYGON); ligHt1 ligHt4 ligHt5 ligHt8 glEnd();
    glBegin(GL_POLYGON); ligHt2 ligHt7 ligHt6 ligHt3 glEnd();
    glBegin(GL_POLYGON); shaDow1 shaDow2 shaDow3 shaDow4 glEnd();
    glBegin(GL_POLYGON); shaDow4 shaDow3 shaDow6 shaDow5 glEnd();
    glBegin(GL_POLYGON); shaDow5 shaDow6 shaDow7 shaDow8 glEnd();
    glBegin(GL_POLYGON); shaDow8 shaDow7 shaDow2 shaDow1 glEnd();
    glBegin(GL_POLYGON); shaDow1 shaDow4 shaDow5 shaDow8 glEnd();
    glBegin(GL_POLYGON); shaDow2 shaDow7 shaDow6 shaDow3 glEnd();
    glPopMatrix();
    glutSwapBuffers();
    }
void SetupRC(){
    glClearColor(0, 0, 0, 1);   // 배경색은 까만색
    glEnable(GL_DEPTH_TEST);   // 앞 뒤를 구분하는 명령어
    glFrontFace(GL_CW);       // CCW를 기본으로 지정하는 명령어.
    }
void SpecialKeys(int key, int x, int y){
    int i,j;
    if (key==GLUT_KEY_F3)for(i=0; i<8; i++)ScaleMatrix(i,1);
    if (key==GLUT_KEY_F4)for(i=0; i<8; i++)ScaleMatrix(i,3);

    if (key==GLUT_KEY_HOME)zRot-=1;
    if (key==GLUT_KEY_END) zRot+=1;
    if (key==GLUT_KEY_PAGE_UP){
        j=8;
        if(LP_z[0]>450) j=0;
        for(i=0; i<8; i++)move_matrix(i, j);
        }

    if (key==GLUT_KEY_PAGE_DOWN){
        j=2;
        if(LP_z[0]<165) j=0;
        for(i=0; i<8; i++) move_matrix(i, j);
        }

    if (key==GLUT_KEY_UP){
        TimeSaver=TimeSwitch;
        TimeSwitch=0;
        if(TimeSaver<2) choiceX=2;
        else {
            choiceX=2;
            choiceY=0;
            choiceZ=0;
            }
        }
    if (key==GLUT_KEY_DOWN){
            TimeSaver=TimeSwitch;
            TimeSwitch=0;
            if(TimeSaver<2) choiceX=8;
            else {
                choiceX=8;
                choiceY=0;
                choiceZ=0;
            }
        }
    if (key==GLUT_KEY_LEFT){
            TimeSaver=TimeSwitch;
            TimeSwitch=0;
            if(TimeSaver<2) choiceY=6;
            else {
                choiceX=0;
                choiceY=6;
                choiceZ=0;
            }
        }
    if (key==GLUT_KEY_RIGHT){
            TimeSaver=TimeSwitch;
            TimeSwitch=0;
            if(TimeSaver<2) choiceY=4;
            else {
                choiceX=0;
                choiceY=4;
                choiceZ=0;
            }
        }
    if (key==GLUT_KEY_F1){
            TimeSaver=TimeSwitch;
            TimeSwitch=0;
            if(TimeSaver<2) choiceZ=9;
            else {
                choiceX=0;
                choiceY=0;
                choiceZ=9;
            }
        }
    if (key==GLUT_KEY_F2){
            TimeSaver=TimeSwitch;
            TimeSwitch=0;
            if(TimeSaver<2) choiceZ=7;
            else {
                choiceX=0;
                choiceY=0;
                choiceZ=7;
            }
        }
    if (key==GLUT_KEY_F12) k=1;

    }
void ChangeSize(GLsizei w, GLsizei h) {
    GLfloat ratio=(GLfloat)h/(GLfloat)w;
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w<=h)
 glOrtho(-CliPingSize,CliPingSize,-CliPingSize*ratio,CliPingSize*ratio,-CliPingSize,CliPingSize);
    else
 glOrtho(-CliPingSize/ratio,CliPingSize/ratio,-CliPingSize,CliPingSize,-CliPingSize,CliPingSize);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    }
void TimeSquare(GLsizei value){
    int i,j;
    TimeSwitch++;
    if(k==0) {
        START_auto++;
        if(START_auto>1   && START_auto<70)   xRot-=1;
        if(START_auto>69  && START_auto<140)  zRot-=1;
        if(START_auto>139 && START_auto<230) for(i=0;i<8;i++)move_matrix(i,8);
        if(START_auto>300) {choiceZ=7; zRot-=0.1;}
        if(START_auto>320 && START_auto<370)  for(i=0;i<8;i++)move_matrix(i,2);
        if(START_auto>370 && START_auto<420)  for(i=0;i<8;i++)move_matrix(i,8);
        if(START_auto>420) START_auto=320;
        }

    for(i=0;i<8;i++) revision(i);
    for(i=0;i<8;i++) for(j=0; j<2; j++) ShadowMask(i , j);

    for(i=0;i<5;i++) {
        if(color_counter[i]==0) color[i]+=0.01;
        if(color[i]>0.7)color_counter[i]=1;

        if(color_counter[i]==1) color[i]-=0.01;
        if(color[i]<0.5)color_counter[i]=0;
        }
    glutPostRedisplay();
    glutTimerFunc(33,TimeSquare,1);
    }
void revision (GLsizei Crack){
    (choiceX==8||choiceX==2)?X_Matrix(Crack):NULL;
    (choiceY==4||choiceY==6)?Y_Matrix(Crack):NULL;
    (choiceZ==7||choiceZ==9)?Z_Matrix(Crack):NULL;
    }
void main(void){
    printf("t light move : PageUp,  PageDown  nn");
    printf("t square move : F1,  up,  down,  left,  right, F2 n");
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(650,650);
    glutInitWindowPosition(10,10);
    glutCreateWindow("Opia");
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);
    glutTimerFunc(33, TimeSquare, 1);
    glutSpecialFunc(SpecialKeys);
    SetupRC();
    glutMainLoop(); // main함수를 반복시킨다.
    }