mirror of https://github.com/buggins/dlangui.git
fix #168 - share OpenGL context between windows under Win32/OpenGL
This commit is contained in:
parent
3c5573aba0
commit
f9780e268e
|
@ -102,7 +102,10 @@ extern (C) int UIAppMain(string[] args) {
|
|||
cam.translation = vec3(0, 0, -5);
|
||||
scene.activeCamera = cam;
|
||||
mat4 camMatrix = scene.viewProjectionMatrix;
|
||||
MeshPart part = new MeshPart();
|
||||
VertexFormat vfmt = VertexFormat(VertexElementType.POSITION, VertexElementType.COLOR, VertexElementType.TEXCOORD0);
|
||||
Mesh2 mesh = new Mesh2(vfmt);
|
||||
mesh.addVertex([1,2,3, 1,1,1,1, 0,0]);
|
||||
//MeshPart part = new MeshPart();
|
||||
|
||||
// show window
|
||||
window.show();
|
||||
|
|
|
@ -86,7 +86,11 @@ struct FileFilterEntry {
|
|||
}
|
||||
|
||||
version (Windows) {
|
||||
__gshared bool SHOW_FILE_DIALOG_IN_POPUP = true;
|
||||
static if (BACKEND_SDL) {
|
||||
__gshared bool SHOW_FILE_DIALOG_IN_POPUP = false;
|
||||
} else {
|
||||
__gshared bool SHOW_FILE_DIALOG_IN_POPUP = false;
|
||||
}
|
||||
} else {
|
||||
__gshared bool SHOW_FILE_DIALOG_IN_POPUP = false;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,21 @@ struct VertexElement {
|
|||
private ubyte _size;
|
||||
@property VertexElementType type() const { return _type; }
|
||||
@property ubyte size() const { return _size; }
|
||||
this(VertexElementType type, ubyte size) {
|
||||
this(VertexElementType type, ubyte size = 0) {
|
||||
if (size == 0) {
|
||||
switch(type) with (VertexElementType) {
|
||||
case POSITION:
|
||||
case NORMAL:
|
||||
size = 3;
|
||||
break;
|
||||
case COLOR:
|
||||
size = 4;
|
||||
break;
|
||||
default:
|
||||
size = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_type = type;
|
||||
_size = size;
|
||||
}
|
||||
|
@ -38,6 +52,14 @@ struct VertexFormat {
|
|||
foreach(elem; elems)
|
||||
_vertexSize += elem.size * float.sizeof;
|
||||
}
|
||||
/// init from vertex element types, using default sizes for types
|
||||
this(inout VertexElementType[] types...) {
|
||||
foreach(t; types) {
|
||||
VertexElement elem = VertexElement(t);
|
||||
_elements ~= elem;
|
||||
_vertexSize += elem.size;
|
||||
}
|
||||
}
|
||||
/// get number of elements
|
||||
@property int length() const {
|
||||
return cast(int)_elements.length;
|
||||
|
@ -46,10 +68,24 @@ struct VertexFormat {
|
|||
VertexElement opIndex(int index) const {
|
||||
return _elements[index];
|
||||
}
|
||||
/// returns vertex size in bytes for format
|
||||
/// returns vertex size in bytes
|
||||
@property int vertexSize() const {
|
||||
return _vertexSize * float.sizeof;
|
||||
}
|
||||
/// returns vertex size in floats
|
||||
@property int vertexFloats() const {
|
||||
return _vertexSize;
|
||||
}
|
||||
/// returns true if it's valid vertex format
|
||||
@property bool isValid() const {
|
||||
if (!_vertexSize)
|
||||
return false;
|
||||
foreach(elem; _elements) {
|
||||
if (elem.type == VertexElementType.POSITION)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/// compare
|
||||
bool opEquals(immutable ref VertexFormat fmt) {
|
||||
if (_vertexSize != fmt._vertexSize)
|
||||
|
@ -61,6 +97,46 @@ struct VertexFormat {
|
|||
}
|
||||
}
|
||||
|
||||
class Mesh2 {
|
||||
protected VertexFormat _vertexFormat;
|
||||
protected int _vertexCount;
|
||||
protected float[] _vertexData;
|
||||
|
||||
@property ref const(VertexFormat) vertexFormat() const { return _vertexFormat; }
|
||||
@property void vertexFormat(VertexFormat format) {
|
||||
assert(_vertexCount == 0);
|
||||
_vertexFormat = format;
|
||||
}
|
||||
@property int vertexCount() const { return _vertexCount; }
|
||||
|
||||
/// adds single vertex
|
||||
int addVertex(float[] data) {
|
||||
assert(_vertexFormat.isValid && data.length == _vertexFormat.vertexFloats);
|
||||
int res = _vertexCount;
|
||||
_vertexData.assumeSafeAppend();
|
||||
_vertexData ~= data;
|
||||
_vertexCount++;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// adds one or more vertexes
|
||||
int addVertexes(float[] data) {
|
||||
assert(_vertexFormat.isValid && (data.length > 0) && (data.length % _vertexFormat.vertexFloats == 0));
|
||||
int res = _vertexCount;
|
||||
_vertexData.assumeSafeAppend();
|
||||
_vertexData ~= data;
|
||||
_vertexCount += cast(int)(data.length / _vertexFormat.vertexFloats);
|
||||
return res;
|
||||
}
|
||||
|
||||
this() {
|
||||
}
|
||||
|
||||
this(VertexFormat vertexFormat) {
|
||||
_vertexFormat = vertexFormat;
|
||||
}
|
||||
}
|
||||
|
||||
class Mesh {
|
||||
protected MeshPart[] _parts;
|
||||
protected int _vertexCount;
|
||||
|
|
|
@ -156,6 +156,69 @@ static if (ENABLE_OPENGL) {
|
|||
|
||||
const uint CUSTOM_MESSAGE_ID = WM_USER + 1;
|
||||
|
||||
static if (ENABLE_OPENGL) {
|
||||
|
||||
/// Shared opengl context helper
|
||||
struct SharedGLContext {
|
||||
import derelict.opengl3.wgl;
|
||||
|
||||
HGLRC _hGLRC; // opengl context
|
||||
HPALETTE _hPalette;
|
||||
bool _error;
|
||||
/// Init OpenGL context, if not yet initialized
|
||||
bool init(HDC hDC) {
|
||||
if (_hGLRC)
|
||||
return true;
|
||||
if (_error)
|
||||
return false;
|
||||
if (setupPixelFormat(hDC)) {
|
||||
_hPalette = setupPalette(hDC);
|
||||
_hGLRC = wglCreateContext(hDC);
|
||||
if (_hGLRC) {
|
||||
bind(hDC);
|
||||
bool initialized = initGLSupport(false);
|
||||
unbind(hDC);
|
||||
if (!initialized) {
|
||||
uninit();
|
||||
Log.e("Failed to init OpenGL shaders");
|
||||
_error = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
_error = true;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Log.e("Cannot setup pixel format");
|
||||
_error = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void uninit() {
|
||||
if (_hGLRC) {
|
||||
wglDeleteContext(_hGLRC);
|
||||
_hGLRC = null;
|
||||
}
|
||||
}
|
||||
/// make this context current for DC
|
||||
void bind(HDC hDC) {
|
||||
wglMakeCurrent(hDC, _hGLRC);
|
||||
}
|
||||
/// make null context current for DC
|
||||
void unbind(HDC hDC) {
|
||||
wglMakeCurrent(hDC, null);
|
||||
}
|
||||
void swapBuffers(HDC hDC) {
|
||||
SwapBuffers(hDC);
|
||||
}
|
||||
}
|
||||
|
||||
/// OpenGL context to share between windows
|
||||
__gshared SharedGLContext sharedGLContext;
|
||||
}
|
||||
|
||||
|
||||
class Win32Window : Window {
|
||||
Win32Platform _platform;
|
||||
|
||||
|
@ -200,25 +263,11 @@ class Win32Window : Window {
|
|||
_hInstance, // program instance handle
|
||||
cast(void*)this); // creation parameters
|
||||
static if (ENABLE_OPENGL) {
|
||||
import derelict.opengl3.wgl;
|
||||
|
||||
/* initialize OpenGL rendering */
|
||||
HDC hDC = GetDC(_hwnd);
|
||||
|
||||
if (openglEnabled || !_glSupport) {
|
||||
if (setupPixelFormat(hDC)) {
|
||||
_hPalette = setupPalette(hDC);
|
||||
_hGLRC = wglCreateContext(hDC);
|
||||
if (_hGLRC) {
|
||||
wglMakeCurrent(hDC, _hGLRC);
|
||||
useOpengl = initGLSupport(false);
|
||||
wglMakeCurrent(hDC, null);
|
||||
}
|
||||
} else {
|
||||
Log.e("Pixelformat failed");
|
||||
// disable GL
|
||||
useOpengl = false;
|
||||
}
|
||||
useOpengl = sharedGLContext.init(hDC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -239,7 +288,7 @@ class Win32Window : Window {
|
|||
//HDC hdc = BeginPaint(_hwnd, &ps);
|
||||
//scope(exit) EndPaint(_hwnd, &ps);
|
||||
HDC hdc = GetDC(_hwnd);
|
||||
wglMakeCurrent(hdc, _hGLRC);
|
||||
sharedGLContext.bind(hdc);
|
||||
//_glSupport = _gl;
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glViewport(0, 0, _dx, _dy);
|
||||
|
@ -267,14 +316,15 @@ class Win32Window : Window {
|
|||
onDraw(buf);
|
||||
}
|
||||
buf.afterDrawing();
|
||||
SwapBuffers(hdc);
|
||||
wglMakeCurrent(hdc, null);
|
||||
sharedGLContext.swapBuffers(hdc);
|
||||
sharedGLContext.unbind(hdc);
|
||||
destroy(buf);
|
||||
}
|
||||
}
|
||||
|
||||
~this() {
|
||||
debug Log.d("Window destructor");
|
||||
/*
|
||||
static if (ENABLE_OPENGL) {
|
||||
import derelict.opengl3.wgl;
|
||||
if (_hGLRC) {
|
||||
|
@ -287,6 +337,7 @@ class Win32Window : Window {
|
|||
_hGLRC = null;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (_hwnd)
|
||||
DestroyWindow(_hwnd);
|
||||
_hwnd = null;
|
||||
|
|
Loading…
Reference in New Issue