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. 15. 18:00

■ OpenGL: Modern OpenGL Tutorial Text Rendering 01[1]


1. 소개 

OpenGL에서 text를 다루는 기능들이 별루 없다는 것을 알 수 있다. 그 이유는 세상에는 너무 많은 폰트들이 존재하기 때문에 사이즈와 폰트들의 수등을 전부 표현하기 어렵기 때문이라고 한다. (요약) 하지만 OpenGL에서 텍스트를 표현하기 위해 다음과 같은 방법들이 존재한다.

가. GL_LINES를 이용한 문자 그리기

나. GL_TRIANGLES를 이용한 문자 모양 채우기

다. 3D 문자 표현

라. 텍스쳐를 사용한 사각형에 문자 그리기

마. 텍스쳐가 적용된 사각형을 이용해 문장이나 절 그리기

바. glDrawPixels()로 framebuffer에 직접 텍스트그리기(OpenGL ES 2.0에서는 불가능하다고 함)


이 tutorial 에서는 사각형에 텍스쳐를 입혀 문장 또는 한글자를 표현함.

- 이 기술은 굉장히 유용함. 보고 계신 분들이 텍스쳐의 속성을 이해하게 되면 텍스트를 랜더링하는 가장 빠른 방법 중에 하나가 될 것임.

- 여기서 표현되는 텍스트는 보시는 분들의 워드프로세서 또는 브라우저(Browser)에 따라 품질이 다를 수 있음


2. 무료 라이브러리(FreeType Library)

OpenGL에서 텍스트를 표현하기 위해 

step 1: 폰트 정보를 읽고

step 2: 해당 폰트를 형식에 변환해서 저장해야 함

위 방법을 지원하는 다양한 라이브러리가 있지만 잘 알려진 FreeType 라이브러리를 사용할 거야

이 라이브러리는 많은 폰트 포멧을 지원하고 TrueType과 OpenType를 포함한다고 함

TrueType: 컴퓨터에서 지원하는 타입

OpenType: 애플과 마이크로소프트 사에서 제공하는 타입

FreeType 라이브러리는 텍스트 레이아웃 엔진이 아니여라. 때문에 자동적으로 diacritics를 렌더링할 수 없으며, ligatures를 사용는거 또는 다른 복잡한 인쇄기능을 구현할 수가 없지롱. 만약 이 기능들이 필요하면 Pango라는 텍스트 레이아웃 라이브러리를 사용하면됨


사용방법

#include <ft2build.h>

#include FT_FREETYPE_H


FreeType 기능을 사용하기 위해 라이브러리 초기화 방법

FT_Library ft;

 

if(FT_Init_FreeType(&ft)) {

  fprintf(stderr, "Could not init freetype library\n");

  return 1;

}


3. 폰트와 Glyphs(글립스)

잠깐 아놔 글립스가 모야!!! 난 처음 본다. 급하게 검색해서 이해하자. TrueType 폰트를 구성하는 하나하나를 Glyph라고 한다. 요 아이는 수학적 함수를 통해 폰트의 외각선을 계산하기 때문에 비트맵 폰트에서 발생하는 계단현상을 극복하고 부드러운 폰트외각선을 그릴 수 있다는 것이 장점이넹..그렇군!!!



3.1 폰트 설정 및 정보 가져오기

폰트는 종류와 모양을 설정할 수 있는 그 방법은 다음과 같음 

- 폰트체 설정: Times New Roman

- 폰트 모양 설정: regular, bold, italic, and other styles

FT_Face face;//폰트를 읽어서 저장하는 face 형 변수 

if(FT_New_Face(ft, "FreeSans.ttf", 0, &face)) { // FreeSan 체 사용

  fprintf(stderr, "Could not open font\n");

  return 1;

}

FreeType library를 사용할 경우 사용자가 원하는 폰트에 대한 파일 경로를 다 써서 읽어야 함

이때 해당 폰트를 읽어서 저장하는 함수가 "face"임


- 폰트 사이즈 설정(폰트에서 사이즈 설정만 가능)

