add a distance field display for the fonts ==> needed openGL ES 2
This commit is contained in:
parent
6b98ad543c
commit
022055b86e
@ -1 +1 @@
|
||||
Subproject commit 80585116ed17a8ead625d229e40ecef37783c7bb
|
||||
Subproject commit bfba3999b5cee49bd9a556f51170193849228a46
|
@ -168,8 +168,17 @@ template <typename T> class Vector2D
|
||||
--(*this);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
T QuadDist(void)
|
||||
{
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
T Dist(void)
|
||||
{
|
||||
return sqrt(x*x + y*y);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////:
|
||||
|
||||
|
@ -28,10 +28,11 @@ LOCAL_CFLAGS := -Wno-write-strings \
|
||||
-DEWOL_VERSION_TAG_NAME="\"$(LOCAL_VERSION_TAG_SHORT)-$(BUILD_DIRECTORY_MODE)\"" \
|
||||
-Wall
|
||||
|
||||
ifdef CONFIG_EWOL_OPENGL_ES_V1
|
||||
LOCAL_CFLAGS += -D__VIDEO__OPENGL_ES_2
|
||||
LOCAL_EXPORT_CFLAGS := -D__VIDEO__OPENGL_ES_2
|
||||
endif
|
||||
#ifdef CONFIG_EWOL_OPENGL_ES_V2
|
||||
LOCAL_CFLAGS += -D__VIDEO__OPENGL_ES_2
|
||||
LOCAL_EXPORT_CFLAGS := -D__VIDEO__OPENGL_ES_2
|
||||
$(info Compilation For openGL-ES-v2 compatibility)
|
||||
#endif
|
||||
|
||||
# load the common sources file of the platform
|
||||
include $(LOCAL_PATH)/file.mk
|
||||
|
@ -234,6 +234,25 @@ bool ewol::resource::Keep(etk::UString& filename, ewol::Font*& object)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __VIDEO__OPENGL_ES_2
|
||||
bool ewol::resource::Keep(etk::UString& filename, ewol::DistantFieldFont*& object)
|
||||
{
|
||||
EWOL_VERBOSE("KEEP : DistanceFieldFont : file : \"" << filename << "\"");
|
||||
object = static_cast<ewol::DistantFieldFont*>(LocalKeep(filename));
|
||||
if (NULL != object) {
|
||||
return true;
|
||||
}
|
||||
// need to crate a new one ...
|
||||
object = new ewol::DistantFieldFont(filename);
|
||||
if (NULL == object) {
|
||||
EWOL_ERROR("allocation error of a resource : " << filename);
|
||||
return false;
|
||||
}
|
||||
LocalAdd(object);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ewol::resource::Keep(ewol::Texture*& object)
|
||||
{
|
||||
// this element create a new one every time ....
|
||||
@ -333,6 +352,14 @@ void ewol::resource::Release(ewol::Font*& object)
|
||||
object = NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef __VIDEO__OPENGL_ES_2
|
||||
void ewol::resource::Release(ewol::DistantFieldFont*& object)
|
||||
{
|
||||
ewol::Resource* object2 = static_cast<ewol::Resource*>(object);
|
||||
Release(object2);
|
||||
object = NULL;
|
||||
}
|
||||
#endif
|
||||
void ewol::resource::Release(ewol::Texture*& object)
|
||||
{
|
||||
ewol::Resource* object2 = static_cast<ewol::Resource*>(object);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <ewol/openGL/Program.h>
|
||||
#include <ewol/font/Font.h>
|
||||
#include <ewol/font/TexturedFont.h>
|
||||
#include <ewol/font/DistantFieldFont.h>
|
||||
#include <ewol/texture/Texture.h>
|
||||
#include <ewol/texture/TextureFile.h>
|
||||
|
||||
@ -53,6 +54,7 @@ namespace ewol
|
||||
#ifdef __VIDEO__OPENGL_ES_2
|
||||
bool Keep(etk::UString& filename, ewol::Program*& object);
|
||||
bool Keep(etk::UString& filename, ewol::Shader*& object);
|
||||
bool Keep(etk::UString& filename, ewol::DistantFieldFont*& object);
|
||||
#endif
|
||||
bool Keep(ewol::Texture*& object); // no name needed here ...
|
||||
bool Keep(etk::UString& filename, ewol::TextureFile*& object, Vector2D<int32_t> size);
|
||||
@ -63,6 +65,7 @@ namespace ewol
|
||||
#ifdef __VIDEO__OPENGL_ES_2
|
||||
void Release(ewol::Program*& object);
|
||||
void Release(ewol::Shader*& object);
|
||||
void Release(ewol::DistantFieldFont*& object);
|
||||
#endif
|
||||
void Release(ewol::Texture*& object);
|
||||
void Release(ewol::TextureFile*& object);
|
||||
|
465
Sources/libewol/ewol/font/DistantFieldFont.cpp
Normal file
465
Sources/libewol/ewol/font/DistantFieldFont.cpp
Normal file
@ -0,0 +1,465 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file ewol/font/DistanceFieldFont.cpp
|
||||
* @brief ewol Textured distant field Font system (Sources)
|
||||
* @author Edouard DUPIN
|
||||
* @date 22/08/2012
|
||||
* @par Project
|
||||
* ewol
|
||||
*
|
||||
* @par Copyright
|
||||
* Copyright 2011 Edouard DUPIN, all right reserved
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY.
|
||||
*
|
||||
* Licence summary :
|
||||
* You can modify and redistribute the sources code and binaries.
|
||||
* You can send me the bug-fix
|
||||
*
|
||||
* Term of the licence in in the file licence.txt.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#include <etk/Types.h>
|
||||
#include <ewol/font/Font.h>
|
||||
#include <ewol/font/DistantFieldFont.h>
|
||||
#include <ewol/font/FontManager.h>
|
||||
#include <ewol/ResourceManager.h>
|
||||
|
||||
|
||||
static int32_t nextP2(int32_t value)
|
||||
{
|
||||
int32_t val=1;
|
||||
for (int32_t iii=1; iii<31; iii++) {
|
||||
if (value <= val) {
|
||||
return val;
|
||||
}
|
||||
val *=2;
|
||||
}
|
||||
EWOL_CRITICAL("impossible CASE....");
|
||||
return val;
|
||||
}
|
||||
|
||||
static int32_t simpleSQRT(int32_t value)
|
||||
{
|
||||
int32_t val=1;
|
||||
for (int32_t iii=1; iii<1000; iii++) {
|
||||
val =iii*iii;
|
||||
if (value <= val) {
|
||||
return iii;
|
||||
}
|
||||
}
|
||||
EWOL_CRITICAL("impossible CASE....");
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
ewol::DistantFieldFont::DistantFieldFont(etk::UString fontName) :
|
||||
ewol::Texture(fontName),
|
||||
m_font(NULL),
|
||||
m_lastGlyphPos(0,0),
|
||||
m_lastRawHeigh(0)
|
||||
{
|
||||
int32_t tmpSize = 0;
|
||||
// extarct name and size :
|
||||
char * tmpData = fontName.c_str();
|
||||
char * tmpPos = strchr(tmpData, ':');
|
||||
|
||||
if (tmpPos==NULL) {
|
||||
m_size = 1;
|
||||
EWOL_CRITICAL("Can not parse the font name : \"" << fontName << "\" ??? ':' " );
|
||||
return;
|
||||
} else {
|
||||
if (sscanf(tmpPos+1, "%d", &tmpSize)!=1) {
|
||||
m_size = 1;
|
||||
EWOL_CRITICAL("Can not parse the font name : \"" << fontName << "\" ==> size ???");
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_name = fontName.Extract(0, (tmpPos - tmpData));
|
||||
m_size = tmpSize;
|
||||
|
||||
//EWOL_CRITICAL("Load FONT name : \"" << m_name << "\" ==> size=" << m_size);
|
||||
ewol::resource::Keep(m_name, m_font);
|
||||
if (NULL == m_font) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set the bassic charset:
|
||||
m_listElement.Clear();
|
||||
freeTypeFontElement_ts tmpchar1;
|
||||
tmpchar1.property.m_UVal = 0;
|
||||
m_listElement.PushBack(tmpchar1);
|
||||
for (int32_t iii=0x20; iii<0xFF; iii++) {
|
||||
freeTypeFontElement_ts tmpchar;
|
||||
tmpchar.property.m_UVal = iii;
|
||||
m_listElement.PushBack(tmpchar);
|
||||
if (0x7F == iii) {
|
||||
iii = 0x9F;
|
||||
}
|
||||
}
|
||||
|
||||
/* this is a bad code for now ... */
|
||||
// ==> determine the texture Size
|
||||
GlyphProperty tmpproperty;
|
||||
tmpproperty.m_UVal = 'A';
|
||||
m_font->GetGlyphProperty(m_size, tmpproperty);
|
||||
|
||||
int32_t nbElement = 0xFF - 0x20 + 1;
|
||||
int32_t coter = simpleSQRT(nbElement);
|
||||
// note : +1 is for the overlapping of the glyph (Part 1)
|
||||
int32_t glyphMaxWidth = tmpproperty.m_advance.x +1;
|
||||
int32_t glyphMaxHeight = tmpproperty.m_advance.y +1;
|
||||
int32_t textureWidth = nextP2(coter*glyphMaxWidth);
|
||||
int32_t nbRaws = textureWidth / glyphMaxWidth;
|
||||
if (nbRaws <= 0) {
|
||||
EWOL_ERROR("devide by 0");
|
||||
nbRaws = 1;
|
||||
}
|
||||
int32_t nbLine = (nbElement / nbRaws) + 1;
|
||||
int32_t textureHeight = nextP2(nbLine*glyphMaxHeight);
|
||||
// for android :
|
||||
textureHeight = etk_max(textureHeight, textureWidth);
|
||||
textureWidth = textureHeight;
|
||||
|
||||
|
||||
EWOL_DEBUG("Generate a text texture for char(" << nbRaws << "," << nbLine << ") with size=(" << textureWidth << "," << textureHeight << ")");
|
||||
// resize must be done on the texture ...
|
||||
SetImageSize(Vector2D<int32_t>(textureWidth,textureHeight));
|
||||
// now we can acces directly on the image
|
||||
m_data.SetFillColor(draw::Color(0xFFFFFF00));
|
||||
m_data.Clear();
|
||||
|
||||
m_height = m_font->GetHeight(m_size);
|
||||
|
||||
int32_t CurrentLineHigh = 0;
|
||||
Vector2D<int32_t> glyphPosition(1,1);
|
||||
for (int32_t iii=0; iii<m_listElement.Size(); iii++) {
|
||||
if (true == m_font->GetGlyphProperty(m_size, m_listElement[iii].property)) {
|
||||
/*
|
||||
// check internal property:
|
||||
// enought in the texture :
|
||||
//if (m_data.GetWidth() < m_lastGlyphPos.x + m_listElement[iii].property.m_sizeTexture.x
|
||||
// resize if needed ...
|
||||
|
||||
// line size :
|
||||
|
||||
// draw
|
||||
|
||||
// move the curent pointer of drawing:
|
||||
*/
|
||||
// change line if needed ...
|
||||
if (glyphPosition.x+m_listElement[iii].property.m_sizeTexture.x > textureWidth) {
|
||||
glyphPosition.x = 0;
|
||||
glyphPosition.y += CurrentLineHigh;
|
||||
CurrentLineHigh = 0;
|
||||
}
|
||||
// draw the glyph
|
||||
m_font->DrawGlyph(m_data, m_size, glyphPosition, m_listElement[iii].property);
|
||||
// set video position
|
||||
m_listElement[iii].posStart.u = (float)(glyphPosition.x) / (float)textureWidth;
|
||||
m_listElement[iii].posStart.v = (float)(glyphPosition.y) / (float)textureHeight;
|
||||
m_listElement[iii].posStop.u = (float)(glyphPosition.x + m_listElement[iii].property.m_sizeTexture.x) / (float)textureWidth;
|
||||
m_listElement[iii].posStop.v = (float)(glyphPosition.y + m_listElement[iii].property.m_sizeTexture.y) / (float)textureHeight;
|
||||
/*
|
||||
EWOL_DEBUG("generate '" << (char)m_listElement[iii].property.m_UVal << "'");
|
||||
EWOL_DEBUG(" in tex : " << glyphPosition << " ==> " << m_listElement[iii].posStart.u<< "," << m_listElement[iii].posStart.v );
|
||||
EWOL_DEBUG(" m_sizeTexture =" << m_listElement[iii].property.m_sizeTexture );
|
||||
EWOL_DEBUG(" m_bearing =" << m_listElement[iii].property.m_bearing );
|
||||
EWOL_DEBUG(" m_advance =" << m_listElement[iii].property.m_advance );
|
||||
*/
|
||||
|
||||
// update the maximum of the line hight :
|
||||
if (CurrentLineHigh<m_listElement[iii].property.m_sizeTexture.y) {
|
||||
// note : +1 is for the overlapping of the glyph (Part 2)
|
||||
CurrentLineHigh = m_listElement[iii].property.m_sizeTexture.y+1;
|
||||
}
|
||||
// note : +1 is for the overlapping of the glyph (Part 3)
|
||||
// update the Bitmap position drawing :
|
||||
glyphPosition.x += m_listElement[iii].property.m_sizeTexture.x+1;
|
||||
}
|
||||
|
||||
}
|
||||
// For testing cheree the box are set)
|
||||
#if 0
|
||||
draw::Color tlpppp(0xFF,0xFF,0xFF,0x00);
|
||||
for(int32_t jjj=0; jjj < textureHeight;jjj++) {
|
||||
for(int32_t iii=0; iii < textureWidth; iii++){
|
||||
tlpppp = m_data.Get(Vector2D<int32_t>(iii, jjj) );
|
||||
// set only alpha :
|
||||
tlpppp.a = etk_min( tlpppp.a+0x60, 0xFF);
|
||||
// real set of color
|
||||
m_data.Set(Vector2D<int32_t>(iii, jjj), tlpppp );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
EWOL_DEBUG("End generation of the Fond bitmap, start adding texture");
|
||||
// generate the distance field from this element ...
|
||||
m_data.DistanceField();
|
||||
Flush();
|
||||
|
||||
}
|
||||
|
||||
ewol::DistantFieldFont::~DistantFieldFont(void)
|
||||
{
|
||||
if (NULL!= m_font) {
|
||||
ewol::resource::Release(m_font);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ewol::DistantFieldFont::HasName(etk::UString& fileName)
|
||||
{
|
||||
etk::UString tmpName = m_name;
|
||||
tmpName += ":";
|
||||
tmpName += m_size;
|
||||
EWOL_VERBOSE("S : check : " << fileName << " ?= " << tmpName << " = " << (fileName==tmpName) );
|
||||
return (fileName==tmpName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t ewol::DistantFieldFont::Draw(Vector2D<float> textPos,
|
||||
const etk::UString& unicodeString,
|
||||
etk::Vector<Vector2D<float> > & coord,
|
||||
etk::Vector<texCoord_ts> & coordTex)
|
||||
{
|
||||
float totalSize = 0;
|
||||
Vector2D<float> tmpPos = textPos;
|
||||
for(int32_t iii=0; iii<unicodeString.Size(); iii++) {
|
||||
int32_t ret = Draw(tmpPos, unicodeString[iii], coord, coordTex);
|
||||
tmpPos.x += ret;
|
||||
totalSize += ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// To display the texture ...
|
||||
{
|
||||
/* Bitmap position
|
||||
* 0------1
|
||||
* | |
|
||||
* | |
|
||||
* 3------2
|
||||
*/
|
||||
Vector2D<float> bitmapDrawPos[4];
|
||||
bitmapDrawPos[0].x = 10;
|
||||
bitmapDrawPos[1].x = 400;
|
||||
bitmapDrawPos[2].x = 400;
|
||||
bitmapDrawPos[3].x = 10;
|
||||
|
||||
bitmapDrawPos[0].y = 400;
|
||||
bitmapDrawPos[1].y = 400;
|
||||
bitmapDrawPos[2].y = 10;
|
||||
bitmapDrawPos[3].y = 10;
|
||||
/* texture Position :
|
||||
* 0------1
|
||||
* | |
|
||||
* | |
|
||||
* 3------2
|
||||
*/
|
||||
texCoord_ts texturePos[4];
|
||||
texturePos[0].u = 0;
|
||||
texturePos[1].u = 1;
|
||||
texturePos[2].u = 1;
|
||||
texturePos[3].u = 0;
|
||||
|
||||
texturePos[0].v = 0;
|
||||
texturePos[1].v = 0;
|
||||
texturePos[2].v = 1;
|
||||
texturePos[3].v = 1;
|
||||
|
||||
// NOTE : Android does not support the Quads elements ...
|
||||
/* Step 1 :
|
||||
* ********
|
||||
* ******
|
||||
* ****
|
||||
* **
|
||||
*
|
||||
*/
|
||||
// set texture coordonates :
|
||||
coordTex.PushBack(texturePos[0]);
|
||||
coordTex.PushBack(texturePos[1]);
|
||||
coordTex.PushBack(texturePos[2]);
|
||||
// set display positions :
|
||||
coord.PushBack(bitmapDrawPos[0]);
|
||||
coord.PushBack(bitmapDrawPos[1]);
|
||||
coord.PushBack(bitmapDrawPos[2]);
|
||||
|
||||
/* Step 2 :
|
||||
*
|
||||
* **
|
||||
* ****
|
||||
* ******
|
||||
* ********
|
||||
*/
|
||||
// set texture coordonates :
|
||||
coordTex.PushBack(texturePos[0]);
|
||||
coordTex.PushBack(texturePos[2]);
|
||||
coordTex.PushBack(texturePos[3]);
|
||||
// set display positions :
|
||||
coord.PushBack(bitmapDrawPos[0]);
|
||||
coord.PushBack(bitmapDrawPos[2]);
|
||||
coord.PushBack(bitmapDrawPos[3]);
|
||||
}
|
||||
#endif
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
int32_t ewol::DistantFieldFont::Draw(Vector2D<float> textPos,
|
||||
const uniChar_t unicodeChar,
|
||||
etk::Vector<Vector2D<float> > & coord,
|
||||
etk::Vector<texCoord_ts> & coordTex)
|
||||
{
|
||||
float posDrawX = textPos.x;
|
||||
|
||||
int32_t charIndex;
|
||||
if (unicodeChar < 0x20) {
|
||||
charIndex = 0;
|
||||
} else if (unicodeChar < 0x80) {
|
||||
charIndex = unicodeChar - 0x1F;
|
||||
} else {
|
||||
charIndex = 0;
|
||||
for (int32_t iii=0x80-0x20; iii < m_listElement.Size(); iii++) {
|
||||
if (m_listElement[iii].property.m_UVal == unicodeChar) {
|
||||
charIndex = iii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 0x01 == 0x20 == ' ';
|
||||
if (unicodeChar != 0x01) {
|
||||
/* Bitmap position
|
||||
* xA xB
|
||||
* yC *------*
|
||||
* | |
|
||||
* | |
|
||||
* yD *------*
|
||||
*/
|
||||
float dxA = posDrawX + m_listElement[charIndex].property.m_bearing.x;
|
||||
float dxB = posDrawX + m_listElement[charIndex].property.m_bearing.x + m_listElement[charIndex].property.m_sizeTexture.x;
|
||||
float dyC = textPos.y + m_listElement[charIndex].property.m_bearing.y + m_height - m_size;
|
||||
float dyD = dyC - m_listElement[charIndex].property.m_sizeTexture.y;
|
||||
|
||||
float tuA = m_listElement[charIndex].posStart.u;
|
||||
float tuB = m_listElement[charIndex].posStop.u;
|
||||
float tvC = m_listElement[charIndex].posStart.v;
|
||||
float tvD = m_listElement[charIndex].posStop.v;
|
||||
|
||||
|
||||
// Clipping and drawing area
|
||||
if( dxB <= dxA
|
||||
|| dyD >= dyC) {
|
||||
// nothing to do ...
|
||||
} else {
|
||||
/* Bitmap position
|
||||
* 0------1
|
||||
* | |
|
||||
* | |
|
||||
* 3------2
|
||||
*/
|
||||
Vector2D<int32_t> bitmapDrawPos[4];
|
||||
bitmapDrawPos[0].x = (int32_t)dxA;
|
||||
bitmapDrawPos[1].x = (int32_t)dxB;
|
||||
bitmapDrawPos[2].x = (int32_t)dxB;
|
||||
bitmapDrawPos[3].x = (int32_t)dxA;
|
||||
|
||||
bitmapDrawPos[0].y = (int32_t)dyC;
|
||||
bitmapDrawPos[1].y = (int32_t)dyC;
|
||||
bitmapDrawPos[2].y = (int32_t)dyD;
|
||||
bitmapDrawPos[3].y = (int32_t)dyD;
|
||||
/* texture Position :
|
||||
* 0------1
|
||||
* | |
|
||||
* | |
|
||||
* 3------2
|
||||
*/
|
||||
texCoord_ts texturePos[4];
|
||||
texturePos[0].u = tuA;
|
||||
texturePos[1].u = tuB;
|
||||
texturePos[2].u = tuB;
|
||||
texturePos[3].u = tuA;
|
||||
|
||||
texturePos[0].v = tvC;
|
||||
texturePos[1].v = tvC;
|
||||
texturePos[2].v = tvD;
|
||||
texturePos[3].v = tvD;
|
||||
|
||||
// NOTE : Android does not support the Quads elements ...
|
||||
/* Step 1 :
|
||||
* ********
|
||||
* ******
|
||||
* ****
|
||||
* **
|
||||
*
|
||||
*/
|
||||
// set texture coordonates :
|
||||
coordTex.PushBack(texturePos[0]);
|
||||
coordTex.PushBack(texturePos[1]);
|
||||
coordTex.PushBack(texturePos[2]);
|
||||
// set display positions :
|
||||
coord.PushBack(bitmapDrawPos[0]);
|
||||
coord.PushBack(bitmapDrawPos[1]);
|
||||
coord.PushBack(bitmapDrawPos[2]);
|
||||
|
||||
/* Step 2 :
|
||||
*
|
||||
* **
|
||||
* ****
|
||||
* ******
|
||||
* ********
|
||||
*/
|
||||
// set texture coordonates :
|
||||
coordTex.PushBack(texturePos[0]);
|
||||
coordTex.PushBack(texturePos[2]);
|
||||
coordTex.PushBack(texturePos[3]);
|
||||
// set display positions :
|
||||
coord.PushBack(bitmapDrawPos[0]);
|
||||
coord.PushBack(bitmapDrawPos[2]);
|
||||
coord.PushBack(bitmapDrawPos[3]);
|
||||
|
||||
}
|
||||
}
|
||||
posDrawX += m_listElement[charIndex].property.m_advance.x;
|
||||
int32_t sizeOut = posDrawX - textPos.x;
|
||||
textPos.x = posDrawX;
|
||||
return sizeOut;
|
||||
}
|
||||
|
||||
Vector2D<float> ewol::DistantFieldFont::GetSize(const etk::UString & unicodeString)
|
||||
{
|
||||
Vector2D<float> outputSize(0,m_height);
|
||||
for(int32_t iii=0; iii<unicodeString.Size(); iii++) {
|
||||
Vector2D<float> tmpp = GetSize(unicodeString[iii]);
|
||||
outputSize.x += tmpp.x;
|
||||
}
|
||||
return outputSize;
|
||||
}
|
||||
|
||||
|
||||
Vector2D<float> ewol::DistantFieldFont::GetSize(const uniChar_t unicodeChar)
|
||||
{
|
||||
Vector2D<float> outputSize(0,m_height);
|
||||
int32_t charIndex;
|
||||
if (unicodeChar >= 0x80) {
|
||||
charIndex = 0;
|
||||
} else if (unicodeChar < 0x20) {
|
||||
charIndex = 0;
|
||||
} else if (unicodeChar < 0x80) {
|
||||
charIndex = unicodeChar - 0x1F;
|
||||
} else {
|
||||
for (int32_t iii=0x80-0x20; iii < m_listElement.Size(); iii++) {
|
||||
if (m_listElement[iii].property.m_UVal == unicodeChar) {
|
||||
charIndex = iii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// TODO : Update if possible the mapping
|
||||
charIndex = 0;
|
||||
}
|
||||
outputSize.x = m_listElement[charIndex].property.m_advance.x;
|
||||
return outputSize;
|
||||
}
|
||||
|
||||
|
76
Sources/libewol/ewol/font/DistantFieldFont.h
Normal file
76
Sources/libewol/ewol/font/DistantFieldFont.h
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file ewol/font/TexturedFont.h
|
||||
* @brief ewol Textured Font system (header)
|
||||
* @author Edouard DUPIN
|
||||
* @date 22/08/2012
|
||||
* @par Project
|
||||
* ewol
|
||||
*
|
||||
* @par Copyright
|
||||
* Copyright 2011 Edouard DUPIN, all right reserved
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY.
|
||||
*
|
||||
* Licence summary :
|
||||
* You can modify and redistribute the sources code and binaries.
|
||||
* You can send me the bug-fix
|
||||
*
|
||||
* Term of the licence in in the file licence.txt.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __EWOL_DISTANT_FIELD_FONT_H__
|
||||
#define __EWOL_DISTANT_FIELD_FONT_H__
|
||||
|
||||
#include <ewol/font/Font.h>
|
||||
#include <ewol/texture/Texture.h>
|
||||
#include <ewol/Resource.h>
|
||||
|
||||
namespace ewol
|
||||
{
|
||||
class DistantFieldFont : public ewol::Texture {
|
||||
|
||||
typedef struct {
|
||||
GlyphProperty property;
|
||||
texCoord_ts posStart;
|
||||
texCoord_ts posStop;
|
||||
}freeTypeFontElement_ts;
|
||||
private:
|
||||
int32_t m_size;
|
||||
int32_t m_height;
|
||||
ewol::Font* m_font;
|
||||
etk::Vector<freeTypeFontElement_ts> m_listElement;
|
||||
// for the texture generation :
|
||||
Vector2D<int32_t> m_lastGlyphPos;
|
||||
int32_t m_lastRawHeigh;
|
||||
public:
|
||||
DistantFieldFont(etk::UString fontName);
|
||||
~DistantFieldFont(void);
|
||||
virtual bool HasName(etk::UString& fileName);
|
||||
const char* GetType(void) { return "ewol::TexturedFont"; };
|
||||
int32_t getFontSize(void) { return m_size; };
|
||||
int32_t Draw(Vector2D<float> textPos,
|
||||
const etk::UString& unicodeString,
|
||||
etk::Vector<Vector2D<float> > & coord,
|
||||
etk::Vector<texCoord_ts> & coordTex);
|
||||
int32_t Draw(Vector2D<float> textPos,
|
||||
const uniChar_t unicodeChar,
|
||||
etk::Vector<Vector2D<float> > & coord,
|
||||
etk::Vector<texCoord_ts> & coordTex);
|
||||
Vector2D<float> GetSize(const etk::UString & unicodeString);
|
||||
Vector2D<float> GetSize(const uniChar_t unicodeChar);
|
||||
// TODO : Remove this element, it is stupid ...
|
||||
int32_t GetHeight(void) { return m_height; };
|
||||
int32_t GetFontSize(void) { return m_size; };
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -196,11 +196,8 @@ ewol::TexturedFont::TexturedFont(etk::UString fontName) :
|
||||
}
|
||||
#endif
|
||||
EWOL_DEBUG("End generation of the Fond bitmap, start adding texture");
|
||||
//m_data.DistanceField();
|
||||
Flush();
|
||||
|
||||
// initilize the texture ...
|
||||
// TODO : Do a better methode that not initialize with a stupid language ... like now ...
|
||||
//m_font->GenerateBitmapFont(m_size, m_height, m_texture, m_listElement);
|
||||
}
|
||||
|
||||
ewol::TexturedFont::~TexturedFont(void)
|
||||
|
223
Sources/libewol/ewol/oObject/2DTextShader.cpp
Normal file
223
Sources/libewol/ewol/oObject/2DTextShader.cpp
Normal file
@ -0,0 +1,223 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file ewol/oObject/2DTextColored.cpp
|
||||
* @brief ewol OpenGl Object system (Sources)
|
||||
* @author Edouard DUPIN
|
||||
* @date 16/01/2012
|
||||
* @par Project
|
||||
* ewol
|
||||
*
|
||||
* @par Copyright
|
||||
* Copyright 2011 Edouard DUPIN, all right reserved
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY.
|
||||
*
|
||||
* Licence summary :
|
||||
* You can modify and redistribute the sources code and binaries.
|
||||
* You can send me the bug-fix
|
||||
*
|
||||
* Term of the licence in in the file licence.txt.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#include <ewol/oObject/2DTextShader.h>
|
||||
#include <ewol/openGL/openGL.h>
|
||||
#include <ewol/texture/Texture.h>
|
||||
#include <ewol/font/FontManager.h>
|
||||
#include <ewol/ResourceManager.h>
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "ewol::OObject2DTextShader"
|
||||
|
||||
void ewol::OObject2DTextShader::SetFontProperty(etk::UString fontName, int32_t fontSize)
|
||||
{
|
||||
// remove old one
|
||||
if (NULL != m_font) {
|
||||
ewol::resource::Release(m_font);
|
||||
m_font = NULL;
|
||||
}
|
||||
etk::UString tmpName = fontName;
|
||||
tmpName += ":";
|
||||
tmpName += fontSize;
|
||||
// link to new One
|
||||
if (false == ewol::resource::Keep(tmpName, m_font)) {
|
||||
EWOL_ERROR("Can not get font resource");
|
||||
}
|
||||
}
|
||||
|
||||
void ewol::OObject2DTextShader::SetFont(etk::UString fontName)
|
||||
{
|
||||
// get old size
|
||||
int32_t fontSize = ewol::font::GetDefaultSize();
|
||||
if (NULL != m_font) {
|
||||
fontSize = m_font->GetFontSize();
|
||||
}
|
||||
SetFontProperty(fontName, fontSize);
|
||||
}
|
||||
|
||||
void ewol::OObject2DTextShader::SetSize(int32_t fontSize)
|
||||
{
|
||||
// get old size
|
||||
etk::UString fontName = ewol::font::GetDefaultFont();
|
||||
if (NULL != m_font) {
|
||||
fontName = m_font->GetName();
|
||||
}
|
||||
SetFontProperty(fontName, fontSize);
|
||||
}
|
||||
|
||||
ewol::OObject2DTextShader::OObject2DTextShader(etk::UString fontName, int32_t size) :
|
||||
m_font(NULL)
|
||||
{
|
||||
m_color = draw::color::black;
|
||||
SetFontProperty(fontName, size);
|
||||
etk::UString tmpString("fontDistanceField/font1.prog");
|
||||
// get the shader resource :
|
||||
m_GLPosition = 0;
|
||||
if (true == ewol::resource::Keep(tmpString, m_GLprogram) ) {
|
||||
m_GLPosition = m_GLprogram->GetAttribute("EW_coord2d");
|
||||
m_GLColor = m_GLprogram->GetAttribute("EW_color");
|
||||
m_GLtexture = m_GLprogram->GetAttribute("EW_texture2d");
|
||||
m_GLMatrix = m_GLprogram->GetUniform("EW_MatrixTransformation");
|
||||
m_GLtexID = m_GLprogram->GetUniform("EW_texID");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// open with default font ...
|
||||
ewol::OObject2DTextShader::OObject2DTextShader(void) :
|
||||
m_font(NULL)
|
||||
{
|
||||
m_color = draw::color::black;
|
||||
SetFontProperty(ewol::font::GetDefaultFont(), ewol::font::GetDefaultSize());
|
||||
etk::UString tmpString("fontDistanceField/font1.prog");
|
||||
// get the shader resource :
|
||||
m_GLPosition = 0;
|
||||
if (true == ewol::resource::Keep(tmpString, m_GLprogram) ) {
|
||||
m_GLPosition = m_GLprogram->GetAttribute("EW_coord2d");
|
||||
m_GLColor = m_GLprogram->GetAttribute("EW_color");
|
||||
m_GLtexture = m_GLprogram->GetAttribute("EW_texture2d");
|
||||
m_GLMatrix = m_GLprogram->GetUniform("EW_MatrixTransformation");
|
||||
m_GLtexID = m_GLprogram->GetUniform("EW_texID");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ewol::OObject2DTextShader::~OObject2DTextShader(void)
|
||||
{
|
||||
if (NULL != m_font) {
|
||||
ewol::resource::Release(m_font);
|
||||
m_font = NULL;
|
||||
}
|
||||
ewol::resource::Release(m_GLprogram);
|
||||
}
|
||||
|
||||
void ewol::OObject2DTextShader::Draw(void)
|
||||
{
|
||||
if (m_coord.Size()<=0 || NULL == m_font) {
|
||||
// TODO : a remètre ...
|
||||
//EWOL_WARNING("Nothink to draw...");
|
||||
return;
|
||||
}
|
||||
if (m_font == NULL) {
|
||||
EWOL_WARNING("no font...");
|
||||
return;
|
||||
}
|
||||
if (m_GLprogram==NULL) {
|
||||
EWOL_ERROR("No shader ...");
|
||||
return;
|
||||
}
|
||||
m_GLprogram->Use();
|
||||
// set Matrix : translation/positionMatrix
|
||||
etk::Matrix tmpMatrix = ewol::openGL::GetMatrix();
|
||||
m_GLprogram->SendUniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat);
|
||||
// TextureID
|
||||
m_GLprogram->SetTexture0(m_GLtexID, m_font->GetId());
|
||||
// position :
|
||||
m_GLprogram->SendAttribute(m_GLPosition, 2/*x,y*/, &m_coord[0]);
|
||||
// Texture :
|
||||
m_GLprogram->SendAttribute(m_GLtexture, 2/*u,v*/, &m_coordTex[0]);
|
||||
// color :
|
||||
m_GLprogram->SendAttribute(m_GLColor, 4/*r,g,b,a*/, &m_coordColor[0]);
|
||||
// Request the draw od the elements :
|
||||
glDrawArrays(GL_TRIANGLES, 0, m_coord.Size());
|
||||
m_GLprogram->UnUse();
|
||||
}
|
||||
|
||||
void ewol::OObject2DTextShader::Clear(void)
|
||||
{
|
||||
m_coord.Clear();
|
||||
m_coordTex.Clear();
|
||||
m_coordColor.Clear();
|
||||
}
|
||||
|
||||
int32_t ewol::OObject2DTextShader::Text(Vector2D<float> textPos, const etk::UString& unicodeString)
|
||||
{
|
||||
if (m_font == NULL) {
|
||||
EWOL_ERROR("Font Id is not corectly defined");
|
||||
return 0;
|
||||
}
|
||||
int32_t nbElementInTheArray = m_coord.Size();
|
||||
int32_t size = 0;
|
||||
if (true==m_hasClipping) {
|
||||
size = m_font->Draw(textPos, unicodeString, m_coord, m_coordTex);
|
||||
} else {
|
||||
size = m_font->Draw(textPos, unicodeString, m_coord, m_coordTex);
|
||||
}
|
||||
// set the color ...
|
||||
for (int32_t iii=nbElementInTheArray; iii<m_coord.Size(); iii++) {
|
||||
m_coordColor.PushBack(m_color);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int32_t ewol::OObject2DTextShader::Text(Vector2D<float> textPos, const uniChar_t unicodeChar)
|
||||
{
|
||||
if (m_font == NULL) {
|
||||
EWOL_ERROR("Font Id is not corectly defined");
|
||||
return 0;
|
||||
}
|
||||
int32_t nbElementInTheArray = m_coord.Size();
|
||||
int32_t size = 0;
|
||||
if (true==m_hasClipping) {
|
||||
size = m_font->Draw(textPos, unicodeChar, m_coord, m_coordTex);
|
||||
} else {
|
||||
size = m_font->Draw(textPos, unicodeChar, m_coord, m_coordTex);
|
||||
}
|
||||
for (int32_t iii=nbElementInTheArray; iii<m_coord.Size(); iii++) {
|
||||
m_coordColor.PushBack(m_color);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
void ewol::OObject2DTextShader::SetColor(draw::Color color)
|
||||
{
|
||||
m_color = color;
|
||||
}
|
||||
|
||||
|
||||
void ewol::OObject2DTextShader::SetColor(float red, float green, float blue, float alpha)
|
||||
{
|
||||
m_color = draw::Color(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
Vector2D<float> ewol::OObject2DTextShader::GetSize(const uniChar_t unicodeChar)
|
||||
{
|
||||
if (m_font == NULL) {
|
||||
EWOL_ERROR("Font Id is not corectly defined");
|
||||
return Vector2D<float>(0,0);
|
||||
}
|
||||
return m_font->GetSize(unicodeChar);
|
||||
}
|
||||
|
||||
Vector2D<float> ewol::OObject2DTextShader::GetSize(const etk::UString& unicodeString)
|
||||
{
|
||||
if (m_font == NULL) {
|
||||
EWOL_ERROR("Font Id is not corectly defined");
|
||||
return Vector2D<float>(0,0);
|
||||
}
|
||||
return m_font->GetSize(unicodeString);
|
||||
}
|
||||
|
70
Sources/libewol/ewol/oObject/2DTextShader.h
Normal file
70
Sources/libewol/ewol/oObject/2DTextShader.h
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file ewol/oObject/2DTextColored.h
|
||||
* @brief ewol OpenGl Object system (header)
|
||||
* @author Edouard DUPIN
|
||||
* @date 16/01/2012
|
||||
* @par Project
|
||||
* ewol
|
||||
*
|
||||
* @par Copyright
|
||||
* Copyright 2011 Edouard DUPIN, all right reserved
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY.
|
||||
*
|
||||
* Licence summary :
|
||||
* You can modify and redistribute the sources code and binaries.
|
||||
* You can send me the bug-fix
|
||||
*
|
||||
* Term of the licence in in the file licence.txt.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __EWOL_O_OBJECT_2D_TEXT_SHADER_H__
|
||||
#define __EWOL_O_OBJECT_2D_TEXT_SHADER_H__
|
||||
|
||||
#include <ewol/oObject/OObject.h>
|
||||
#include <ewol/font/DistantFieldFont.h>
|
||||
#include <ewol/ResourceManager.h>
|
||||
|
||||
namespace ewol {
|
||||
class OObject2DTextShader :public ewol::OObject
|
||||
{
|
||||
public:
|
||||
OObject2DTextShader(etk::UString FontName, int32_t size);
|
||||
OObject2DTextShader(void);
|
||||
virtual ~OObject2DTextShader(void);
|
||||
public:
|
||||
virtual void Draw(void);
|
||||
void SetColor(float red, float green, float blue, float alpha = 1.0);
|
||||
void SetColor(draw::Color color);
|
||||
// set a specific text
|
||||
void Clear(void);
|
||||
int32_t Text(Vector2D<float> textPos, const etk::UString& unicodeString);
|
||||
int32_t Text(Vector2D<float> textPos, const uniChar_t unicodeChar);
|
||||
protected:
|
||||
ewol::Program* m_GLprogram;
|
||||
int32_t m_GLPosition;
|
||||
int32_t m_GLMatrix;
|
||||
int32_t m_GLColor;
|
||||
int32_t m_GLtexture;
|
||||
int32_t m_GLtexID;
|
||||
ewol::DistantFieldFont* m_font; //!< ewol font system
|
||||
draw::Color m_color; //!< tmp text color ...
|
||||
etk::Vector<Vector2D<float> > m_coord; //!< internal coord of the object
|
||||
etk::Vector<texCoord_ts> m_coordTex; //!< internal texture coordinate for every point
|
||||
etk::Vector<draw::Colorf> m_coordColor; //!< internal color of the different point
|
||||
public:
|
||||
void SetFont(etk::UString fontName);
|
||||
void SetSize(int32_t fontSize);
|
||||
void SetFontProperty(etk::UString fontName, int32_t fontSize);
|
||||
int32_t GetHeight(void) { return (NULL!=m_font)?m_font->GetHeight():10; };
|
||||
Vector2D<float> GetSize(const uniChar_t unicodeChar);
|
||||
Vector2D<float> GetSize(const etk::UString& unicodeString);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -75,3 +75,6 @@ namespace ewol {
|
||||
#include <ewol/oObject/2DColored.h>
|
||||
#include <ewol/oObject/2DTextColored.h>
|
||||
|
||||
#ifdef __VIDEO__OPENGL_ES_2
|
||||
#include <ewol/oObject/2DTextShader.h>
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@ FILE_LIST+= ewol/game/GameElement.cpp \
|
||||
# Object abstraction for OpenGl
|
||||
FILE_LIST+= ewol/oObject/OObject.cpp \
|
||||
ewol/oObject/2DTextColored.cpp \
|
||||
ewol/oObject/2DTextShader.cpp \
|
||||
ewol/oObject/2DColored.cpp \
|
||||
ewol/oObject/2DTextured.cpp \
|
||||
ewol/oObject/3DTextured.cpp \
|
||||
@ -42,7 +43,8 @@ FILE_LIST+= ewol/texture/Texture.cpp \
|
||||
# fonst system
|
||||
FILE_LIST+= ewol/font/FontManager.cpp \
|
||||
ewol/font/FontFreeType.cpp \
|
||||
ewol/font/TexturedFont.cpp
|
||||
ewol/font/TexturedFont.cpp \
|
||||
ewol/font/DistantFieldFont.cpp
|
||||
|
||||
# all widgets
|
||||
FILE_LIST+= ewol/widget/Widget.cpp \
|
||||
|
26
share/fontDistanceField/font1.frag
Normal file
26
share/fontDistanceField/font1.frag
Normal file
@ -0,0 +1,26 @@
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
#endif
|
||||
|
||||
// Input :
|
||||
uniform sampler2D EW_texID;
|
||||
|
||||
varying vec2 f_texcoord;
|
||||
varying vec4 f_color;
|
||||
|
||||
void main(void) {
|
||||
vec4 tmpcolor = texture2D(EW_texID, f_texcoord);
|
||||
vec4 outColor = vec4(0,0,0,0);
|
||||
// compare distance with 0.5 that represent the middle ...
|
||||
if (tmpcolor[3]>0.5) {
|
||||
outColor = f_color;
|
||||
outColor[3] = 1.0;
|
||||
} else if (tmpcolor[3]>0.49) {
|
||||
// antialiasing :
|
||||
outColor = f_color;
|
||||
outColor[3] = (tmpcolor[3]-0.49)*1.0/0.02;
|
||||
}
|
||||
gl_FragColor = outColor;
|
||||
}
|
||||
|
2
share/fontDistanceField/font1.prog
Normal file
2
share/fontDistanceField/font1.prog
Normal file
@ -0,0 +1,2 @@
|
||||
fontDistanceField/font1.vert
|
||||
fontDistanceField/font1.frag
|
42
share/fontDistanceField/font1.vert
Normal file
42
share/fontDistanceField/font1.vert
Normal file
@ -0,0 +1,42 @@
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
#endif
|
||||
|
||||
// Input :
|
||||
attribute vec2 EW_coord2d;
|
||||
attribute vec2 EW_texture2d;
|
||||
attribute vec4 EW_color;
|
||||
uniform mat4 EW_MatrixTransformation;
|
||||
|
||||
// output :
|
||||
varying vec4 f_color;
|
||||
varying vec2 f_texcoord;
|
||||
|
||||
void main(void) {
|
||||
gl_Position = EW_MatrixTransformation * vec4(EW_coord2d, 0.0, 1.0);
|
||||
// set texture output coord
|
||||
f_texcoord = EW_texture2d;
|
||||
// set output color :
|
||||
f_color = EW_color;
|
||||
}
|
||||
|
||||
/*
|
||||
// Distance map contour texturing according to Green (2007),
|
||||
// implementation by Stefan Gustavson 2009.
|
||||
// This code is in the public domain.
|
||||
|
||||
uniform sampler2D gradtexture, reftexture;
|
||||
uniform float texw, texh;
|
||||
varying float onestepu, onestepv;
|
||||
varying vec2 st;
|
||||
|
||||
void main( void )
|
||||
{
|
||||
// Get the texture coordinates
|
||||
st = gl_MultiTexCoord0.xy;
|
||||
onestepu = 1.0 / texw; // Saves a division in the fragment shader
|
||||
onestepv = 1.0 / texh;
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
*/
|
57
share/fontDistanceField/font2.frag
Normal file
57
share/fontDistanceField/font2.frag
Normal file
@ -0,0 +1,57 @@
|
||||
// Distance map contour texturing, Stefan Gustavson 2009
|
||||
// A re-implementation of Green's method, with an
|
||||
// 8-bit distance map but explicit texel interpolation.
|
||||
// This code is in the public domain.
|
||||
|
||||
uniform sampler2D disttexture, reftexture;
|
||||
uniform float texw, texh;
|
||||
varying float onestepu, onestepv;
|
||||
varying vec2 st;
|
||||
|
||||
void main( void )
|
||||
{
|
||||
// Scale texcoords to range ([0,texw], [0,texh])
|
||||
vec2 uv = st * vec2(texw, texh);
|
||||
|
||||
// Compute texel-local (u,v) coordinates for the four closest texels
|
||||
vec2 uv00 = floor(uv - vec2(0.5)); // Lower left corner of lower left texel
|
||||
vec2 uvthis = floor(uv); // Lower left corner of texel containing (u,v)
|
||||
vec2 uvlerp = uv - uv00 - vec2(0.5); // Texel-local lerp blends [0,1]
|
||||
|
||||
// Perform explicit texture interpolation of D coefficient.
|
||||
// This works around the currently very bad texture interpolation
|
||||
// precision in ATI hardware.
|
||||
|
||||
// Center st00 on lower left texel and rescale to [0,1] for texture lookup
|
||||
vec2 st00 = (uv00 + vec2(0.5)) * vec2(onestepu, onestepv);
|
||||
|
||||
// Compute g_u, g_v, D coefficients from four closest 8-bit RGBA texels
|
||||
vec4 rawtex00 = texture2D(disttexture, st00);
|
||||
vec4 rawtex10 = texture2D(disttexture, st00 + vec2(0.5*onestepu, 0.0));
|
||||
vec4 rawtex01 = texture2D(disttexture, st00 + vec2(0.0, 0.5*onestepv));
|
||||
vec4 rawtex11 = texture2D(disttexture, st00 + vec2(0.5*onestepu, 0.5*onestepv));
|
||||
|
||||
// Restore the value for D from its 8-bit encoding
|
||||
vec2 D00_10 = 16.0*(vec2(rawtex00.r, rawtex10.r)-0.50196);
|
||||
vec2 D01_11 = 16.0*(vec2(rawtex01.r, rawtex11.r)-0.50196);
|
||||
|
||||
// Interpolate D between four closest texels
|
||||
vec2 uvlocal = fract(uv)-0.5; // Texel-local uv coordinates [-0.5,0.5]
|
||||
// Interpolate along v
|
||||
vec2 D0_1 = mix(D00_10, D01_11, uvlerp.y);
|
||||
// Interpolate along u
|
||||
float D = mix(D0_1.x, D0_1.y, uvlerp.x);
|
||||
|
||||
// Perform anisotropic analytic antialiasing (fwidth() is slightly wrong)
|
||||
float aastep = length(vec2(dFdx(D), dFdy(D)));
|
||||
|
||||
// 'pattern' is 1 where D>0, 0 where D<0, with proper AA around D=0.
|
||||
float pattern = smoothstep(-aastep, aastep, D);
|
||||
|
||||
// 'bitmap' is a regular grayscale texture with AA for comparison.
|
||||
vec2 uvoffset = uvthis - uv00; // 0 or 1 depending on (u,v) quadrant
|
||||
float bitmap = texture2D(reftexture, st00+uvoffset*vec2(onestepu, onestepv)).r;
|
||||
|
||||
// Final fragment color
|
||||
gl_FragColor = vec4(bitmap, pattern, bitmap, 1.0);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user