BLOG main image
FunnyPR (32)
OpenGL (20)
PatternRecognition (7)
Tips (2)
XML (1)
DataMining (1)
Visitors up to today!
Today hit, Yesterday hit
daisy rss
tistory 티스토리 가입하기!
2014. 5. 18. 16:38

■OpenGL: Very Simple Textured Text[1]


하 FreeType 라이브러리를 하다 OpenGL 2.0이 필요해서 잠깐 스톱을 했다. 2.0을 써야 하다니 난 그냥 1.0기준의 OpenGL 로 간단한 폰트를 만들고 싶은데.....더 검색을 해 보았다. 


요번에는 참고 1 사이트를 기준으로 작업을 하고자 한다.


흠 우선 폰트를 TGA 파일로 만드는 구나. 그래픽 어플리케이션을 만들때 폰트들을 만들어서 쓴다고 한다. 간단하게 김프(Gimp)라는 어플을 사용한다고 함.


우선  김프 사용법은 다음에 또 알아보고 사이트에서 제공되는 font.tga파일을 통해 폰트를 찍어 보자. 


step 1: 텍스쳐 및 블렌딩 설정

1
2
3
4
5
glEnable(GL_TEXTURE_2D);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


step 2: 심플 폰트 코드 설정 

- 문자 맵 텍스쳐의 차원, 각 문자의 사이즈, 텍스쳐 ID

- TGA texture을 읽기 위해 NeHe Lesson 33에서 사용된 Texture 클래스를 사용함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
class Font
{
public:
    Font(GLuint init_texture, GLuint init_m_width, GLuint init_m_height,
           GLuint init_c_width, GLuint init_c_height);
     void drawText(GLfloat x, GLfloat y, GLint w, GLint h, char * text);
private:
    GLuint texture;
    GLint c_per_row;
 
    //bitmap setting
    GLuint m_width;
    GLuint m_height;
 
    //character settings
    GLuint c_width;
    GLuint c_height;
};
 
Font::Font(GLuint init_texture, GLuint init_m_width, 
                    GLuint init_m_height,
                    GLuint init_c_width, GLuint init_c_height) :
    texture(init_texture), m_width(init_m_width),
    m_height(init_m_height), c_width(init_c_width), 
    c_height(init_c_height)
    {
         c_per_row = m_width/c_width;
    }
 
void Font::drawText(GLfloat x, GLfloat y, GLint w, GLint h, char * text)
{
    glLoadIdentity();
    glTranslatef(x, y, 0.0f);
    glBindTexture( GL_TEXTURE_2D, texture );
    glBegin( GL_QUADS );
 
     //character location and dimensions
    GLfloat cx = 0.0f;
    GLfloat cy = 0.0f;
    GLfloat cw = float(w);
    GLfloat ch = float(h);
 
     //calculate how wide each character is in term of texture coords
     GLfloat dtx = float(c_width)/float(m_width);
     GLfloat dty = float(c_height)/float(m_height);
 
     for (char * c = text; *c != 0; c++, cx += cw) {
         // subtract the value of the first char in the character map
        // to get the index in our map
        int index = *c - '0';
        int row = index/c_per_row;
        int col = index%c_per_row;
 
        if (index < 0)
              throw GameException(__FILE__, __LINE__, "Character outside of font");
 
         // find the texture coords
         GLfloat tx = float(col * c_width)/float(m_width);
         GLfloat ty = float(row * c_height)/float(m_height);
 
         glTexCoord2d(tx,ty); glVertex2f(cx,cy);
         glTexCoord2d(tx+dtx,ty); glVertex2f(cx+cw,cy);
         glTexCoord2d(tx+dtx,ty+dty); glVertex2f(cx+cw,cy+ch);
         glTexCoord2d(tx,ty+dty); glVertex2f(cx,cy+ch);
    }
    glEnd();
}


step 3: 폰트 생성

1
2
3
Image image;
image.loadTGAImage("../images/font.tga");
font = new Font(Texture::build_texture(&image), 256, 256,19, 29);

Texture::bulid_texture 함수는 OpenGL texture ID를 반환함

TGA 폰트 이미지 사이즈가 256*256 그리고 각 폰트의 사이즈 19*29 임 


step 4: 폰트 그리기

1
2
glColor4f(1.0f, 0.0f, 0.0f, 1.0f); //make the text red
font->drawText(x, y, desired_width, desired_height, str);

폰트를 찍는데 요구된 사이즈에 좌표값 그리고 해당 str에 원하는 폰트를 넣어 프린트 하면 된다넹..


위와 같이 코딩해서 만들어 실행한 화면이 다음과 같다 라고 한다.



근데 말이지 난 해보니깐 저렇게 안나와 머징... 킁킁 배경이 투명이고 2D 지오메트릭에 이미지를 불러들인 텍스쳐를 4개의 꼭지점에 맵핑시키고 출력하면 배경과 같이 출력되던뎅...



저렇게 나오던뎅.. 소스도 약간수정했다.

우선 텍스쳐 맵핑에 대한 개념을 잡은거 같다. 

수정한 부분은 아래와 같음 그리고 참고사이트에 가면 소스파일이 있는데 다운 받아서 util.c, util,hpp, font.tga 파일을 써야 하는데 util.hpp 파일내에 FONT 클래스가 C++에서는 미리 정의된 클래스로 사용해선 안됨 때문에 적절하게 FONT 클래스 이름을 바꾸어서 사용해야함


1
2
3
4
        glTexCoord2d(tx, ty); glVertex2f(cx, cy + ch);
        glTexCoord2d(tx + dtx, ty); glVertex2f(cx + cw, cy + ch);
        glTexCoord2d(tx + dtx, ty + dty); glVertex2f(cx + cw, cy);
        glTexCoord2d(tx, ty + dty); glVertex2f(cx, cy);


왜 난 다르게 나올까... 한참 생각해 본다. 혹시 아시는 고수분들 계시면 뎃글 부탁 드립니다.


[1] http://www.andrewewhite.net/wordpress/2007/06/06/very-simple-text-in-opengl/