FT_Set_Pixel_Sizes(face, 0, 32); //폰트 사이즈를 32로 설정


3.2 Glyphs 값 가져오기

face에서 문자 Z에 대한 glyph 정보를 얻을라면 다음과 같이 쓰면 된다.

여기서 glyph 정보란 위 첫번째 그림과 같이 폰트를 그리기 위해 필요한 정보들이다.


if(FT_Load_Char(face, 'Z', FT_LOAD_RENDER)) {

  fprintf(stderr, "Could not load character 'Z'\n");

  return 1;

}


FT_LOAD_RENDER: FreeType는 8bit 그레이 스케일 이미지로 만들어짐, 이 정보는 face->glyph->bitmap로 얻을 수 있음


이렇게 얻어진 face에는 glyph slot에 대한 정보를 가지고 있으며 이 정보를 얻기 위해서는 FT_GlyphSlot 형의 변수를 선언하여 접근함

: 이런 줸장 또 glyph slot는 머야 ㅡㅡ^ 다음과 같다.

The glyph image is always stored in a special object called a glyph slot.

글립 이미지는 glyph slot라는 특별한 객체에 항상 저장된다고 한다. 즉 glyph slot는 폰트를 이루는 하나의 글자이미지 정보를 저장한 욘속이다. 


FT_GlyphSlot g=face->glyph;

========================================================================================

g->bitmap.buffer//이전 설정된 폰트사이즈로 그려진 폰트의 8bit 그레이스케일 이미지에 대한 포인터 

Pointer to the 8-bit greyscale image of the glyph, rendered at the previously selected font size.

g->bitmap.width  

Width of the bitmap, in pixels.

g->bitmap.rows 

Height of the bitmap, in pixels.

g->bitmap_left 

Horizontal position relative to the cursor, in pixels.

g->bitmap_top 

Vertical position relative to the baseline, in pixels.

g->advance.x //다음 문자와의 평행 거리?

How far to move the cursor horizontally for the next character, in 1/64 pixels.

g->advance.y //다음 문자와의 수직 거리? 거의 0이구만

How far to move the cursor vertically for the next character, in 1/64 pixels, almost always 0.

========================================================================================

왜 폰트만 가져다 찍으면 되지 위와 같이 이미지 정보를 가져와서 우짤라고?!! 머 이유가 있는데 모든 Glyph 들은 동일한 사이즈를 가지고 있지 않다고 하넹. FreeType는 이미지 폰트를 그리는데 충분한 문자 visible parts를 가지고 있다고 함. 머 폰트 마다 베이스 라인 잡고 포지션닝 하기 위해 위와 같은 정보가 필요하다고 한다. 난 폰트만 가져다가 찍고 싶은데 배울께 많다. 아마 지금 까지 읽으신 분들도 지루하실듯... 킁킁


4. Shaders

와 쉐이더~~~ 모닝 이아이는 또 모니~~

명사: 

1. 물체의 색상, specularity(반사성), displacement(변위:이동 같은거)와 같은 장면에서 물체의 표면상태를 결정짓는 속성들. surface shader, volume shaders, displacement shaders, 그리고 light shaders 등을 포함하는 다양하고 많은 유형들을 가지고 있다.

2. shading을 결정짓는 속성들(blinn, phong, metal 등).

3. 3D 애니메이션에서 물체의 질감부분에 대한 여러 가지 특성과 기능을 관리하고 제어하는 사람.

[네이버 지식백과] 셰이더 [shader] (만화애니메이션사전, 2008.12.30, 한국만화영상진흥원)

그렇다고 한다. 


텍스트 랜더링에서 기본적인 쉐이더를 사용할거랍니다. 기본적으로 텍스트는 2D 이기 때문에 이를 랜더하기 위해서는 다음과 같은 요소가 필요함

- attribute vec2 for vertices // 꼭지점에 관한 속성

- attribute vec2 for texture coordinates. //텍스쳐 좌표에 대한 속성

위 두요소를 4차원 배열에다가 합쳐서 넣는것이 가능하며, vertex shader는 두개로 분활할 수 있다고 함(아래 예제 보면 4차원에서 2차원 배열로 각자 나눠주는 것을 확인할 수 있음)


#version 120

 

attribute vec4 coord; //4차원 배열 

varying vec2 texcoord; //2차원 배열

 

void main(void) {

  gl_Position = vec4(coord.xy, 0, 1); // 포지션에 관한 정보는 4차원에서 x,y 값을 저장

  texcoord = coord.zw; // 텍스쳐 좌료 값은 4차원에서 z,w 값을 저장

}


확실하지 않지만 alpha values를 가지는 텍스쳐를 사용하여 텍스트를 그리는 방법이 제일 좋다고 생각함

RGB 컬러는 모든 픽셀에 동일하게 적용됨. 알파값이 투명도 구만

- 알파값 1(opaque)이면 색상이 적용된 폰트가 보임, 0(transparent)이면 배경색이 보임, 당연히 1과 0 사이 알파값을 가지면 배경색과 폰트색이 혼합되서 나타남


그럼 fragment Shader 값은 다음과 같이 표현될 수 있음

#version 120

 

varying vec2 texcoord; // glyph 꼭지점 집합과 텍스쳐 좌표 저장버퍼

uniform sampler2D tex; // 샘플 2D tex

uniform vec4 color; // 컬러 4차원 배열

 

void main(void) {

  gl_FragColor = vec4(1, 1, 1, texture2D(tex, texcoord).a) * color; // vec4( <-- 머야 이욘속!!!

//무튼 쉐이더의 색상 조각은 위와 같이 정의된다고 함

}

Fragment shader는 텍스트가 투명하게 보일수 있게 해 줌. 이 욘속은 다음의 OpenGL 함수와 짝짝꿍해야 함

glEnable(GL_BLEND);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


5. Rendering Lines of Text(텍스트 라인 그리기)

힘내 거의 다왔어 마지막이야

우선 해당 싸이트에서 언급한것들은 핵심에 대해서만 예기하고 있다 고로 사용된 예제 파일을 먼저 받아 보면서 이해 하고 필요한 헤더파일을 더 추가 시켜야 한다. 

- http://sourceforge.net/projects/ogl-math/       (glm-0.9.5.3 다운)

- https://gitorious.org/wikibooks-opengl/modern-tutorials/source/0b75884b849e8144899b72097d48f7f034c6d4e4:   (예제파일)

파일들은 언능 받는게 좋다. 왜냐면 링크가 언제 떨어질지 모르잖옹!! +_+

예제 파일 폴더

..............\wikibooks-opengl-modern-tutorials\text01_intro

여기가 사용된 파일인듯!!!

헤더 파일이 더 많이 사용되었는뎅


#include <GL/glew.h> // 요아이 셋팅

#include <GL/glut.h>


#include <glm/glm.hpp>  // 요아이 셋팅

#include <glm/gtc/matrix_transform.hpp>

#include <glm/gtc/type_ptr.hpp>


#include <ft2build.h>

#include FT_FREETYPE_H


#include "../common/shader_utils.h"  // 요아이 셋팅


요 아이들 먼저 포함시키자. 어떻게 하는지 알지? 느낌아니깐~~

C:\Program Files (x86)\Windows Kits\8.1\Include\um

나는 윈도우 8이니깐 위 폴더에 glm 폴더를 복사 해 넣는다. 

glew 는 아래 블로거 선생님이 가르쳐 주셨다. 

http://blog.naver.com/empirespony?Redirect=Log&logNo=30034286252

아마 보시면서 한숨 나올듯 폰트 하나 찍는데 너무 오래 걸린다. 줸장할 하루를 다 소비하는 듯한 느낌.


우선 소스 전체를 보자꾸낭(오픈 소스 올렸는데 저작권이 걸리라나 아시는 분 말씀해 주세요. ㅠㅠ)

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
#include <GL/glew.h>
#include <GL/glut.h>
 
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
 
#include <ft2build.h>
#include FT_FREETYPE_H
 
#include "../common/shader_utils.h"
 
GLuint program;
GLint attribute_coord;
GLint uniform_tex;
GLint uniform_color;
 
