Computer Graphics

Chapter06. 디스플레이 리스트

CodeJB 2021. 5. 31. 18:25

디스플레이 리스트

Display 콜백함수에서 계산을 줄이기 위한 그래픽 속도 향상 솔루션
  • Display 콜백함수에서 Object의 색상 점 등을 계산하면 display 시의 load가 커짐
  • Object의 수가 많아지고, 복잡해 질 수록 속도 저하
  • Object를 미리 만들어 list에 넣어 두고, 콜백 함수에서는 이를 재사용

예시 코드

int list_id // 전역변수 생성

void createList(){
    list_id = glGenLists(1); // list 1개 생성
    glNewList(list_id, GL_COMPILE); //list의 시작, 컴파일(계산)만 수행함
    	glBegin(GL_POLYGON);
        	//그릴 내용
        glEnd();
    glEndList();//리스트 종료
}

createList(); //Object리스트 생성

glCallList(list_id);// Object List에 있는 내용 그리기, display 콜백함수 등에서 호출

3차원 큐브 그리기 + 디스플레이 리스트 적용

#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include <iostream>

#define _WINDOW_WIDTH 1200
#define _WINDOW_HEIGHT 1200

//GLfloat MyVertices[8][3] = {{-0.25,-0.25,0.25},{-0.25,0.25,0.25},{0.25,0.25,0.25},{0.25,-0.25,0.25},{-0.25,-0.25,-0.25},{-0.25,0.25,-0.25},{0.25,0.25,-0.25},{0.25,-0.25,-0.25}}; //3차원 공간 상의 각 정점, 너비가 0.5인 큐브
GLfloat defaultCube[8][3] = {{-0.5,-0.5,0.5},{-0.5,0.5,0.5},{0.5,0.5,0.5},{0.5,-0.5,0.5},{-0.5,-0.5,-0.5},{-0.5,0.5,-0.5},{0.5,0.5,-0.5},{0.5,-0.5,-0.5}}; //3차원 공간 상의 각 정점, 너비가 1인 큐브

GLfloat MyColor[8][3] = {{0.2,0.2,0.2},{1.0,0.0,0.0},{1.0,1.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{1.0,0.0,1.0},{1.0,1.0,1.0},{0.0,1.0,1.0}};
//각 정점마다 색깔

int list_id;

void drawCube(GLfloat size, GLfloat x, GLfloat y, GLfloat z){
    //defaultCube를 이용해서 새로운 큐브를 만듬
    GLfloat MyCube[8][3];
    for(int i = 0; i < 8; i++){
        MyCube[i][0] = size * defaultCube[i][0] + x; //크기가 늘어난 상태로. 이동
        MyCube[i][1] = size * defaultCube[i][1] + y; // 0은 x축 1은 y축 z는 z축
        MyCube[i][2] = size * defaultCube[i][2] + z;
    }
    
    int index[6][4] = {{0,3,2,1},{2,3,7,6},{7,4,5,6},{1,2,6,5},{0,3,7,4},{0,4,5,1}};
    
    for(int i = 0; i < 6; i++){
        int index0 = index[i][0];
        int index1 = index[i][1];
        int index2 = index[i][2];
        int index3 = index[i][3];
        glBegin(GL_POLYGON);
            glColor3fv(MyColor[index0]); glVertex3fv(MyCube[index0]);
            glColor3fv(MyColor[index1]); glVertex3fv(MyCube[index1]);
            glColor3fv(MyColor[index2]); glVertex3fv(MyCube[index2]);
            glColor3fv(MyColor[index3]); glVertex3fv(MyCube[index3]);
        glEnd();
    }
}

void createList(){
    list_id = glGenLists(1);
    
    glNewList(list_id, GL_COMPILE);//계산을 미리 해놓고 리스트에 저장해라
        drawCube(0.1, 0, 0,0);
        drawCube(0.1, 0.8, 0, 0);
        drawCube(0.1, 0 , 0.8, 0);
        drawCube(0.1, 0 , 0, 0.8);
        drawCube(0.1, 0.8, 0.8, 0.8);
    glEndList();
}

void MyDisplay(){
    glClear(GL_COLOR_BUFFER_BIT);
    glCallList(list_id);//리스트에 있는 내용을 그려라
    glFlush();
}

void MyReshape(int width, int height){
    glViewport(0, 0, width, height);
    GLfloat f_w = (GLfloat)width / (GLfloat)_WINDOW_WIDTH;
    GLfloat f_h = (GLfloat)height / (GLfloat)_WINDOW_HEIGHT;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1.0*f_w, 1.0*f_w, -1.0*f_h, 1.0*f_h, -2, 2);
    gluLookAt(0.5, 0.5, 1, 0, 0, 0, 0, 1, 0);
}

int main(int argc, char ** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB); //이중 버퍼링을 위해 이중버퍼 사용
    glutInitWindowSize(_WINDOW_WIDTH, _WINDOW_HEIGHT);
    glutCreateWindow("Cube Drawing");
    
    //콜백함수
    glutDisplayFunc(MyDisplay);
    glutReshapeFunc(MyReshape);
    
    //디스플레이 리스트
    createList();//함수 호출
    
    glutMainLoop();
}