OpenGL Программирование/Рендеринг Текста в Современном OpenGL 01: различия между версиями

Содержимое удалено Содержимое добавлено
Нет описания правки
м <source> -> <syntaxhighlight> (phab:T237267)
 
Строка 48:
Использовать FreeType очень просто. Следующие 2 строчки кода должны быть добавлены в начала вашего кода, чтобы подключить заголовочные файлы:
 
<sourcesyntaxhighlight lang="cpp">
#include <ft2build.h>
#include FT_FREETYPE_H
</syntaxhighlight>
</source>
 
Перед использованием других функция FreeType необходимо инициализировать библиотеку:
 
<sourcesyntaxhighlight lang="cpp">
FT_Library ft;
 
Строка 62:
return 1;
}
</syntaxhighlight>
</source>
 
= Шрифты и глифы =
Строка 73:
Например, чтобы загрузить обычный шрифт FreeSans из текущей директории нужно:
 
<sourcesyntaxhighlight lang="cpp">
FT_Face face;
 
Строка 80:
return 1;
}
</syntaxhighlight>
</source>
 
После загрузки face остаётся еще один параметр, который можно установить.
Это размер шрифта. Чтобы установить высоту в 48 пикселей необходимо использовать:
 
<sourcesyntaxhighlight lang="cpp">
FT_Set_Pixel_Sizes(face, 0, 48);
</syntaxhighlight>
</source>
 
Face - это просто набор [[w:Глиф|глифов]].
Строка 98:
Например, давайте возьмем из шрифта глиф символа 'X':
 
<sourcesyntaxhighlight lang="cpp">
if(FT_Load_Char(face, 'X', FT_LOAD_RENDER)) {
fprintf(stderr, "Невозможно загрузить символ 'X'\n");
return 1;
}
</syntaxhighlight>
</source>
 
Функция <code>FT_Load_Char()</code> заполнит информацию об этом символе в "слоте для глифов" шрифта, доступ к которому можно получить с помощью <code>face->glyph</code>.
Строка 109:
Каждый раз писать <code>face->glyph</code> очень утомительно. А если ссылка на <code>face->glyph</code> не изменяется, то проще будет создать сокращение:
 
<sourcesyntaxhighlight lang="cpp">
FT_GlyphSlot g = face->glyph;
</syntaxhighlight>
</source>
 
В уроке мы будем использовать следующую информацию:
Строка 142:
But it is also possible to combine the vertex and texture coordinates into a single four-dimensional vector, and have the vertex shader split it in two:
 
<sourcesyntaxhighlight lang="glsl">
#version 120
 
Строка 152:
texcoord = coord.zw;
}
</syntaxhighlight>
</source>
 
Although this might not be directly obvious,
Строка 162:
The fragment shader is as follows:
 
<sourcesyntaxhighlight lang="glsl">
#version 120
 
Строка 172:
gl_FragColor = vec4(1, 1, 1, texture2D(tex, texcoord).r) * color;
}
</syntaxhighlight>
</source>
 
This fragment shader allows us to render transparent text, and should be used in combination with blending:
 
<sourcesyntaxhighlight lang="cpp">
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
</syntaxhighlight>
</source>
 
= Rendering lines of text =
Строка 186:
First, we will use a single texture object to render all the glyphs:
 
<sourcesyntaxhighlight lang="cpp">
GLuint tex;
glActiveTexture(GL_TEXTURE0);
Строка 192:
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(uniform_tex, 0);
</syntaxhighlight>
</source>
 
To prevent certain artifacts when a character is not rendered exactly on pixel boundaries,
we should clamp the texture at the edges, and enable linear interpolation:
 
<sourcesyntaxhighlight lang="cpp">
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Строка 203:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
</syntaxhighlight>
</source>
 
It is also very important to disable the default 4-byte alignment restrictions that OpenGL uses
Строка 211:
To ensure there are no alignment restrictions, we have to use this line:
 
<sourcesyntaxhighlight lang="cpp">
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
</syntaxhighlight>
</source>
 
We also need to set up a vertex buffer object for our combined vertex and texture coordinates:
 
<sourcesyntaxhighlight lang="cpp">
GLuint vbo;
glGenBuffers(1, &vbo);
Строка 223:
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(attribute_coord, 4, GL_FLOAT, GL_FALSE, 0, 0);
</syntaxhighlight>
</source>
 
We now have everything in place to render a line of text.
Строка 232:
We repeat this for all the characters in the line.
 
<sourcesyntaxhighlight lang="cpp">
void render_text(const char *text, float x, float y, float sx, float sy) {
const char *p;
Строка 271:
}
}
</syntaxhighlight>
</source>
 
The function <code>render_text()</code> takes 5 arguments: the string to render, the x and y start coordinates, and the x and y scale parameters.
Строка 277:
Let's look at the <code>display()</code> function which draws the whole screen:
 
<sourcesyntaxhighlight lang="cpp">
void display() {
glClearColor(1, 1, 1, 1);
Строка 295:
glutSwapBuffers();
}
</syntaxhighlight>
</source>
 
We start by clearing the screen to white, and setting the font color to black.
Строка 312:
Add the following to the <code>display()</code> function:
 
<sourcesyntaxhighlight lang="cpp">
FT_Set_Pixel_Sizes(face, 0, 48);
render_text("The Small Texture Scaled Fox Jumps Over The Lazy Dog",
Строка 325:
render_text("The Tiny Font Sized Fox Jumps Over The Lazy Dog",
-1 + 8 * sx, 1 - 250 * sy, sx, sy);
</syntaxhighlight>
</source>
 
You should see that despite the linear texture interpolation of OpenGL,
Строка 339:
we just change the uniform color to our liking:
 
<sourcesyntaxhighlight lang="cpp">
FT_Set_Pixel_Sizes(face, 0, 48);
render_text("The Solid Black Fox Jumps Over The Lazy Dog",
Строка 357:
render_text("The Transparent Green Fox Jumps Over The Lazy Dog",
-1 + 18 * sx, 1 - 440 * sy, sx, sy);
</syntaxhighlight>
</source>
 
Exercises: