mirror of https://github.com/buggins/dlangui.git
GL texture drawing is working
This commit is contained in:
parent
2dc0a9ff82
commit
69fd696458
|
@ -16,6 +16,14 @@ struct Rect {
|
||||||
int top;
|
int top;
|
||||||
int right;
|
int right;
|
||||||
int bottom;
|
int bottom;
|
||||||
|
@property int middlex() { return (left + right) / 2; }
|
||||||
|
@property int middley() { return (top + bottom) / 2; }
|
||||||
|
void offset(int dx, int dy) {
|
||||||
|
left += dx;
|
||||||
|
right += dx;
|
||||||
|
top += dy;
|
||||||
|
bottom += dy;
|
||||||
|
}
|
||||||
@property int width() { return right - left; }
|
@property int width() { return right - left; }
|
||||||
@property int height() { return bottom - top; }
|
@property int height() { return bottom - top; }
|
||||||
this(int x0, int y0, int x1, int y1) {
|
this(int x0, int y0, int x1, int y1) {
|
||||||
|
|
|
@ -5,6 +5,9 @@ import dlangui.core.logger;
|
||||||
|
|
||||||
/// blend two RGB pixels using alpha
|
/// blend two RGB pixels using alpha
|
||||||
uint blendARGB(uint dst, uint src, uint alpha) {
|
uint blendARGB(uint dst, uint src, uint alpha) {
|
||||||
|
uint dstalpha = dst >> 24;
|
||||||
|
if (dstalpha > 0x80)
|
||||||
|
return src;
|
||||||
uint srcr = (src >> 16) & 0xFF;
|
uint srcr = (src >> 16) & 0xFF;
|
||||||
uint srcg = (src >> 8) & 0xFF;
|
uint srcg = (src >> 8) & 0xFF;
|
||||||
uint srcb = (src >> 0) & 0xFF;
|
uint srcb = (src >> 0) & 0xFF;
|
||||||
|
|
|
@ -63,10 +63,20 @@ class GLDrawBuf : DrawBuf {
|
||||||
/// draw source buffer rectangle contents to destination buffer
|
/// draw source buffer rectangle contents to destination buffer
|
||||||
override void drawFragment(int x, int y, DrawBuf src, Rect srcrect) {
|
override void drawFragment(int x, int y, DrawBuf src, Rect srcrect) {
|
||||||
assert(_scene !is null);
|
assert(_scene !is null);
|
||||||
|
GLImageCacheItem item = glImageCache.get(src.id);
|
||||||
|
if (item is null)
|
||||||
|
item = glImageCache.set(src);
|
||||||
|
Rect dstrect = Rect(x, y, x + srcrect.width, y + srcrect.height);
|
||||||
|
// TODO: clipping
|
||||||
|
_scene.add(new TextureSceneItem(src.id, dstrect, srcrect, 0xFFFFFF, 0, null, 0));
|
||||||
}
|
}
|
||||||
/// draw source buffer rectangle contents to destination buffer rectangle applying rescaling
|
/// draw source buffer rectangle contents to destination buffer rectangle applying rescaling
|
||||||
override void drawRescaled(Rect dstrect, DrawBuf src, Rect srcrect) {
|
override void drawRescaled(Rect dstrect, DrawBuf src, Rect srcrect) {
|
||||||
assert(_scene !is null);
|
assert(_scene !is null);
|
||||||
|
GLImageCacheItem item = glImageCache.get(src.id);
|
||||||
|
if (item is null)
|
||||||
|
item = glImageCache.set(src);
|
||||||
|
_scene.add(new TextureSceneItem(src.id, dstrect, srcrect, 0xFFFFFF, 0, null, 0));
|
||||||
}
|
}
|
||||||
override void clear() {
|
override void clear() {
|
||||||
}
|
}
|
||||||
|
@ -80,10 +90,7 @@ public:
|
||||||
@property GLImageCachePage page() { return _page; }
|
@property GLImageCachePage page() { return _page; }
|
||||||
uint _objectId;
|
uint _objectId;
|
||||||
// image size
|
// image size
|
||||||
int _dx;
|
Rect _rc;
|
||||||
int _dy;
|
|
||||||
int _x0;
|
|
||||||
int _y0;
|
|
||||||
bool _deleted;
|
bool _deleted;
|
||||||
this(GLImageCachePage page, uint objectId) { _page = page; _objectId = objectId; }
|
this(GLImageCachePage page, uint objectId) { _page = page; _objectId = objectId; }
|
||||||
};
|
};
|
||||||
|
@ -197,10 +204,10 @@ public:
|
||||||
_map.clear();
|
_map.clear();
|
||||||
}
|
}
|
||||||
/// draw cached item
|
/// draw cached item
|
||||||
void drawItem(uint objectId, int x, int y, int dx, int dy, int srcx, int srcy, int srcwidth, int srcheight, uint color, int options, Rect * clip, int rotationAngle) {
|
void drawItem(uint objectId, Rect dstrc, Rect srcrc, uint color, int options, Rect * clip, int rotationAngle) {
|
||||||
if (objectId in _map) {
|
if (objectId in _map) {
|
||||||
GLImageCacheItem item = _map[objectId];
|
GLImageCacheItem item = _map[objectId];
|
||||||
item.page.drawItem(item, x, y, dx, dy, srcx, srcy, srcwidth, srcheight, color, options, clip, rotationAngle);
|
item.page.drawItem(item, dstrc, srcrc, color, options, clip, rotationAngle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// handle cached object deletion, mark as deleted
|
/// handle cached object deletion, mark as deleted
|
||||||
|
@ -314,13 +321,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void invertAlpha(GLImageCacheItem item) {
|
void invertAlpha(GLImageCacheItem item) {
|
||||||
int x0 = item._x0;
|
Rect rc = item._rc;
|
||||||
int y0 = item._y0;
|
for (int y = rc.top; y < rc.bottom; y++) {
|
||||||
int x1 = x0 + item._dx;
|
|
||||||
int y1 = y0 + item._dy;
|
|
||||||
for (int y = y0; y < y1; y++) {
|
|
||||||
uint * row = _drawbuf.scanLine(y);
|
uint * row = _drawbuf.scanLine(y);
|
||||||
for (int x = x0; x < x1; x++) {
|
for (int x = rc.left; x < rc.right; x++) {
|
||||||
uint cl = row[x];
|
uint cl = row[x];
|
||||||
cl ^= 0xFF000000;
|
cl ^= 0xFF000000;
|
||||||
uint r = (cl & 0x00FF0000) >> 16;
|
uint r = (cl & 0x00FF0000) >> 16;
|
||||||
|
@ -335,30 +339,27 @@ public:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// next line if necessary
|
// next line if necessary
|
||||||
if (_x + width > _tdx) {
|
if (_x + width + 2 > _tdx) {
|
||||||
// move to next line
|
// move to next line
|
||||||
_currentLine = _nextLine;
|
_currentLine = _nextLine;
|
||||||
_x = 0;
|
_x = 0;
|
||||||
}
|
}
|
||||||
// check if no room left for glyph height
|
// check if no room left for glyph height
|
||||||
if (_currentLine + height > _tdy) {
|
if (_currentLine + height + 2 > _tdy) {
|
||||||
_closed = true;
|
_closed = true;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
cacheItem._dx = width;
|
cacheItem._rc = Rect(_x + 1, _currentLine + 1, _x + width + 1, _currentLine + height + 1);
|
||||||
cacheItem._dy = height;
|
|
||||||
cacheItem._x0 = _x;
|
|
||||||
cacheItem._y0 = _currentLine;
|
|
||||||
if (height && width) {
|
if (height && width) {
|
||||||
if (_nextLine < _currentLine + height)
|
if (_nextLine < _currentLine + height + 2)
|
||||||
_nextLine = _currentLine + height;
|
_nextLine = _currentLine + height + 2;
|
||||||
if (!_drawbuf) {
|
if (!_drawbuf) {
|
||||||
_drawbuf = new ColorDrawBuf(_tdx, _tdy);
|
_drawbuf = new ColorDrawBuf(_tdx, _tdy);
|
||||||
//_drawbuf.SetBackgroundColor(0x000000);
|
//_drawbuf.SetBackgroundColor(0x000000);
|
||||||
//_drawbuf.SetTextColor(0xFFFFFF);
|
//_drawbuf.SetTextColor(0xFFFFFF);
|
||||||
_drawbuf.fill(0xFF000000);
|
_drawbuf.fill(0xFF000000);
|
||||||
}
|
}
|
||||||
_x += width;
|
_x += width + 1;
|
||||||
_needUpdateTexture = true;
|
_needUpdateTexture = true;
|
||||||
}
|
}
|
||||||
_itemCount++;
|
_itemCount++;
|
||||||
|
@ -373,12 +374,12 @@ public:
|
||||||
if (cacheItem is null)
|
if (cacheItem is null)
|
||||||
return null;
|
return null;
|
||||||
buf.onDestroyCallback = &onObjectDestroyedCallback;
|
buf.onDestroyCallback = &onObjectDestroyedCallback;
|
||||||
_drawbuf.drawImage(cacheItem._x0, cacheItem._y0, buf);
|
_drawbuf.drawImage(cacheItem._rc.left, cacheItem._rc.top, buf);
|
||||||
invertAlpha(cacheItem);
|
invertAlpha(cacheItem);
|
||||||
_needUpdateTexture = true;
|
_needUpdateTexture = true;
|
||||||
return cacheItem;
|
return cacheItem;
|
||||||
}
|
}
|
||||||
void drawItem(GLImageCacheItem item, int x, int y, int dx, int dy, int srcx, int srcy, int srcdx, int srcdy, uint color, uint options, Rect * clip, int rotationAngle) {
|
void drawItem(GLImageCacheItem item, Rect dstrc, Rect srcrc, uint color, uint options, Rect * clip, int rotationAngle) {
|
||||||
//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)
|
||||||
updateTexture();
|
updateTexture();
|
||||||
|
@ -388,15 +389,14 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//rotationAngle = 0;
|
//rotationAngle = 0;
|
||||||
int rx = x + dx / 2;
|
int rx = dstrc.middlex;
|
||||||
int ry = (y + dy / 2);
|
int ry = dstrc.middley;
|
||||||
if (rotationAngle) {
|
if (rotationAngle) {
|
||||||
//rotationAngle = 0;
|
//rotationAngle = 0;
|
||||||
//setRotation(rx, ry, rotationAngle);
|
//setRotation(rx, ry, rotationAngle);
|
||||||
}
|
}
|
||||||
|
// convert coordinates to cached texture
|
||||||
Rect srcrc = Rect(item._x0 + srcx, item._y0 + srcy, item._x0 + srcx+srcdx, item._y0 + srcy+srcdy);
|
srcrc.offset(item._rc.left, item._rc.top);
|
||||||
Rect dstrc = Rect(x, y, x + dx, y+dy);
|
|
||||||
if (clip) {
|
if (clip) {
|
||||||
int srcw = srcrc.width();
|
int srcw = srcrc.width();
|
||||||
int srch = srcrc.height();
|
int srch = srcrc.height();
|
||||||
|
@ -416,7 +416,7 @@ public:
|
||||||
dstrc.bottom -= clip.bottom;
|
dstrc.bottom -= clip.bottom;
|
||||||
}
|
}
|
||||||
if (!dstrc.empty)
|
if (!dstrc.empty)
|
||||||
drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, srcrc.width() != dstrc.width() || srcrc.height() != dstrc.height());
|
drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, false); //srcrc.width() != dstrc.width() || srcrc.height() != dstrc.height()
|
||||||
//drawColorAndTextureRect(vertices, texcoords, color, _textureId);
|
//drawColorAndTextureRect(vertices, texcoords, color, _textureId);
|
||||||
|
|
||||||
if (rotationAngle) {
|
if (rotationAngle) {
|
||||||
|
@ -437,3 +437,31 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private class TextureSceneItem : SceneItem {
|
||||||
|
uint objectId;
|
||||||
|
//CacheableObject * img;
|
||||||
|
Rect dstrc;
|
||||||
|
Rect srcrc;
|
||||||
|
uint color;
|
||||||
|
uint options;
|
||||||
|
Rect * clip;
|
||||||
|
int rotationAngle;
|
||||||
|
public:
|
||||||
|
override void draw() {
|
||||||
|
if (glImageCache)
|
||||||
|
glImageCache.drawItem(objectId, dstrc, srcrc, color, options, clip, rotationAngle);
|
||||||
|
}
|
||||||
|
this(uint _objectId, Rect _dstrc, Rect _srcrc, uint _color, uint _options, Rect * _clip, int _rotationAngle)
|
||||||
|
{
|
||||||
|
objectId = _objectId;
|
||||||
|
dstrc = _dstrc;
|
||||||
|
srcrc = _srcrc;
|
||||||
|
color = _color;
|
||||||
|
options = _options;
|
||||||
|
clip = _clip;
|
||||||
|
rotationAngle = _rotationAngle;
|
||||||
|
}
|
||||||
|
~this() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ void drawSolidFillRect(Rect rc, uint color1, uint color2, uint color3, uint colo
|
||||||
x1,y1,Z_2D,
|
x1,y1,Z_2D,
|
||||||
x1,y0,Z_2D];
|
x1,y0,Z_2D];
|
||||||
if (_solidFillProgram !is null) {
|
if (_solidFillProgram !is null) {
|
||||||
Log.d("solid fill: vertices ", vertices, " colors ", colors);
|
//Log.d("solid fill: vertices ", vertices, " colors ", colors);
|
||||||
_solidFillProgram.execute(vertices, colors);
|
_solidFillProgram.execute(vertices, colors);
|
||||||
} else
|
} else
|
||||||
Log.e("No program");
|
Log.e("No program");
|
||||||
|
@ -67,6 +67,7 @@ void drawSolidFillRect(Rect rc, uint color1, uint color2, uint color3, uint colo
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawColorAndTextureRect(uint textureId, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color, bool linear) {
|
void drawColorAndTextureRect(uint textureId, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color, bool linear) {
|
||||||
|
Log.v("drawColorAndTextureRect tx=", textureId, " src=", srcrc, " dst=", dstrc);
|
||||||
drawColorAndTextureRect(textureId, tdx, tdy, srcrc.left, srcrc.top, srcrc.width(), srcrc.height(), dstrc.left, dstrc.top, dstrc.width(), dstrc.height(), color, linear);
|
drawColorAndTextureRect(textureId, tdx, tdy, srcrc.left, srcrc.top, srcrc.width(), srcrc.height(), dstrc.left, dstrc.top, dstrc.width(), dstrc.height(), color, linear);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ __gshared DrawableCache _drawableCache;
|
||||||
/// drawable cache singleton
|
/// drawable cache singleton
|
||||||
@property DrawableCache drawableCache() { return _drawableCache; }
|
@property DrawableCache drawableCache() { return _drawableCache; }
|
||||||
|
|
||||||
static this() {
|
shared static this() {
|
||||||
_imageCache = new ImageCache();
|
_imageCache = new ImageCache();
|
||||||
_drawableCache = new DrawableCache();
|
_drawableCache = new DrawableCache();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import dlangui.platforms.common.platform;
|
||||||
import dlangui.platforms.windows.win32fonts;
|
import dlangui.platforms.windows.win32fonts;
|
||||||
import dlangui.platforms.windows.win32drawbuf;
|
import dlangui.platforms.windows.win32drawbuf;
|
||||||
import dlangui.graphics.drawbuf;
|
import dlangui.graphics.drawbuf;
|
||||||
|
import dlangui.graphics.images;
|
||||||
import dlangui.graphics.fonts;
|
import dlangui.graphics.fonts;
|
||||||
import dlangui.graphics.glsupport;
|
import dlangui.graphics.glsupport;
|
||||||
import dlangui.core.logger;
|
import dlangui.core.logger;
|
||||||
|
@ -131,7 +132,7 @@ class Win32Window : Window {
|
||||||
_caption = windowCaption;
|
_caption = windowCaption;
|
||||||
_hwnd = CreateWindow(toUTF16z(WIN_CLASS_NAME), // window class name
|
_hwnd = CreateWindow(toUTF16z(WIN_CLASS_NAME), // window class name
|
||||||
toUTF16z(windowCaption), // window caption
|
toUTF16z(windowCaption), // window caption
|
||||||
WS_OVERLAPPEDWINDOW, // window style
|
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, // window style
|
||||||
CW_USEDEFAULT, // initial x position
|
CW_USEDEFAULT, // initial x position
|
||||||
CW_USEDEFAULT, // initial y position
|
CW_USEDEFAULT, // initial y position
|
||||||
CW_USEDEFAULT, // initial x size
|
CW_USEDEFAULT, // initial x size
|
||||||
|
@ -226,6 +227,12 @@ class Win32Window : Window {
|
||||||
void onPaint() {
|
void onPaint() {
|
||||||
Log.d("onPaint()");
|
Log.d("onPaint()");
|
||||||
if (useOpengl && _hGLRC) {
|
if (useOpengl && _hGLRC) {
|
||||||
|
// hack to stop infinite WM_PAINT loop
|
||||||
|
PAINTSTRUCT ps;
|
||||||
|
HDC hdc2 = BeginPaint(_hwnd, &ps);
|
||||||
|
EndPaint(_hwnd, &ps);
|
||||||
|
|
||||||
|
|
||||||
import derelict.opengl3.gl3;
|
import derelict.opengl3.gl3;
|
||||||
import derelict.opengl3.wgl;
|
import derelict.opengl3.wgl;
|
||||||
import dlangui.graphics.gldrawbuf;
|
import dlangui.graphics.gldrawbuf;
|
||||||
|
@ -245,9 +252,22 @@ class Win32Window : Window {
|
||||||
buf.fillRect(Rect(100, 100, 200, 200), 0x704020);
|
buf.fillRect(Rect(100, 100, 200, 200), 0x704020);
|
||||||
buf.fillRect(Rect(40, 70, 100, 120), 0x000000);
|
buf.fillRect(Rect(40, 70, 100, 120), 0x000000);
|
||||||
buf.fillRect(Rect(80, 80, 150, 150), 0x80008000); // green
|
buf.fillRect(Rect(80, 80, 150, 150), 0x80008000); // green
|
||||||
|
DrawableRef img = drawableCache.get("exit");
|
||||||
|
if (!img.isNull) {
|
||||||
|
img.drawTo(buf, Rect(300, 100, 364, 164));
|
||||||
|
img.drawTo(buf, Rect(400, 200, 528, 328));
|
||||||
|
}
|
||||||
|
DrawableRef img2 = drawableCache.get("btn_default_pressed");
|
||||||
|
if (!img2.isNull) {
|
||||||
|
img2.drawTo(buf, Rect(300, 200, 564, 264));
|
||||||
|
img2.drawTo(buf, Rect(600, 200, 628, 328));
|
||||||
|
}
|
||||||
|
drawableCache.get("btn_default_normal").drawTo(buf, Rect(300, 0, 400, 50));;
|
||||||
|
drawableCache.get("btn_default_selected").drawTo(buf, Rect(0, 0, 100, 50));;
|
||||||
buf.afterDrawing();
|
buf.afterDrawing();
|
||||||
//Log.d("onPaint() end drawing opengl");
|
//Log.d("onPaint() end drawing opengl");
|
||||||
SwapBuffers(hdc);
|
SwapBuffers(hdc);
|
||||||
|
wglMakeCurrent(hdc, null);
|
||||||
} else {
|
} else {
|
||||||
PAINTSTRUCT ps;
|
PAINTSTRUCT ps;
|
||||||
HDC hdc = BeginPaint(_hwnd, &ps);
|
HDC hdc = BeginPaint(_hwnd, &ps);
|
||||||
|
@ -268,14 +288,14 @@ class Win32Platform : Platform {
|
||||||
//MSG msg;
|
//MSG msg;
|
||||||
WNDCLASS wndclass;
|
WNDCLASS wndclass;
|
||||||
|
|
||||||
wndclass.style = CS_HREDRAW | CS_VREDRAW;
|
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
||||||
wndclass.lpfnWndProc = &WndProc;
|
wndclass.lpfnWndProc = &WndProc;
|
||||||
wndclass.cbClsExtra = 0;
|
wndclass.cbClsExtra = 0;
|
||||||
wndclass.cbWndExtra = 0;
|
wndclass.cbWndExtra = 0;
|
||||||
wndclass.hInstance = _hInstance;
|
wndclass.hInstance = _hInstance;
|
||||||
wndclass.hIcon = LoadIcon(null, IDI_APPLICATION);
|
wndclass.hIcon = LoadIcon(null, IDI_APPLICATION);
|
||||||
wndclass.hCursor = LoadCursor(null, IDC_ARROW);
|
wndclass.hCursor = LoadCursor(null, IDC_ARROW);
|
||||||
wndclass.hbrBackground = cast(HBRUSH)GetStockObject(WHITE_BRUSH);
|
wndclass.hbrBackground = null; //cast(HBRUSH)GetStockObject(WHITE_BRUSH);
|
||||||
wndclass.lpszMenuName = null;
|
wndclass.lpszMenuName = null;
|
||||||
wndclass.lpszClassName = toUTF16z(WIN_CLASS_NAME);
|
wndclass.lpszClassName = toUTF16z(WIN_CLASS_NAME);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue