Custom OpenGL drawable

This commit is contained in:
Vadim Lopatin 2015-12-18 16:14:40 +03:00
parent 73314752e2
commit 568a124274
5 changed files with 98 additions and 2 deletions

View File

@ -894,6 +894,11 @@ void main()
}; };
tabs.addTab(canvas, "TAB_CANVAS"c); tabs.addTab(canvas, "TAB_CANVAS"c);
static if (ENABLE_OPENGL) {
//
tabs.addTab(new MyOpenglWidget(), "OpenGL"d);
}
//========================================================================== //==========================================================================
contentLayout.addChild(tabs); contentLayout.addChild(tabs);
@ -914,3 +919,19 @@ void main()
return Platform.instance.enterMessageLoop(); return Platform.instance.enterMessageLoop();
} }
static if (ENABLE_OPENGL) {
class MyOpenglWidget : Widget {
this() {
super("OpenGLView");
layoutWidth = FILL_PARENT;
layoutHeight = FILL_PARENT;
backgroundDrawable = DrawableRef(new OpenGLDrawable(&doDraw));
}
private void doDraw(DrawBuf buf, Rect rc) {
// do some drawing
// TODO
}
}
}

View File

@ -39,6 +39,9 @@ static if (ENABLE_OPENGL) {
private __gshared uint drawBufIdGenerator = 0; private __gshared uint drawBufIdGenerator = 0;
} }
/// Custom draw delegate for OpenGL direct drawing
alias OpenGLDrawableDelegate = void delegate(DrawBuf buf, Rect rc);
/// drawing buffer - image container which allows to perform some drawing operations /// drawing buffer - image container which allows to perform some drawing operations
class DrawBuf : RefCountedObject { class DrawBuf : RefCountedObject {
protected Rect _clipRect; protected Rect _clipRect;
@ -384,6 +387,12 @@ class DrawBuf : RefCountedObject {
return this; return this;
} }
/// draw custom OpenGL scene
void drawCustomOpenGLScene(Rect rc, OpenGLDrawableDelegate handler) {
// override it for OpenGL draw buffer
Log.w("drawCustomOpenGLScene is called for non-OpenGL DrawBuf");
}
void clear() { void clear() {
resetClipping(); resetClipping();
} }

View File

@ -89,6 +89,11 @@ class GLDrawBuf : DrawBuf, GLConfigCallback {
resetClipping(); resetClipping();
} }
/// draw custom OpenGL scene
override void drawCustomOpenGLScene(Rect rc, OpenGLDrawableDelegate handler) {
_scene.add(new CustomDrawnSceneItem(this, rc, handler));
}
/// fill the whole buffer with solid color (no clipping applied) /// fill the whole buffer with solid color (no clipping applied)
override void fill(uint color) { override void fill(uint color) {
if (hasClipping) { if (hasClipping) {
@ -905,3 +910,25 @@ public:
~this() { ~this() {
} }
} }
private class CustomDrawnSceneItem : SceneItem {
private:
DrawBuf _buf;
Rect _rc;
OpenGLDrawableDelegate _handler;
public:
this(DrawBuf buf, Rect rc, OpenGLDrawableDelegate handler) {
_buf = buf;
_rc = rc;
_handler = handler;
}
override void draw() {
if (_handler) {
import derelict.opengl3.gl3;
import derelict.opengl3.gl;
glViewport(_rc.left, _rc.top, _rc.right, _rc.bottom);
_handler(_buf, _rc);
glSupport.setOrthoProjection(Rect(0, 0, _buf.width, _buf.height));
}
}
}

View File

@ -221,6 +221,7 @@ immutable(ubyte[]) loadResourceBytes(string filename) {
} }
} }
/// Base class for all drawables
class Drawable : RefCountedObject { class Drawable : RefCountedObject {
debug static __gshared int _instanceCount; debug static __gshared int _instanceCount;
debug @property static int instanceCount() { return _instanceCount; } debug @property static int instanceCount() { return _instanceCount; }
@ -239,6 +240,37 @@ class Drawable : RefCountedObject {
@property Rect padding() { return Rect(0,0,0,0); } @property Rect padding() { return Rect(0,0,0,0); }
} }
/// Custom drawing inside openGL
class OpenGLDrawable : Drawable {
private OpenGLDrawableDelegate _drawHandler;
@property OpenGLDrawableDelegate drawHandler() { return _drawHandler; }
@property OpenGLDrawable drawHandler(OpenGLDrawableDelegate handler) { _drawHandler = handler; return this; }
this(OpenGLDrawableDelegate drawHandler = null) {
_drawHandler = drawHandler;
}
void onDraw(DrawBuf buf, Rect rc) {
// either override this method or assign draw handler
if (_drawHandler) {
_drawHandler(buf, rc);
}
}
override void drawTo(DrawBuf buf, Rect rc, uint state = 0, int tilex0 = 0, int tiley0 = 0) {
buf.drawCustomOpenGLScene(rc, &onDraw);
}
override @property int width() {
return 20; // dummy size
}
override @property int height() {
return 20; // dummy size
}
}
class EmptyDrawable : Drawable { class EmptyDrawable : Drawable {
override void drawTo(DrawBuf buf, Rect rc, uint state = 0, int tilex0 = 0, int tiley0 = 0) { override void drawTo(DrawBuf buf, Rect rc, uint state = 0, int tilex0 = 0, int tiley0 = 0) {
} }

View File

@ -402,9 +402,16 @@ class Widget {
return style.focusRectColors; return style.focusRectColors;
} }
DrawableRef _backgroundDrawable;
/// background drawable /// background drawable
@property DrawableRef backgroundDrawable() const { @property DrawableRef backgroundDrawable() const {
if (_backgroundDrawable.isNull)
return stateStyle.backgroundDrawable; return stateStyle.backgroundDrawable;
return (cast(Widget)this)._backgroundDrawable;
}
/// background drawable
@property void backgroundDrawable(DrawableRef drawable) {
_backgroundDrawable = drawable;
} }
/// widget drawing alpha value (0=opaque .. 255=transparent) /// widget drawing alpha value (0=opaque .. 255=transparent)