struct point {
    GLfloat x;
    GLfloat y;
    GLfloat s;
    GLfloat t;
};
 
GLuint vbo;
 
FT_Library ft;
FT_Face face;
 
const char *fontfilename;
 
int init_resources() {
    /* Initialize the FreeType2 library */
    if (FT_Init_FreeType(&ft)) {
        fprintf(stderr, "Could not init freetype library\n");
        return 0;
    }
 
    /* Load a font */
    if (FT_New_Face(ft, fontfilename, 0, &face)) {
        fprintf(stderr, "Could not open font %s\n", fontfilename);
        return 0;
    }
 
    program = create_program("text.v.glsl""text.f.glsl");
    if(program == 0)
        return 0;
 
    attribute_coord = get_attrib(program, "coord");
    uniform_tex = get_uniform(program, "tex");
    uniform_color = get_uniform(program, "color");
 
    if(attribute_coord == -1 || uniform_tex == -1 || uniform_color == -1)
        return 0;
 
    // Create the vertex buffer object
    glGenBuffers(1, &vbo);
 
    return 1;
}
 
/**
 * Render text using the currently loaded font and currently set font size.
 * Rendering starts at coordinates (x, y), z is always 0.
 * The pixel coordinates that the FreeType2 library uses are scaled by (sx, sy).
 */
void render_text(const char *text, float x, float y, float sx, float sy) {
    const char *p;
    FT_GlyphSlot g = face->glyph;
 
    /* Create a texture that will be used to hold one "glyph" */
    GLuint tex;
 
    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glUniform1i(uniform_tex, 0);
 
    /* We require 1 byte alignment when uploading texture data */
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
    /* Clamping to edges is important to prevent artifacts when scaling */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
    /* Linear filtering usually looks best for text */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
    /* Set up the VBO for our vertex data */
    glEnableVertexAttribArray(attribute_coord);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(attribute_coord, 4, GL_FLOAT, GL_FALSE, 0, 0);
 
    /* Loop through all characters */
    for (p = text; *p; p++) {
        /* Try to load and render the character */
        if (FT_Load_Char(face, *p, FT_LOAD_RENDER))
            continue;
 
        /* Upload the "bitmap", which contains an 8-bit grayscale image, as an alpha texture */
        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, g->bitmap.width, g->bitmap.rows, 0, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);
 
        /* Calculate the vertex and texture coordinates */
        float x2 = x + g->bitmap_left * sx;
        float y2 = -y - g->bitmap_top * sy;
        float w = g->bitmap.width * sx;
        float h = g->bitmap.rows * sy;
 
        point box[4] = {
            {x2, -y2, 0, 0},
            {x2 + w, -y2, 1, 0},
            {x2, -y2 - h, 0, 1},
            {x2 + w, -y2 - h, 1, 1},
        };
 
        /* Draw the character on the screen */
        glBufferData(GL_ARRAY_BUFFER, sizeof box, box, GL_DYNAMIC_DRAW);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 
        /* Advance the cursor to the start of the next character */
        x += (g->advance.x >> 6) * sx;
        y += (g->advance.y >> 6) * sy;
    }
 
    glDisableVertexAttribArray(attribute_coord);
    glDeleteTextures(1, &tex);
}
 
