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);
static if (ENABLE_OPENGL) {
//
tabs.addTab(new MyOpenglWidget(), "OpenGL"d);
}
//==========================================================================
contentLayout.addChild(tabs);
@ -914,3 +919,19 @@ void main()
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;
}
/// 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
class DrawBuf : RefCountedObject {
protected Rect _clipRect;
@ -384,6 +387,12 @@ class DrawBuf : RefCountedObject {
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() {
resetClipping();
}

View File

@ -89,6 +89,11 @@ class GLDrawBuf : DrawBuf, GLConfigCallback {
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)
override void fill(uint color) {
if (hasClipping) {
@ -905,3 +910,25 @@ public:
~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 {
debug static __gshared int _instanceCount;
debug @property static int instanceCount() { return _instanceCount; }
@ -239,6 +240,37 @@ class Drawable : RefCountedObject {
@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 {
override void drawTo(DrawBuf buf, Rect rc, uint state = 0, int tilex0 = 0, int tiley0 = 0) {
}

View File

@ -402,11 +402,18 @@ class Widget {
return style.focusRectColors;
}
DrawableRef _backgroundDrawable;
/// background drawable
@property DrawableRef backgroundDrawable() const {
return stateStyle.backgroundDrawable;
if (_backgroundDrawable.isNull)
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)
@property uint alpha() const { return stateStyle.alpha; }
/// set widget drawing alpha value (0=opaque .. 255=transparent)