我只是试图将从Freetype加载的字形(字母Ě)作为位图图片显示在整个窗口上拉伸的OpenGL纹理上。结果在这里:
要获得此结果,我必须将极大的FT_Set_Pixel_Sizes设置为450,否则生成的图像看起来会更糟。
我正在使用M.M.的GLSLShader loader class。 Mobeen,GLEW,SDL2和GLM。
着色器/ shader.vert
#version 330 core
layout(location=0) in vec4 vVertex; //object space vertex
out vec2 vUV; // texture coordinates for texture lookup in the fragment shader
void main()
{
gl_Position = vec4(vVertex.xy,0,1);
vUV = vVertex.zw; // texture coordinate
}
着色器/ shader.frag
#version 330 core
layout (location=0) out vec4 vFragColor;
smooth in vec2 vUV;
uniform sampler2D textureMap;
void main()
{
vFragColor = texture(textureMap, vUV);
}
的main.cpp
#include <glew.h>
#include <glm/glm.hpp>
#include "SDL2/SDL.h"
#include "SDL2/SDL_opengl.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include "GLSLShader.h" // https://github.com/bagobor/opengl33_dev_cookbook_2013/blob/master/Chapter3/src/GLSLShader.h
//shader reference
GLSLShader shader;
//vertex array and vertex buffer object IDs
GLuint vaoID;
GLuint vboVerticesID;
GLuint vboIndicesID;
//texture ID
GLuint textureID;
//quad vertices and indices
glm::vec4 vertices[4];
GLushort indices[6];
int main( int argc, const char* argv[] )
{
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) return EXIT_FAILURE;
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 );
SDL_Window* window = SDL_CreateWindow( "OpenGL + Freetype",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
1024, 768,
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
SDL_GLContext glcontext = SDL_GL_CreateContext( window );
if( glcontext == nullptr ) return EXIT_FAILURE;
glewExperimental = GL_TRUE;
if( glewInit() != GLEW_OK ) return EXIT_FAILURE;
SDL_GL_SetSwapInterval( 1 );
shader.LoadFromFile( GL_VERTEX_SHADER, "shaders/shader.vert" );
shader.LoadFromFile( GL_FRAGMENT_SHADER, "shaders/shader.frag" );
//compile and link shader
shader.CreateAndLinkProgram();
shader.Use();
shader.AddAttribute( "vVertex" );
shader.AddUniform( "textureMap" );
glUniform1i( shader( "textureMap" ), 0 );
shader.UnUse();
//setup quad geometry
vertices[0] = glm::vec4( -1.0, -1.0, 0, 1 );
vertices[1] = glm::vec4( 1.0, 1.0, 1, 0 );
vertices[2] = glm::vec4( 1.0, -1.0, 1, 1 );
vertices[3] = glm::vec4( -1.0, 1.0, 0, 0 );
//fill quad indices array
GLushort* id = &indices[0];
*id++ = 0;
*id++ = 1;
*id++ = 2;
*id++ = 0;
*id++ = 1;
*id++ = 3;
glGenVertexArrays( 1, &vaoID );
glGenBuffers( 1, &vboVerticesID );
glGenBuffers( 1, &vboIndicesID );
glBindVertexArray( vaoID );
glBindBuffer( GL_ARRAY_BUFFER, vboVerticesID );
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), &vertices[0], GL_DYNAMIC_DRAW );
glEnableVertexAttribArray( shader["vVertex"] );
glVertexAttribPointer( shader["vVertex"], sizeof( shader["vVertex"] ), GL_FLOAT, GL_FALSE, 0, 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIndicesID );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), &indices[0], GL_STATIC_DRAW );
glGenTextures( 1, &textureID );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, textureID );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
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 );
FT_Library library;
FT_Face face;
bool error = FT_Init_FreeType( &library );
if( error ) return EXIT_FAILURE;
error = FT_New_Face( library,
"dejavu.ttf",
0,
&face );
if( error ) return EXIT_FAILURE;
error = FT_Set_Pixel_Sizes( face, 0, 16 );
if( error ) return EXIT_FAILURE;
FT_Set_Pixel_Sizes( face, 0, 450 );
FT_UInt glyph_index = FT_Get_Char_Index( face, 282 ); // letter Ě
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
if( error ) return EXIT_FAILURE;
error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
if( error ) return EXIT_FAILURE;
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGB,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);
bool running = true;
while( running )
{
SDL_Event e;
if( SDL_PollEvent( &e ) )
{
switch( e.type )
{
case SDL_QUIT:
running = false;
break;
default:
break;
}
}
glClearColor( 1, 1, 1, 1 );
glClear( GL_COLOR_BUFFER_BIT );
shader.Use(); // bind shader
glDrawElements( GL_TRIANGLES, sizeof( indices ), GL_UNSIGNED_SHORT, 0 );
shader.UnUse(); // unbind shader
SDL_GL_SwapWindow( window );
}
return 0;
}
答案 0 :(得分:3)
FT_RENDER_MODE_NORMAL
results in a single-channel bitmap, not RGB:
FT_RENDER_MODE_NORMAL
这是默认的渲染模式;它对应于8位抗锯齿位图。
在GL_RED
来电中format
代替glTexImage2D()
尝试GL_RGB
:
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGB,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RED,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);