Allow using single color channel for font texture
This commit is contained in:
parent
f78d749a0c
commit
314c32865b
@ -22,6 +22,7 @@
|
|||||||
#include "font/font_manager.hpp"
|
#include "font/font_manager.hpp"
|
||||||
#include "font/font_settings.hpp"
|
#include "font/font_settings.hpp"
|
||||||
#include "graphics/2dutils.hpp"
|
#include "graphics/2dutils.hpp"
|
||||||
|
#include "graphics/central_settings.hpp"
|
||||||
#include "graphics/irr_driver.hpp"
|
#include "graphics/irr_driver.hpp"
|
||||||
#include "graphics/stk_texture.hpp"
|
#include "graphics/stk_texture.hpp"
|
||||||
#include "graphics/stk_tex_manager.hpp"
|
#include "graphics/stk_tex_manager.hpp"
|
||||||
@ -131,13 +132,24 @@ void FontWithFace::loadGlyphInfo(wchar_t c)
|
|||||||
*/
|
*/
|
||||||
void FontWithFace::createNewGlyphPage()
|
void FontWithFace::createNewGlyphPage()
|
||||||
{
|
{
|
||||||
uint8_t* data = new uint8_t[getGlyphPageSize() * getGlyphPageSize() * 4]();
|
#ifndef SERVER_ONLY
|
||||||
|
uint8_t* data = new uint8_t[getGlyphPageSize() * getGlyphPageSize() *
|
||||||
|
(CVS->isARBTextureSwizzleUsable() ? 1 : 4)];
|
||||||
|
#else
|
||||||
|
uint8_t* data = NULL;
|
||||||
|
#endif
|
||||||
m_current_height = 0;
|
m_current_height = 0;
|
||||||
m_used_width = 0;
|
m_used_width = 0;
|
||||||
m_used_height = 0;
|
m_used_height = 0;
|
||||||
STKTexture* stkt = new STKTexture(data, typeid(*this).name() +
|
STKTexture* stkt = new STKTexture(data, typeid(*this).name() +
|
||||||
StringUtils::toString(m_spritebank->getTextureCount()),
|
StringUtils::toString(m_spritebank->getTextureCount()),
|
||||||
getGlyphPageSize());
|
getGlyphPageSize(),
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
CVS->isARBTextureSwizzleUsable()
|
||||||
|
#else
|
||||||
|
false
|
||||||
|
#endif
|
||||||
|
);
|
||||||
m_spritebank->addTexture(stkt);
|
m_spritebank->addTexture(stkt);
|
||||||
STKTexManager::getInstance()->addTexture(stkt);
|
STKTexManager::getInstance()->addTexture(stkt);
|
||||||
} // createNewGlyphPage
|
} // createNewGlyphPage
|
||||||
@ -180,36 +192,6 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
|||||||
createNewGlyphPage();
|
createNewGlyphPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint32_t> image_data;
|
|
||||||
image_data.resize(texture_size.Width * texture_size.Height,
|
|
||||||
video::SColor(0, 255, 255, 255).color);
|
|
||||||
switch (bits.pixel_mode)
|
|
||||||
{
|
|
||||||
case FT_PIXEL_MODE_GRAY:
|
|
||||||
{
|
|
||||||
// Load the grayscale data in.
|
|
||||||
const float gray_count = static_cast<float>(bits.num_grays);
|
|
||||||
const unsigned int image_pitch =
|
|
||||||
4 * texture_size.Width / sizeof(unsigned int);
|
|
||||||
uint8_t* glyph_data = bits.buffer;
|
|
||||||
for (unsigned int y = 0; y < (unsigned int)bits.rows; y++)
|
|
||||||
{
|
|
||||||
uint8_t* row = glyph_data;
|
|
||||||
for (unsigned int x = 0; x < (unsigned int)bits.width; x++)
|
|
||||||
{
|
|
||||||
image_data.data()[y * image_pitch + x] |=
|
|
||||||
static_cast<uint32_t>(255.0f *
|
|
||||||
(static_cast<float>(*row++) / gray_count)) << 24;
|
|
||||||
}
|
|
||||||
glyph_data += bits.pitch;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done creating a single glyph, now copy to the glyph page...
|
|
||||||
// Determine the linebreak location
|
// Determine the linebreak location
|
||||||
if (m_used_width + texture_size.Width > getGlyphPageSize())
|
if (m_used_width + texture_size.Width > getGlyphPageSize())
|
||||||
{
|
{
|
||||||
@ -222,19 +204,45 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
|||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
video::ITexture* tex = m_spritebank->getTexture(cur_tex);
|
video::ITexture* tex = m_spritebank->getTexture(cur_tex);
|
||||||
glBindTexture(GL_TEXTURE_2D, tex->getOpenGLTextureName());
|
glBindTexture(GL_TEXTURE_2D, tex->getOpenGLTextureName());
|
||||||
unsigned int format = GL_BGRA;
|
if (CVS->isARBTextureSwizzleUsable())
|
||||||
#if defined(USE_GLES2)
|
{
|
||||||
if (!CVS->isEXTTextureFormatBGRA8888Usable())
|
glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height,
|
||||||
format = GL_RGBA;
|
bits.width, bits.rows, GL_RED, GL_UNSIGNED_BYTE, bits.buffer);
|
||||||
#endif
|
}
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height,
|
else
|
||||||
texture_size.Width, texture_size.Height, format, GL_UNSIGNED_BYTE,
|
{
|
||||||
image_data.data());
|
std::vector<uint32_t> image_data;
|
||||||
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
image_data.resize(texture_size.Width * texture_size.Height,
|
||||||
//static GLint swizzle_mask[] = { GL_ONE, GL_ONE, GL_ONE, GL_RED };
|
video::SColor(0, 255, 255, 255).color);
|
||||||
//glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle_mask);
|
switch (bits.pixel_mode)
|
||||||
//glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height, bits.width, bits.rows, GL_RED, GL_UNSIGNED_BYTE, bits.buffer);
|
{
|
||||||
//glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
case FT_PIXEL_MODE_GRAY:
|
||||||
|
{
|
||||||
|
// Load the grayscale data in.
|
||||||
|
const float gray_count = static_cast<float>(bits.num_grays);
|
||||||
|
const unsigned int image_pitch =
|
||||||
|
4 * texture_size.Width / sizeof(unsigned int);
|
||||||
|
uint8_t* glyph_data = bits.buffer;
|
||||||
|
for (unsigned int y = 0; y < (unsigned int)bits.rows; y++)
|
||||||
|
{
|
||||||
|
uint8_t* row = glyph_data;
|
||||||
|
for (unsigned int x = 0; x < (unsigned int)bits.width; x++)
|
||||||
|
{
|
||||||
|
image_data.data()[y * image_pitch + x] |=
|
||||||
|
static_cast<uint32_t>(255.0f *
|
||||||
|
(static_cast<float>(*row++) / gray_count)) << 24;
|
||||||
|
}
|
||||||
|
glyph_data += bits.pitch;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height,
|
||||||
|
texture_size.Width, texture_size.Height, GL_BGRA, GL_UNSIGNED_BYTE,
|
||||||
|
image_data.data());
|
||||||
|
}
|
||||||
if (tex->hasMipMaps())
|
if (tex->hasMipMaps())
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
@ -51,6 +51,7 @@ void CentralVideoSettings::init()
|
|||||||
hasExplicitAttribLocation = false;
|
hasExplicitAttribLocation = false;
|
||||||
hasGS = false;
|
hasGS = false;
|
||||||
hasTextureFilterAnisotropic = false;
|
hasTextureFilterAnisotropic = false;
|
||||||
|
hasTextureSwizzle = false;
|
||||||
|
|
||||||
#if defined(USE_GLES2)
|
#if defined(USE_GLES2)
|
||||||
hasBGRA = false;
|
hasBGRA = false;
|
||||||
@ -182,7 +183,11 @@ void CentralVideoSettings::init()
|
|||||||
hasGS = true;
|
hasGS = true;
|
||||||
Log::info("GLDriver", "Geometry Shaders Present");
|
Log::info("GLDriver", "Geometry Shaders Present");
|
||||||
}
|
}
|
||||||
|
if (hasGLExtension("GL_ARB_texture_swizzle"))
|
||||||
|
{
|
||||||
|
hasTextureSwizzle = true;
|
||||||
|
Log::info("GLDriver", "ARB Texture Swizzle Present");
|
||||||
|
}
|
||||||
// Only unset the high def textures if they are set as default. If the
|
// Only unset the high def textures if they are set as default. If the
|
||||||
// user has enabled them (bit 1 set), then leave them enabled.
|
// user has enabled them (bit 1 set), then leave them enabled.
|
||||||
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HIGHDEFINITION_TEXTURES) &&
|
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HIGHDEFINITION_TEXTURES) &&
|
||||||
@ -228,6 +233,7 @@ void CentralVideoSettings::init()
|
|||||||
if (m_glsl == true)
|
if (m_glsl == true)
|
||||||
{
|
{
|
||||||
hasTextureStorage = true;
|
hasTextureStorage = true;
|
||||||
|
hasTextureSwizzle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FORMAT_BGRA8888) &&
|
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FORMAT_BGRA8888) &&
|
||||||
@ -447,4 +453,10 @@ bool CentralVideoSettings::supportsHardwareSkinning() const
|
|||||||
{
|
{
|
||||||
return isARBUniformBufferObjectUsable();
|
return isARBUniformBufferObjectUsable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CentralVideoSettings::isARBTextureSwizzleUsable() const
|
||||||
|
{
|
||||||
|
return m_glsl && hasTextureSwizzle;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !SERVER_ONLY
|
#endif // !SERVER_ONLY
|
||||||
|
@ -43,6 +43,7 @@ private:
|
|||||||
bool hasImageLoadStore;
|
bool hasImageLoadStore;
|
||||||
bool hasMultiDrawIndirect;
|
bool hasMultiDrawIndirect;
|
||||||
bool hasTextureFilterAnisotropic;
|
bool hasTextureFilterAnisotropic;
|
||||||
|
bool hasTextureSwizzle;
|
||||||
|
|
||||||
#if defined(USE_GLES2)
|
#if defined(USE_GLES2)
|
||||||
bool hasBGRA;
|
bool hasBGRA;
|
||||||
@ -82,6 +83,7 @@ public:
|
|||||||
bool isARBMultiDrawIndirectUsable() const;
|
bool isARBMultiDrawIndirectUsable() const;
|
||||||
bool isARBExplicitAttribLocationUsable() const;
|
bool isARBExplicitAttribLocationUsable() const;
|
||||||
bool isEXTTextureFilterAnisotropicUsable() const;
|
bool isEXTTextureFilterAnisotropicUsable() const;
|
||||||
|
bool isARBTextureSwizzleUsable() const;
|
||||||
|
|
||||||
#if defined(USE_GLES2)
|
#if defined(USE_GLES2)
|
||||||
bool isEXTTextureFormatBGRA8888Usable() const;
|
bool isEXTTextureFormatBGRA8888Usable() const;
|
||||||
|
@ -82,6 +82,8 @@ void STKTexture::reload(bool no_upload, uint8_t* preload_data,
|
|||||||
if (ProfileWorld::isNoGraphics())
|
if (ProfileWorld::isNoGraphics())
|
||||||
{
|
{
|
||||||
m_texture_name = 1;
|
m_texture_name = 1;
|
||||||
|
if (preload_data)
|
||||||
|
delete[] preload_data;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
@ -156,8 +158,8 @@ void STKTexture::reload(bool no_upload, uint8_t* preload_data,
|
|||||||
|
|
||||||
const unsigned int w = m_size.Width;
|
const unsigned int w = m_size.Width;
|
||||||
const unsigned int h = m_size.Height;
|
const unsigned int h = m_size.Height;
|
||||||
unsigned int format = GL_BGRA;
|
unsigned int format = single_channel ? GL_RED : GL_BGRA;
|
||||||
unsigned int internal_format = GL_RGBA;
|
unsigned int internal_format = single_channel ? GL_RED : GL_RGBA;
|
||||||
|
|
||||||
#if !defined(USE_GLES2)
|
#if !defined(USE_GLES2)
|
||||||
if (m_mesh_texture && CVS->isTextureCompressionEnabled())
|
if (m_mesh_texture && CVS->isTextureCompressionEnabled())
|
||||||
@ -166,14 +168,14 @@ void STKTexture::reload(bool no_upload, uint8_t* preload_data,
|
|||||||
GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT :
|
GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT :
|
||||||
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||||
}
|
}
|
||||||
else
|
else if (!single_channel)
|
||||||
{
|
{
|
||||||
internal_format = m_srgb ? GL_SRGB_ALPHA : GL_RGBA;
|
internal_format = m_srgb ? GL_SRGB_ALPHA : GL_RGBA;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_GLES2)
|
#if defined(USE_GLES2)
|
||||||
if (!CVS->isEXTTextureFormatBGRA8888Usable())
|
if (!CVS->isEXTTextureFormatBGRA8888Usable() && !single_channel)
|
||||||
{
|
{
|
||||||
format = GL_RGBA;
|
format = GL_RGBA;
|
||||||
for (unsigned int i = 0; i < w * h; i++)
|
for (unsigned int i = 0; i < w * h; i++)
|
||||||
@ -206,6 +208,14 @@ void STKTexture::reload(bool no_upload, uint8_t* preload_data,
|
|||||||
glBindTexture(GL_TEXTURE_2D, m_texture_name);
|
glBindTexture(GL_TEXTURE_2D, m_texture_name);
|
||||||
if (!reload)
|
if (!reload)
|
||||||
{
|
{
|
||||||
|
if (single_channel)
|
||||||
|
{
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
|
||||||
|
}
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, w, h, 0, format,
|
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, w, h, 0, format,
|
||||||
GL_UNSIGNED_BYTE, data);
|
GL_UNSIGNED_BYTE, data);
|
||||||
}
|
}
|
||||||
@ -220,7 +230,7 @@ void STKTexture::reload(bool no_upload, uint8_t* preload_data,
|
|||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_texture_size = w * h * 4 /*BRGA*/;
|
m_texture_size = w * h * (single_channel ? 1 : 4);
|
||||||
if (no_upload)
|
if (no_upload)
|
||||||
m_texture_image = orig_img;
|
m_texture_image = orig_img;
|
||||||
else if (orig_img)
|
else if (orig_img)
|
||||||
@ -454,10 +464,10 @@ bool STKTexture::hasMipMaps() const
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void* STKTexture::lock(video::E_TEXTURE_LOCK_MODE mode, u32 mipmap_level)
|
void* STKTexture::lock(video::E_TEXTURE_LOCK_MODE mode, u32 mipmap_level)
|
||||||
{
|
{
|
||||||
#ifndef SERVER_ONLY
|
|
||||||
if (m_texture_image)
|
if (m_texture_image)
|
||||||
return m_texture_image->lock();
|
return m_texture_image->lock();
|
||||||
|
|
||||||
|
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
|
||||||
uint8_t* pixels = new uint8_t[m_size.Width * m_size.Height * 4]();
|
uint8_t* pixels = new uint8_t[m_size.Width * m_size.Height * 4]();
|
||||||
GLint tmp_texture;
|
GLint tmp_texture;
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &tmp_texture);
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &tmp_texture);
|
||||||
|
Loading…
Reference in New Issue
Block a user