put OpenGL support under conditional compilation: version(USE_OPENGL)

This commit is contained in:
Vadim Lopatin 2014-03-12 10:29:06 +04:00
parent 0cff3908fe
commit 3113577041
8 changed files with 213 additions and 166 deletions

View File

@ -59,8 +59,10 @@ struct Rect {
align(1)
struct Glyph
{
version (USE_OPENGL) {
///< 0: unique id of glyph (for drawing in hardware accelerated scenes)
uint id;
}
///< 4: width of glyph black box
ubyte blackBoxX;
///< 5: height of glyph black box

View File

@ -46,21 +46,27 @@ struct NinePatch {
Rect padding;
}
version (USE_OPENGL) {
/// non thread safe
private __gshared uint drawBufIdGenerator = 0;
}
/// drawing buffer - image container which allows to perform some drawing operations
class DrawBuf : RefCountedObject {
protected uint _id;
protected Rect _clipRect;
protected NinePatch * _ninePatch;
@property uint id() {
return _id;
version (USE_OPENGL) {
protected uint _id;
/// unique ID of drawbug instance, for using with hardware accelerated rendering for caching
@property uint id() { return _id; }
}
this() {
version (USE_OPENGL) {
_id = drawBufIdGenerator++;
}
}
protected void function(uint) _onDestroyCallback;
@property void onDestroyCallback(void function(uint) callback) { _onDestroyCallback = callback; }
@property void function(uint) onDestroyCallback() { return _onDestroyCallback; }

View File

@ -18,6 +18,7 @@ enum FontWeight : int {
Bold = 800
}
version (USE_OPENGL) {
private __gshared void function(uint id) _glyphDestroyCallback;
/// get glyph destroy callback (to cleanup OpenGL caches)
@property void function(uint id) glyphDestroyCallback() { return _glyphDestroyCallback; }
@ -26,6 +27,7 @@ private __gshared void function(uint id) _glyphDestroyCallback;
private __gshared uint _nextGlyphId;
uint nextGlyphId() { return _nextGlyphId++; }
}
struct GlyphCache
{
@ -66,10 +68,12 @@ struct GlyphCache
void cleanup() {
uint dst = 0;
// notify about destroyed glyphs
version (USE_OPENGL) {
if (_glyphDestroyCallback !is null)
for (uint src = 0; src < _len; src++)
if (_data[src].lastUsage == 0)
_glyphDestroyCallback(_data[src].id);
}
for (uint src = 0; src < _len; src++) {
if (_data[src].lastUsage != 0) {
_data[src].lastUsage = 0;
@ -83,9 +87,11 @@ struct GlyphCache
// removes all entries
void clear() {
version (USE_OPENGL) {
if (_glyphDestroyCallback !is null)
for (uint src = 0; src < _len; src++)
_glyphDestroyCallback(_data[src].id);
}
_data = null;
_len = 0;
}

View File

@ -1,5 +1,7 @@
module dlangui.graphics.gldrawbuf;
version (USE_OPENGL) {
import dlangui.graphics.drawbuf;
import dlangui.core.logger;
private import dlangui.graphics.glsupport;
@ -819,7 +821,7 @@ public:
}
~this() {
}
};
}
}

View File

@ -1,5 +1,7 @@
module dlangui.graphics.glsupport;
version(USE_OPENGL) {
import dlangui.core.logger;
private import derelict.opengl3.gl3;
//private import gl3n.linalg;
@ -657,3 +659,6 @@ void setRotation(int x, int y, int rotationAngle) {
matrix2.copyDataTo(m);
*/
}
}

View File

@ -51,6 +51,7 @@ public class Platform {
abstract public int enterMessageLoop();
}
version (USE_OPENGL) {
private __gshared bool _OPENGL_ENABLED = false;
/// check if hardware acceleration is enabled
@property bool openglEnabled() { return _OPENGL_ENABLED; }
@ -59,6 +60,7 @@ void setOpenglEnabled() {
_OPENGL_ENABLED = true;
glyphDestroyCallback = &onGlyphDestroyedCallback;
}
}
version (Windows) {
immutable char PATH_DELIMITER = '\\';

View File

@ -131,7 +131,9 @@ class Win32Font : Font {
return null;
Glyph g;
version (USE_OPENGL) {
g.id = nextGlyphId();
}
g.blackBoxX = cast(ubyte)metrics.gmBlackBoxX;
g.blackBoxY = cast(ubyte)metrics.gmBlackBoxY;
g.originX = cast(byte)metrics.gmptGlyphOrigin.x;

View File

@ -18,7 +18,6 @@ import dlangui.graphics.images;
import dlangui.graphics.fonts;
import dlangui.graphics.glsupport;
import dlangui.core.logger;
//import derelict.opengl3.wgl;
pragma(lib, "gdi32.lib");
pragma(lib, "user32.lib");
@ -31,6 +30,7 @@ immutable WIN_CLASS_NAME = "DLANGUI_APP";
__gshared HINSTANCE _hInstance;
__gshared int _cmdShow;
version (USE_OPENGL) {
bool setupPixelFormat(HDC hDC)
{
PIXELFORMATDESCRIPTOR pfd = {
@ -120,6 +120,7 @@ HPALETTE setupPalette(HDC hDC)
}
private __gshared bool DERELICT_GL3_RELOADED = false;
}
class Win32Window : Window {
private HWND _hwnd;
@ -142,6 +143,9 @@ class Win32Window : Window {
null, // window menu handle
_hInstance, // program instance handle
cast(void*)this); // creation parameters
version (USE_OPENGL) {
/* initialize OpenGL rendering */
HDC hDC = GetDC(_hwnd);
@ -184,8 +188,10 @@ class Win32Window : Window {
}
}
}
}
~this() {
Log.d("Window destructor");
version (USE_OPENGL) {
import derelict.opengl3.wgl;
if (_hGLRC) {
uninitShaders();
@ -193,6 +199,7 @@ class Win32Window : Window {
wglDeleteContext(_hGLRC);
_hGLRC = null;
}
}
if (_hwnd)
DestroyWindow(_hwnd);
_hwnd = null;
@ -225,9 +232,20 @@ class Win32Window : Window {
void onDestroy() {
Log.d("Window onDestroy");
}
void onPaint() {
Log.d("onPaint()");
if (useOpengl && _hGLRC) {
private void paintUsingGDI() {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(_hwnd, &ps);
scope(exit) EndPaint(_hwnd, &ps);
Win32ColorDrawBuf buf = getDrawBuf();
buf.fill(0x808080);
onDraw(buf);
buf.drawTo(hdc, 0, 0);
}
version (USE_OPENGL) {
private void paintUsingOpenGL() {
// hack to stop infinite WM_PAINT loop
PAINTSTRUCT ps;
HDC hdc2 = BeginPaint(_hwnd, &ps);
@ -268,15 +286,19 @@ class Win32Window : Window {
//Log.d("onPaint() end drawing opengl");
SwapBuffers(hdc);
wglMakeCurrent(hdc, null);
} else {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(_hwnd, &ps);
scope(exit) EndPaint(_hwnd, &ps);
}
}
Win32ColorDrawBuf buf = getDrawBuf();
buf.fill(0x808080);
onDraw(buf);
buf.drawTo(hdc, 0, 0);
void onPaint() {
Log.d("onPaint()");
version (USE_OPENGL) {
if (useOpengl && _hGLRC) {
paintUsingOpenGL();
} else {
paintUsingGDI();
}
} else {
paintUsingGDI();
}
}
}
@ -391,7 +413,7 @@ int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
Win32FontManager fontMan = new Win32FontManager();
FontManager.instance = fontMan;
{
version (USE_OPENGL) {
import derelict.opengl3.gl3;
DerelictGL3.load();