subpixel rendering for OpenGL, part 2

This commit is contained in:
Vadim Lopatin 2015-01-26 10:39:50 +03:00
parent 4e90c9b39e
commit 3e53fdb3db
4 changed files with 60 additions and 36 deletions

View File

@ -188,13 +188,13 @@ extern (C) int UIAppMain(string[] args) {
// embed resources listed in views/resources.list into executable // embed resources listed in views/resources.list into executable
embeddedResourceList.addResources(embedResourcesFromList!("resources.list")()); embeddedResourceList.addResources(embedResourcesFromList!("resources.list")());
version (USE_OPENGL) { //version (USE_OPENGL) {
// you can turn on subpixel font rendering (ClearType) here // // you can turn on subpixel font rendering (ClearType) here
FontManager.subpixelRenderingMode = SubpixelRenderingMode.None; // //FontManager.subpixelRenderingMode = SubpixelRenderingMode.None; //
} else { //} else {
// you can turn on subpixel font rendering (ClearType) here // you can turn on subpixel font rendering (ClearType) here
FontManager.subpixelRenderingMode = SubpixelRenderingMode.BGR; //SubpixelRenderingMode.None; // FontManager.subpixelRenderingMode = SubpixelRenderingMode.BGR; //SubpixelRenderingMode.None; //
} //}
// select translation file - for english language // select translation file - for english language
Platform.instance.uiLanguage = "en"; Platform.instance.uiLanguage = "en";
@ -206,13 +206,13 @@ extern (C) int UIAppMain(string[] args) {
// you can override antialiasing setting here (0 means antialiasing always on, some big value = always off) // you can override antialiasing setting here (0 means antialiasing always on, some big value = always off)
// fonts with size less than specified value will not be antialiased // fonts with size less than specified value will not be antialiased
FontManager.minAnitialiasedFontSize = 0; // 0 means always antialiased FontManager.minAnitialiasedFontSize = 0; // 0 means always antialiased
version (USE_OPENGL) { //version (USE_OPENGL) {
// you can turn on subpixel font rendering (ClearType) here // // you can turn on subpixel font rendering (ClearType) here
FontManager.subpixelRenderingMode = SubpixelRenderingMode.None; // // FontManager.subpixelRenderingMode = SubpixelRenderingMode.None; //
} else { //} else {
// you can turn on subpixel font rendering (ClearType) here // you can turn on subpixel font rendering (ClearType) here
FontManager.subpixelRenderingMode = SubpixelRenderingMode.BGR; //SubpixelRenderingMode.None; // FontManager.subpixelRenderingMode = SubpixelRenderingMode.BGR; //SubpixelRenderingMode.None; //
} //}
// create window // create window
Window window = Platform.instance.createWindow("My Window", null); Window window = Platform.instance.createWindow("My Window", null);

View File

@ -612,21 +612,22 @@ class ColorDrawBufBase : DrawBuf {
int increment = subpixel ? 3 : 1; int increment = subpixel ? 3 : 1;
for (int xx = 0; xx <= srcdx - increment; xx += increment) { for (int xx = 0; xx <= srcdx - increment; xx += increment) {
int colx = x + (subpixel ? xx / 3 : xx); int colx = x + (subpixel ? xx / 3 : xx);
uint alpha1 = srcrow[xx] ^ 255;
if (subpixel) { if (subpixel) {
//int x0 = xx % 3; uint t1 = srcrow[xx];
//ubyte * dst = cast(ubyte*)(row + colx); uint t2 = srcrow[xx + 1];
//ubyte * pcolor = cast(ubyte*)(&color); uint t3 = srcrow[xx + 2];
//blendSubpixel(dst, pcolor, alpha, x0, glyph.subpixelMode); //uint pixel = ((t2 ^ 0x00) << 24) | ((t1 ^ 0xFF)<< 16) | ((t2 ^ 0xFF) << 8) | (t3 ^ 0xFF);
uint pixel = ((t2 ^ 0x00) << 24) | 0xFFFFFF;
row[colx] = pixel;
} else { } else {
uint pixel = (alpha1 << 24) || 0xFFFFFF; //(alpha1 << 16) || (alpha1 << 8) || alpha1; uint alpha1 = srcrow[xx] ^ 0xFF;
//uint pixel = (alpha1 << 24) | 0xFFFFFF; //(alpha1 << 16) || (alpha1 << 8) || alpha1;
//uint pixel = ((alpha1 ^ 0xFF) << 24) | (alpha1 << 16) | (alpha1 << 8) | alpha1;
uint pixel = ((alpha1 ^ 0xFF) << 24) | 0xFFFFFF;
row[colx] = pixel; row[colx] = pixel;
} }
} }
} }
// for debugging
fillRect(Rect(x,y,x+2, y+2), 0xFF8040C0);
fillRect(Rect(x+2,y+2,x+4, y+4), 0x40408070);
} }
override void fillRect(Rect rc, uint color) { override void fillRect(Rect rc, uint color) {

View File

@ -257,12 +257,12 @@ private class GLImageCache {
if (_drawbuf is null) if (_drawbuf is null)
return; // no draw buffer!!! return; // no draw buffer!!!
if (_textureId == 0) { if (_textureId == 0) {
//CRLog::debug("updateTexture - new texture");
_textureId = glSupport.genTexture(); _textureId = glSupport.genTexture();
Log.d("updateTexture - new texture id=", _textureId);
if (!_textureId) if (!_textureId)
return; return;
} }
//CRLog::debug("updateTexture - setting image %dx%d", _drawbuf.width, _drawbuf.height); Log.d("updateTexture for image cache page - setting image ", _drawbuf.width, "x", _drawbuf.height, " tx=", _textureId);
uint * pixels = _drawbuf.scanLine(0); uint * pixels = _drawbuf.scanLine(0);
if (!glSupport.setTextureImage(_textureId, _drawbuf.width, _drawbuf.height, cast(ubyte*)pixels)) { if (!glSupport.setTextureImage(_textureId, _drawbuf.width, _drawbuf.height, cast(ubyte*)pixels)) {
glSupport.deleteTexture(_textureId); glSupport.deleteTexture(_textureId);
@ -565,7 +565,7 @@ private class GLGlyphCache {
this(GLGlyphCache cache, int dx, int dy) { this(GLGlyphCache cache, int dx, int dy) {
_cache = cache; _cache = cache;
Log.v("created image cache page ", dx, "x", dy); Log.v("created glyph cache page ", dx, "x", dy);
_tdx = nearestPOT(dx); _tdx = nearestPOT(dx);
_tdy = nearestPOT(dy); _tdy = nearestPOT(dy);
_itemCount = 0; _itemCount = 0;
@ -586,12 +586,12 @@ private class GLGlyphCache {
if (_drawbuf is null) if (_drawbuf is null)
return; // no draw buffer!!! return; // no draw buffer!!!
if (_textureId == 0) { if (_textureId == 0) {
//CRLog::debug("updateTexture - new texture");
_textureId = glSupport.genTexture(); _textureId = glSupport.genTexture();
//Log.d("updateTexture - new texture ", _textureId);
if (!_textureId) if (!_textureId)
return; return;
} }
//CRLog::debug("updateTexture - setting image %dx%d", _drawbuf.width, _drawbuf.height); //Log.d("updateTexture for font glyph page - setting image ", _drawbuf.width, "x", _drawbuf.height, " tx=", _textureId);
int len = _drawbuf.width * _drawbuf.height; int len = _drawbuf.width * _drawbuf.height;
if (!glSupport.setTextureImage(_textureId, _drawbuf.width, _drawbuf.height, cast(ubyte *)_drawbuf.scanLine(0))) { if (!glSupport.setTextureImage(_textureId, _drawbuf.width, _drawbuf.height, cast(ubyte *)_drawbuf.scanLine(0))) {
glSupport.deleteTexture(_textureId); glSupport.deleteTexture(_textureId);
@ -642,6 +642,7 @@ private class GLGlyphCache {
_itemCount--; _itemCount--;
return _itemCount; return _itemCount;
} }
GLGlyphCacheItem addItem(Glyph * glyph) { GLGlyphCacheItem addItem(Glyph * glyph) {
GLGlyphCacheItem cacheItem = reserveSpace(glyph.id, glyph.correctedBlackBoxX, glyph.blackBoxY); GLGlyphCacheItem cacheItem = reserveSpace(glyph.id, glyph.correctedBlackBoxX, glyph.blackBoxY);
if (cacheItem is null) if (cacheItem is null)
@ -651,6 +652,7 @@ private class GLGlyphCache {
_needUpdateTexture = true; _needUpdateTexture = true;
return cacheItem; return cacheItem;
} }
void drawItem(GLGlyphCacheItem item, Rect dstrc, Rect srcrc, uint color, Rect * clip) { void drawItem(GLGlyphCacheItem item, Rect dstrc, Rect srcrc, uint color, Rect * clip) {
//CRLog::trace("drawing item at %d,%d %dx%d <= %d,%d %dx%d ", x, y, dx, dy, srcx, srcy, srcdx, srcdy); //CRLog::trace("drawing item at %d,%d %dx%d <= %d,%d %dx%d ", x, y, dx, dy, srcx, srcy, srcdx, srcdy);
if (_needUpdateTexture) if (_needUpdateTexture)
@ -682,7 +684,7 @@ private class GLGlyphCache {
} }
if (!dstrc.empty) { if (!dstrc.empty) {
//Log.d("drawing glyph with color ", color); //Log.d("drawing glyph with color ", color);
glSupport.drawColorAndTextureGlyphRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, false); glSupport.drawColorAndTextureGlyphRect(_textureId, _tdx, _tdy, srcrc, dstrc, color);
//glSupport.drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, false); //glSupport.drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, false);
} }

View File

@ -451,6 +451,26 @@ class FontProgram : SolidFillProgram {
return res && texCoordLocation >= 0; return res && texCoordLocation >= 0;
} }
override void beforeExecute() {
glEnable(GL_BLEND);
glDisable(GL_CULL_FACE);
checkError("glDisable(GL_CULL_FACE)");
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glBlendFunc(GL_ONE, GL_SRC_COLOR);
//glBlendFunc(GL_ONE, GL_SRC_COLOR);
//glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
//glBlendFunc(GL_ONE_MINUS_SRC_COLOR, GL_SRC_COLOR);
checkError("glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR)");
bind();
glUniformMatrix4fv(matrixLocation, 1, false, glSupport.qtmatrix.ptr);
checkError("glUniformMatrix4fv");
}
override void afterExecute() {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
super.afterExecute();
}
bool execute(float[] vertices, float[] texcoords, float[] colors, uint textureId, bool linear) { bool execute(float[] vertices, float[] texcoords, float[] colors, uint textureId, bool linear) {
if (error) if (error)
return false; return false;
@ -642,12 +662,12 @@ class GLSupport {
Log.e("No program"); Log.e("No program");
} }
void drawColorAndTextureGlyphRect(uint textureId, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color, bool linear) { void drawColorAndTextureGlyphRect(uint textureId, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color) {
//Log.v("drawColorAndTextureRect tx=", textureId, " src=", srcrc, " dst=", dstrc); //Log.v("drawColorAndGlyphRect tx=", textureId, " src=", srcrc, " dst=", dstrc);
drawColorAndTextureGlyphRect(textureId, tdx, tdy, srcrc.left, srcrc.top, srcrc.width(), srcrc.height(), dstrc.left, dstrc.top, dstrc.width(), dstrc.height(), color, linear); drawColorAndTextureGlyphRect(textureId, tdx, tdy, srcrc.left, srcrc.top, srcrc.width(), srcrc.height(), dstrc.left, dstrc.top, dstrc.width(), dstrc.height(), color);
} }
void drawColorAndTextureGlyphRect(uint textureId, int tdx, int tdy, int srcx, int srcy, int srcdx, int srcdy, int xx, int yy, int dx, int dy, uint color, bool linear) { void drawColorAndTextureGlyphRect(uint textureId, int tdx, int tdy, int srcx, int srcy, int srcdx, int srcdy, int xx, int yy, int dx, int dy, uint color) {
float[6*4] colors; float[6*4] colors;
LVGLFillColor(color, colors.ptr, 6); LVGLFillColor(color, colors.ptr, 6);
float dstx0 = cast(float)xx; float dstx0 = cast(float)xx;
@ -665,14 +685,15 @@ class GLSupport {
float srcy0 = srcy / cast(float)tdy; float srcy0 = srcy / cast(float)tdy;
float srcx1 = (srcx + srcdx) / cast(float)tdx; float srcx1 = (srcx + srcdx) / cast(float)tdx;
float srcy1 = (srcy + srcdy) / cast(float)tdy; float srcy1 = (srcy + srcdy) / cast(float)tdy;
float[3 * 6] vertices = [dstx0,dsty0,Z_2D, float[3 * 6] vertices =
dstx0,dsty1,Z_2D, [dstx0, dsty0, Z_2D,
dstx1,dsty1,Z_2D, dstx0, dsty1, Z_2D,
dstx0,dsty0,Z_2D, dstx1, dsty1, Z_2D,
dstx1,dsty1,Z_2D, dstx0, dsty0, Z_2D,
dstx1,dsty0,Z_2D]; dstx1, dsty1, Z_2D,
dstx1, dsty0, Z_2D];
float[2 * 6] texcoords = [srcx0,srcy0, srcx0,srcy1, srcx1,srcy1, srcx0,srcy0, srcx1,srcy1, srcx1,srcy0]; float[2 * 6] texcoords = [srcx0,srcy0, srcx0,srcy1, srcx1,srcy1, srcx0,srcy0, srcx1,srcy1, srcx1,srcy0];
_fontProgram.execute(vertices, texcoords, colors, textureId, linear); _fontProgram.execute(vertices, texcoords, colors, textureId, false);
//drawColorAndTextureRect(vertices, texcoords, colors, textureId, linear); //drawColorAndTextureRect(vertices, texcoords, colors, textureId, linear);
} }