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 right;
|
||||
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 height() { return bottom - top; }
|
||||
this(int x0, int y0, int x1, int y1) {
|
||||
|
|
|
@ -5,6 +5,9 @@ import dlangui.core.logger;
|
|||
|
||||
/// blend two RGB pixels using alpha
|
||||
uint blendARGB(uint dst, uint src, uint alpha) {
|
||||
uint dstalpha = dst >> 24;
|
||||
if (dstalpha > 0x80)
|
||||
return src;
|
||||
uint srcr = (src >> 16) & 0xFF;
|
||||
uint srcg = (src >> 8) & 0xFF;
|
||||
uint srcb = (src >> 0) & 0xFF;
|
||||
|
|
|
@ -63,10 +63,20 @@ class GLDrawBuf : DrawBuf {
|
|||
/// draw source buffer rectangle contents to destination buffer
|
||||
override void drawFragment(int x, int y, DrawBuf src, Rect srcrect) {
|
||||
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
|
||||
override void drawRescaled(Rect dstrect, DrawBuf src, Rect srcrect) {
|
||||
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() {
|
||||
}
|
||||
|
@ -80,10 +90,7 @@ public:
|
|||
@property GLImageCachePage page() { return _page; }
|
||||
uint _objectId;
|
||||
// image size
|
||||
int _dx;
|
||||
int _dy;
|
||||
int _x0;
|
||||
int _y0;
|
||||
Rect _rc;
|
||||
bool _deleted;
|
||||
this(GLImageCachePage page, uint objectId) { _page = page; _objectId = objectId; }
|
||||
};
|
||||
|
@ -197,10 +204,10 @@ public:
|
|||
_map.clear();
|
||||
}
|
||||
/// 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) {
|
||||
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
|
||||
|
@ -314,13 +321,10 @@ public:
|
|||
}
|
||||
}
|
||||
void invertAlpha(GLImageCacheItem item) {
|
||||
int x0 = item._x0;
|
||||
int y0 = item._y0;
|
||||
int x1 = x0 + item._dx;
|
||||
int y1 = y0 + item._dy;
|
||||
for (int y = y0; y < y1; y++) {
|
||||
Rect rc = item._rc;
|
||||
for (int y = rc.top; y < rc.bottom; 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];
|
||||
cl ^= 0xFF000000;
|
||||
uint r = (cl & 0x00FF0000) >> 16;
|
||||
|
@ -335,30 +339,27 @@ public:
|
|||
return null;
|
||||
|
||||
// next line if necessary
|
||||
if (_x + width > _tdx) {
|
||||
if (_x + width + 2 > _tdx) {
|
||||
// move to next line
|
||||
_currentLine = _nextLine;
|
||||
_x = 0;
|
||||
}
|
||||
// check if no room left for glyph height
|
||||
if (_currentLine + height > _tdy) {
|
||||
if (_currentLine + height + 2 > _tdy) {
|
||||
_closed = true;
|
||||
return null;
|
||||
}
|
||||
cacheItem._dx = width;
|
||||
cacheItem._dy = height;
|
||||
cacheItem._x0 = _x;
|
||||
cacheItem._y0 = _currentLine;
|
||||
cacheItem._rc = Rect(_x + 1, _currentLine + 1, _x + width + 1, _currentLine + height + 1);
|
||||
if (height && width) {
|
||||
if (_nextLine < _currentLine + height)
|
||||
_nextLine = _currentLine + height;
|
||||
if (_nextLine < _currentLine + height + 2)
|
||||
_nextLine = _currentLine + height + 2;
|
||||
if (!_drawbuf) {
|
||||
_drawbuf = new ColorDrawBuf(_tdx, _tdy);
|
||||
//_drawbuf.SetBackgroundColor(0x000000);
|
||||
//_drawbuf.SetTextColor(0xFFFFFF);
|
||||
_drawbuf.fill(0xFF000000);
|
||||
}
|
||||
_x += width;
|
||||
_x += width + 1;
|
||||
_needUpdateTexture = true;
|
||||
}
|
||||
_itemCount++;
|
||||
|
@ -373,12 +374,12 @@ public:
|
|||
if (cacheItem is null)
|
||||
return null;
|
||||
buf.onDestroyCallback = &onObjectDestroyedCallback;
|
||||
_drawbuf.drawImage(cacheItem._x0, cacheItem._y0, buf);
|
||||
_drawbuf.drawImage(cacheItem._rc.left, cacheItem._rc.top, buf);
|
||||
invertAlpha(cacheItem);
|
||||
_needUpdateTexture = true;
|
||||
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);
|
||||
if (_needUpdateTexture)
|
||||
updateTexture();
|
||||
|
@ -388,15 +389,14 @@ public:
|
|||
return;
|
||||
}
|
||||
//rotationAngle = 0;
|
||||
int rx = x + dx / 2;
|
||||
int ry = (y + dy / 2);
|
||||
int rx = dstrc.middlex;
|
||||
int ry = dstrc.middley;
|
||||
if (rotationAngle) {
|
||||
//rotationAngle = 0;
|
||||
//setRotation(rx, ry, rotationAngle);
|
||||
}
|
||||
|
||||
Rect srcrc = Rect(item._x0 + srcx, item._y0 + srcy, item._x0 + srcx+srcdx, item._y0 + srcy+srcdy);
|
||||
Rect dstrc = Rect(x, y, x + dx, y+dy);
|
||||
// convert coordinates to cached texture
|
||||
srcrc.offset(item._rc.left, item._rc.top);
|
||||
if (clip) {
|
||||
int srcw = srcrc.width();
|
||||
int srch = srcrc.height();
|
||||
|
@ -416,7 +416,7 @@ public:
|
|||
dstrc.bottom -= clip.bottom;
|
||||
}
|
||||
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);
|
||||
|
||||
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,y0,Z_2D];
|
||||
if (_solidFillProgram !is null) {
|
||||
Log.d("solid fill: vertices ", vertices, " colors ", colors);
|
||||
//Log.d("solid fill: vertices ", vertices, " colors ", colors);
|
||||
_solidFillProgram.execute(vertices, colors);
|
||||
} else
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ __gshared DrawableCache _drawableCache;
|
|||
/// drawable cache singleton
|
||||
@property DrawableCache drawableCache() { return _drawableCache; }
|
||||
|
||||
static this() {
|
||||
shared static this() {
|
||||
_imageCache = new ImageCache();
|
||||
_drawableCache = new DrawableCache();
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import dlangui.platforms.common.platform;
|
|||
import dlangui.platforms.windows.win32fonts;
|
||||
import dlangui.platforms.windows.win32drawbuf;
|
||||
import dlangui.graphics.drawbuf;
|
||||
import dlangui.graphics.images;
|
||||
import dlangui.graphics.fonts;
|
||||
import dlangui.graphics.glsupport;
|
||||
import dlangui.core.logger;
|
||||
|
@ -131,7 +132,7 @@ class Win32Window : Window {
|
|||
_caption = windowCaption;
|
||||
_hwnd = CreateWindow(toUTF16z(WIN_CLASS_NAME), // window class name
|
||||
toUTF16z(windowCaption), // window caption
|
||||
WS_OVERLAPPEDWINDOW, // window style
|
||||
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, // window style
|
||||
CW_USEDEFAULT, // initial x position
|
||||
CW_USEDEFAULT, // initial y position
|
||||
CW_USEDEFAULT, // initial x size
|
||||
|
@ -226,6 +227,12 @@ class Win32Window : Window {
|
|||
void onPaint() {
|
||||
Log.d("onPaint()");
|
||||
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.wgl;
|
||||
import dlangui.graphics.gldrawbuf;
|
||||
|
@ -245,9 +252,22 @@ class Win32Window : Window {
|
|||
buf.fillRect(Rect(100, 100, 200, 200), 0x704020);
|
||||
buf.fillRect(Rect(40, 70, 100, 120), 0x000000);
|
||||
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();
|
||||
//Log.d("onPaint() end drawing opengl");
|
||||
SwapBuffers(hdc);
|
||||
wglMakeCurrent(hdc, null);
|
||||
} else {
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(_hwnd, &ps);
|
||||
|
@ -268,14 +288,14 @@ class Win32Platform : Platform {
|
|||
//MSG msg;
|
||||
WNDCLASS wndclass;
|
||||
|
||||
wndclass.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
||||
wndclass.lpfnWndProc = &WndProc;
|
||||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = 0;
|
||||
wndclass.hInstance = _hInstance;
|
||||
wndclass.hIcon = LoadIcon(null, IDI_APPLICATION);
|
||||
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.lpszClassName = toUTF16z(WIN_CLASS_NAME);
|
||||
|
||||
|
|
Loading…
Reference in New Issue