void display() {
    float sx = 2.0 / glutGet(GLUT_WINDOW_WIDTH);
    float sy = 2.0 / glutGet(GLUT_WINDOW_HEIGHT);
 
    glUseProgram(program);
 
    /* White background */
    glClearColor(1, 1, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT);
 
    /* Enable blending, necessary for our alpha texture */
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
    GLfloat black[4] = { 0, 0, 0, 1 };
    GLfloat red[4] = { 1, 0, 0, 1 };
    GLfloat transparent_green[4] = { 0, 1, 0, 0.5 };
 
    /* Set font size to 48 pixels, color to black */
    FT_Set_Pixel_Sizes(face, 0, 48);
    glUniform4fv(uniform_color, 1, black);
 
    /* Effects of alignment */
    render_text("The Quick Brown Fox Jumps Over The Lazy Dog", -1 + 8 * sx, 1 - 50 * sy, sx, sy);
    render_text("The Misaligned Fox Jumps Over The Lazy Dog", -1 + 8.5 * sx, 1 - 100.5 * sy, sx, sy);
 
    /* Scaling the texture versus changing the font size */
    render_text("The Small Texture Scaled Fox Jumps Over The Lazy Dog", -1 + 8 * sx, 1 - 175 * sy, sx * 0.5, sy * 0.5);
    FT_Set_Pixel_Sizes(face, 0, 24);
    render_text("The Small Font Sized Fox Jumps Over The Lazy Dog", -1 + 8 * sx, 1 - 200 * sy, sx, sy);
    FT_Set_Pixel_Sizes(face, 0, 48);
    render_text("The Tiny Texture Scaled Fox Jumps Over The Lazy Dog", -1 + 8 * sx, 1 - 235 * sy, sx * 0.25, sy * 0.25);
    FT_Set_Pixel_Sizes(face, 0, 12);
    render_text("The Tiny Font Sized Fox Jumps Over The Lazy Dog", -1 + 8 * sx, 1 - 250 * sy, sx, sy);
    FT_Set_Pixel_Sizes(face, 0, 48);
 
    /* Colors and transparency */
    render_text("The Solid Black Fox Jumps Over The Lazy Dog", -1 + 8 * sx, 1 - 430 * sy, sx, sy);
 
    glUniform4fv(uniform_color, 1, red);
    render_text("The Solid Red Fox Jumps Over The Lazy Dog", -1 + 8 * sx, 1 - 330 * sy, sx, sy);
    render_text("The Solid Red Fox Jumps Over The Lazy Dog", -1 + 28 * sx, 1 - 450 * sy, sx, sy);
 
    glUniform4fv(uniform_color, 1, transparent_green);
    render_text("The Transparent Green Fox Jumps Over The Lazy Dog", -1 + 8 * sx, 1 - 380 * sy, sx, sy);
    render_text("The Transparent Green Fox Jumps Over The Lazy Dog", -1 + 18 * sx, 1 - 440 * sy, sx, sy);
 
    glutSwapBuffers();
}
 
void free_resources() {
    glDeleteProgram(program);
}
 
int main(int argc, char *argv[]) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB);
    glutInitWindowSize(640, 480);
    glutCreateWindow("Basic Text");
 
    if (argc > 1)
        fontfilename = argv[1];
    else
        fontfilename = "FreeSans.ttf";
 
    GLenum glew_status = glewInit();
 
    if (GLEW_OK != glew_status) {
        fprintf(stderr, "Error: %s\n", glewGetErrorString(glew_status));
        return 1;
    }
 
    if (!GLEW_VERSION_2_0) {
        fprintf(stderr, "No support for OpenGL 2.0 found\n");
        return 1;
    }
 
    if (init_resources()) {
        glutDisplayFunc(display);
        glutMainLoop();
    }
 
    free_resources();
    return 0;
}
 

길다 폰트 하나 찍기 힘들구나 ㅎㅎ 그리고 OpenGL 2.0이라고 한다. 흠냐....난 그저 간단한 텍스쳐 매핑된 텍스트를 쓰고 싶었는데 간단한거면 좋았는데 ㅠㅠ


꼼꼼하게 뜯어 보면

GLuint tex; //

glActiveTexture(GL_TEXTURE0); //텍스쳐를 활성화 시킴

glGenTextures(1, &tex); // 텍스쳐 생성

glBindTexture(GL_TEXTURE_2D, tex); // 텍스쳐에 2D 텍스쳐를 묶어버림, 즉 2D 텍스쳐 할꼬얌

glUniform1i(uniform_tex, 0); // 단일 유니폼을 쓸꼬얌

텍스트를 랜더링 하기 전에 몇가지 초기화 해야 하는 일이 있다고 한다. 이것도 그 중에 하나로 단일 텍스쳐 오브렉트에 모든 glyphs를 렌더링 한다는 의미라고 한다.


문자가 픽셀 경계선에 정화하게 그려지지 않을경우 확실한 인공조형물(머 폰트겠지)을 보호하기 위해 우리는 edges에 텍스쳐를 묶어야 하며, 선형보간법을 허용해야 함

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //엣지 묶음

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//선형보간법

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


OpenGL에서 데이터와 텍스쳐를 업로딩 할때 사용하는 4byte alignment restrictions(정렬제한)은 기본값으로 설정되어 있는데 이것을 반드시 disable 시켜야 한다.

glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //GL_UNPACK_ALIGNMENT 하거라


다음으로 텍스쳐 좌표와 꼭지점 조합을 위해 꼭지점 버퍼 객체를 셋업함

GLuint vbo;

glGenBuffers(1, &vbo); //버퍼 만드려므나.

glEnableVertexAttribArray(attribute_coord); // 버텍스 속성 배열을 활성화 시키렴

glBindBuffer(GL_ARRAY_BUFFER, vbo); // 버텍스 배열을 묶어랏!

glVertexAttribPointer(attribute_coord, 4, GL_FLOAT, GL_FALSE, 0, 0);//좌표값을 가져오노라??


자 이제 텍스트를 출력하는 함수

void render_text(const char *text, float x, float y, float sx, float sy) 

//문자열, (x,y) 좌표, (sx, sy) 스케일 매개변수

step 1: 먼저 확실한 수평 베이스라인과 포지션 커서를 가지고 시작

step 2: 처음 문자 읽기

step 3: 텍스쳐에 읽힌 문자 옵로드

step 4: 포지션에 정확하게 그리기

step 5: 그리고 다음 텍스쳐 텍스트를 위해 커서 이동

위를 반복하면서 문자열 출력 


화면에 폰트를 그리기 위해 화면 픽셀에 일치하는 glyph 픽셀을 선택해야 함

void display() {

  glClearColor(1, 1, 1, 1);//white 배경

  glClear(GL_COLOR_BUFFER_BIT);

 

  GLfloat black[4] = {0, 0, 0, 1}; //폰트 컬러 깜장색

  glUniform4fv(uniform_color, 1, black);

 

  float sx = 2.0 / glutGet(GLUT_WINDOW_WIDTH);

  float sy = 2.0 / glutGet(GLUT_WINDOW_HEIGHT);

 

  render_text("The Quick Brown Fox Jumps Over The Lazy Dog", //요게 정확한 좌표에 폰트 매핑

              -1 + 8 * sx,   1 - 50 * sy,    sx, sy);

  render_text("The Misaligned Fox Jumps Over The Lazy Dog",//요건 불명확한 좌표에 폰트 매핑

              -1 + 8.5 * sx, 1 - 100.5 * sy, sx, sy);

 

  glutSwapBuffers();

}

결과를 보면 두번째 라인이 흐리게 보인다고 함

문자열 출력하는 부분을 자세히 보면 폰트 크기, 사이즈, 간격들이 어떻게 변화는지 확인할 수 있음 

해보자!!!



흠... 이전 simple text 보다 훨씬 보기 좋다. 우선 예제 파일을 가지고 요리 저리 라이브러리 헤더파일 그리고 dll 파일을 설정해 주고 나서 컴파일 하면 화면이 나온다. 나 같은 경우는 검정화면이 떠서 왜 그러지... 생각해 보다 창의 window 사이즈와 갱신 관련 문제인듯한 예상에 창을 끌고 모니터 밖으로 끌었다가 다시 모니터 안으로 데려오니 역시나 출력이 되는 구나... 소스 잘만 응용하면 좋은 폰트로 사용할 수 있을듯 하다. 


[1] http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Text_Rendering_01


'OpenGL' 카테고리의 다른 글

OpenGL: Very Simple Textured Text  (1) 2014.05.18
Visual Studio: Setting FreeType Library  (0) 2014.05.16
OpenGL: Text in OpenGL  (0) 2014.05.15
OpenGL: Selection and Picking  (0) 2014.05.05
OpenGL: Normal Vector  (0) 2014.05.04