mirror of https://github.com/buggins/dlangui.git
OpenGL shaders
This commit is contained in:
parent
e0674a98b6
commit
a5ac694004
|
@ -10,20 +10,6 @@ Project("{002A2DE9-8BB6-484D-9802-7E4AD4084715}") = "example1", "examples\exampl
|
|||
EndProject
|
||||
Project("{002A2DE9-8BB6-484D-9802-7E4AD4084715}") = "test", "examples\test\test.visualdproj", "{BE84DF39-64E6-449D-89E0-8E92404003CB}"
|
||||
EndProject
|
||||
Project("{002A2DE9-8BB6-484D-9802-7E4AD4084715}") = "DerelictUtil", "3rdparty\DerelictUtil\DerelictUtil.visualdproj", "{B83A0CDA-F51B-46C0-A23C-65F5CA2994F0}"
|
||||
EndProject
|
||||
Project("{002A2DE9-8BB6-484D-9802-7E4AD4084715}") = "DerelictGL3", "3rdparty\DerelictGL3\DerelictGL3.visualdproj", "{2636C1E1-FF8E-4424-B3F9-764DA9A4B556}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B83A0CDA-F51B-46C0-A23C-65F5CA2994F0} = {B83A0CDA-F51B-46C0-A23C-65F5CA2994F0}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{002A2DE9-8BB6-484D-9802-7E4AD4084715}") = "DerelictFT", "3rdparty\DerelictFT\DerelictFT.visualdproj", "{6E4F189A-D7B0-4ABD-8942-20E10C309D01}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B83A0CDA-F51B-46C0-A23C-65F5CA2994F0} = {B83A0CDA-F51B-46C0-A23C-65F5CA2994F0}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{002A2DE9-8BB6-484D-9802-7E4AD4084715}") = "gl3n", "3rdparty\gl3n\gl3n.visualdproj", "{6EDE8E99-6487-4505-94E9-C717112526A4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
@ -42,22 +28,6 @@ Global
|
|||
{BE84DF39-64E6-449D-89E0-8E92404003CB}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BE84DF39-64E6-449D-89E0-8E92404003CB}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BE84DF39-64E6-449D-89E0-8E92404003CB}.Release|Win32.Build.0 = Release|Win32
|
||||
{B83A0CDA-F51B-46C0-A23C-65F5CA2994F0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B83A0CDA-F51B-46C0-A23C-65F5CA2994F0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B83A0CDA-F51B-46C0-A23C-65F5CA2994F0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B83A0CDA-F51B-46C0-A23C-65F5CA2994F0}.Release|Win32.Build.0 = Release|Win32
|
||||
{2636C1E1-FF8E-4424-B3F9-764DA9A4B556}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{2636C1E1-FF8E-4424-B3F9-764DA9A4B556}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{2636C1E1-FF8E-4424-B3F9-764DA9A4B556}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{2636C1E1-FF8E-4424-B3F9-764DA9A4B556}.Release|Win32.Build.0 = Release|Win32
|
||||
{6E4F189A-D7B0-4ABD-8942-20E10C309D01}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6E4F189A-D7B0-4ABD-8942-20E10C309D01}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6E4F189A-D7B0-4ABD-8942-20E10C309D01}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6E4F189A-D7B0-4ABD-8942-20E10C309D01}.Release|Win32.Build.0 = Release|Win32
|
||||
{6EDE8E99-6487-4505-94E9-C717112526A4}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6EDE8E99-6487-4505-94E9-C717112526A4}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6EDE8E99-6487-4505-94E9-C717112526A4}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6EDE8E99-6487-4505-94E9-C717112526A4}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<compiler>0</compiler>
|
||||
<otherDMD>0</otherDMD>
|
||||
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
|
||||
<imppath>3rdparty 3rdparty/libpng/source</imppath>
|
||||
<imppath>3rdparty 3rdparty/libpng/source ../DerelictGL3/source ../DerelictUtil/source</imppath>
|
||||
<fileImppath />
|
||||
<outdir>$(ConfigurationName)</outdir>
|
||||
<objdir>$(OutDir)</objdir>
|
||||
|
@ -141,7 +141,7 @@
|
|||
<compiler>0</compiler>
|
||||
<otherDMD>0</otherDMD>
|
||||
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
|
||||
<imppath>3rdparty 3rdparty/libpng/source</imppath>
|
||||
<imppath>3rdparty 3rdparty/libpng/source ../DerelictGL3/source</imppath>
|
||||
<fileImppath />
|
||||
<outdir>$(ConfigurationName)</outdir>
|
||||
<objdir>$(OutDir)</objdir>
|
||||
|
@ -190,6 +190,42 @@
|
|||
</Config>
|
||||
<Folder name="dlangui">
|
||||
<Folder name="3rdparty">
|
||||
<Folder name="DerelictUtil">
|
||||
<File path="..\DerelictUtil\source\derelict\util\exception.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\loader.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\sharedlib.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\system.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\wintypes.d" />
|
||||
<File path="..\DerelictUtil\source\derelict\util\xtypes.d" />
|
||||
</Folder>
|
||||
<Folder name="DerelictGL3">
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\arb.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\cgl.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\constants.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\deprecatedConstants.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\deprecatedFunctions.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\ext.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\functions.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\gl.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\gl3.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\glx.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\glxext.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\internal.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\types.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\wgl.d" />
|
||||
<File path="..\DerelictGL3\source\derelict\opengl3\wglext.d" />
|
||||
</Folder>
|
||||
<Folder name="gl3n">
|
||||
<File path="..\gl3n\gl3n\aabb.d" />
|
||||
<File path="..\gl3n\gl3n\frustum.d" />
|
||||
<File path="..\gl3n\gl3n\ext\hsv.d" />
|
||||
<File path="..\gl3n\gl3n\interpolate.d" />
|
||||
<File path="..\gl3n\gl3n\linalg.d" />
|
||||
<File path="..\gl3n\gl3n\math.d" />
|
||||
<File path="..\gl3n\gl3n\ext\matrixstack.d" />
|
||||
<File path="..\gl3n\gl3n\plane.d" />
|
||||
<File path="..\gl3n\gl3n\util.d" />
|
||||
</Folder>
|
||||
<Folder name="libpng">
|
||||
<File path="3rdparty\libpng\source\libpng\png.d" />
|
||||
<File path="3rdparty\libpng\source\libpng\pngconf.d" />
|
||||
|
@ -258,6 +294,7 @@
|
|||
<Folder name="graphics">
|
||||
<File path="src\dlangui\graphics\drawbuf.d" />
|
||||
<File path="src\dlangui\graphics\fonts.d" />
|
||||
<File path="src\dlangui\graphics\glsupport.d" />
|
||||
<File path="src\dlangui\graphics\images.d" />
|
||||
</Folder>
|
||||
<Folder name="platforms">
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<compiler>0</compiler>
|
||||
<otherDMD>0</otherDMD>
|
||||
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
|
||||
<imppath>$(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/3rdparty/libpng/source</imppath>
|
||||
<imppath>$(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/3rdparty/libpng/source $(SolutionDir)/../DerelictGL3/source $(SolutionDir)/../DerelictUtil/source $(SolutionDir)/../gl3n</imppath>
|
||||
<fileImppath />
|
||||
<outdir>$(ConfigurationName)</outdir>
|
||||
<objdir>$(OutDir)</objdir>
|
||||
|
@ -84,7 +84,7 @@
|
|||
<objfiles />
|
||||
<linkswitches />
|
||||
<libfiles>libpng15.lib dlangui.lib phobos.lib ole32.lib kernel32.lib user32.lib comctl32.lib comdlg32.lib dlangui.lib</libfiles>
|
||||
<libpaths>../../Debug ../../3rdparty/libpng/lib 3rdparty/libpng/lib</libpaths>
|
||||
<libpaths>../../Debug ../../3rdparty/libpng/lib 3rdparty/libpng/lib ../../../DerelictOpenGL3/source</libpaths>
|
||||
<deffile />
|
||||
<resfile />
|
||||
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
|
||||
|
|
|
@ -5,8 +5,8 @@ import std.stdio;
|
|||
|
||||
/// workaround for link issue when WinMain is located in library
|
||||
version(Windows) {
|
||||
import win32.windows;
|
||||
import dlangui.platforms.windows.winapp;
|
||||
private import win32.windows;
|
||||
private import dlangui.platforms.windows.winapp;
|
||||
extern (Windows)
|
||||
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine, int nCmdShow)
|
||||
|
|
|
@ -0,0 +1,490 @@
|
|||
module dlangui.graphics.glsupport;
|
||||
|
||||
import dlangui.core.logger;
|
||||
private import derelict.opengl3.gl3;
|
||||
private import gl3n.linalg;
|
||||
private import dlangui.core.types;
|
||||
|
||||
// utility function to fill 4-float array of vertex colors with converted CR 32bit color
|
||||
private void LVGLFillColor(uint color, float * buf, int count) {
|
||||
float r = ((color >> 16) & 255) / 255.0f;
|
||||
float g = ((color >> 8) & 255) / 255.0f;
|
||||
float b = ((color >> 0) & 255) / 255.0f;
|
||||
float a = (((color >> 24) & 255) ^ 255) / 255.0f;
|
||||
for (int i=0; i<count; i++) {
|
||||
*buf++ = r;
|
||||
*buf++ = g;
|
||||
*buf++ = b;
|
||||
*buf++ = a;
|
||||
}
|
||||
}
|
||||
|
||||
/// for OpenGL calls diagnostics.
|
||||
private bool checkError(string context, string file = __FILE__, int line = __LINE__) {
|
||||
int err = glGetError();
|
||||
if (err != GL_NO_ERROR) {
|
||||
Log.e("OpenGL error ", err, " at ", file, ":", line);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// generate new texture ID
|
||||
uint genTexture() {
|
||||
GLuint textureId = 0;
|
||||
glGenTextures(1, &textureId);
|
||||
return textureId;
|
||||
}
|
||||
|
||||
/// delete OpenGL texture
|
||||
void deleteTexture(ref uint textureId) {
|
||||
if (!textureId)
|
||||
return;
|
||||
if (glIsTexture(textureId) != GL_TRUE) {
|
||||
Log.e("Invalid texture ", textureId);
|
||||
return;
|
||||
}
|
||||
GLuint id = textureId;
|
||||
glDeleteTextures(1, &id);
|
||||
checkError("glDeleteTextures");
|
||||
textureId = 0;
|
||||
}
|
||||
|
||||
/// call glFlush
|
||||
void flushGL() {
|
||||
glFlush();
|
||||
checkError("glFlush");
|
||||
}
|
||||
|
||||
bool setTextureImage(uint textureId, int dx, int dy, ubyte * pixels) {
|
||||
//checkError("before setTextureImage");
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
checkError("updateTexture - glActiveTexture");
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
checkError("updateTexture - glBindTexture(0)");
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
checkError("updateTexture - glBindTexture");
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
checkError("updateTexture - glPixelStorei");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
checkError("updateTexture - glTexParameteri");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
checkError("updateTexture - glTexParameteri");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
checkError("updateTexture - glTexParameteri");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
checkError("updateTexture - glTexParameteri");
|
||||
|
||||
if (!glIsTexture(textureId))
|
||||
Log.e("second test - invalid texture passed to CRGLSupportImpl::setTextureImage");
|
||||
|
||||
// ORIGINAL: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dx, dy, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dx, dy, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
checkError("updateTexture - glTexImage2D");
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
Log.e("Cannot set image for texture");
|
||||
return false;
|
||||
}
|
||||
checkError("after setTextureImage");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setTextureImageAlpha(uint textureId, int dx, int dy, ubyte * pixels) {
|
||||
checkError("before setTextureImageAlpha");
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
checkError("updateTexture - glActiveTexture");
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
checkError("updateTexture - glBindTexture(0)");
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
checkError("setTextureImageAlpha - glBindTexture");
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
checkError("setTextureImageAlpha - glPixelStorei");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
checkError("setTextureImageAlpha - glTexParameteri");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
checkError("setTextureImageAlpha - glTexParameteri");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
checkError("setTextureImageAlpha - glTexParameteri");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
checkError("setTextureImageAlpha - glTexParameteri");
|
||||
|
||||
if (!glIsTexture(textureId))
|
||||
Log.e("second test: invalid texture passed to CRGLSupportImpl::setTextureImageAlpha");
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, dx, dy, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels);
|
||||
checkError("setTextureImageAlpha - glTexImage2D");
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
Log.e("Cannot set image for texture");
|
||||
return false;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
checkError("updateTexture - glBindTexture(0)");
|
||||
checkError("after setTextureImageAlpha");
|
||||
return true;
|
||||
}
|
||||
|
||||
private uint currentFramebufferId;
|
||||
|
||||
/// returns texture ID for buffer, 0 if failed
|
||||
bool createFramebuffer(ref uint textureId, ref uint framebufferId, int dx, int dy) {
|
||||
checkError("before createFramebuffer");
|
||||
bool res = true;
|
||||
textureId = framebufferId = 0;
|
||||
textureId = genTexture();
|
||||
if (!textureId)
|
||||
return false;
|
||||
GLuint fid = 0;
|
||||
glGenFramebuffers(1, &fid);
|
||||
if (checkError("createFramebuffer glGenFramebuffersOES")) return false;
|
||||
framebufferId = fid;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebufferId);
|
||||
if (checkError("createFramebuffer glBindFramebuffer")) return false;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
checkError("glBindTexture(GL_TEXTURE_2D, _textureId)");
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dx, dy, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, null);
|
||||
checkError("glTexImage2D");
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
checkError("texParameter");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
checkError("texParameter");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
checkError("texParameter");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
checkError("texParameter");
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
|
||||
checkError("glFramebufferTexture2D");
|
||||
// Always check that our framebuffer is ok
|
||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
Log.e("glFramebufferTexture2D failed");
|
||||
res = false;
|
||||
}
|
||||
checkError("glCheckFramebufferStatus");
|
||||
//glClearColor(0.5f, 0, 0, 1);
|
||||
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
checkError("glClearColor");
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
checkError("glClear");
|
||||
checkError("after createFramebuffer");
|
||||
//CRLog::trace("CRGLSupportImpl::createFramebuffer %d,%d texture=%d, buffer=%d", dx, dy, textureId, framebufferId);
|
||||
currentFramebufferId = framebufferId;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
checkError("createFramebuffer - glBindTexture(0)");
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
checkError("createFramebuffer - glBindFramebuffer(0)");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void deleteFramebuffer(ref uint framebufferId) {
|
||||
//CRLog::debug("GLDrawBuf::deleteFramebuffer");
|
||||
if (framebufferId != 0) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
checkError("deleteFramebuffer - glBindFramebuffer");
|
||||
GLuint fid = framebufferId;
|
||||
glDeleteFramebuffers(1, &fid);
|
||||
checkError("deleteFramebuffer - glDeleteFramebuffer");
|
||||
}
|
||||
//CRLog::trace("CRGLSupportImpl::deleteFramebuffer(%d)", framebufferId);
|
||||
framebufferId = 0;
|
||||
checkError("after deleteFramebuffer");
|
||||
currentFramebufferId = 0;
|
||||
}
|
||||
|
||||
bool bindFramebuffer(uint framebufferId) {
|
||||
//CRLog::trace("CRGLSupportImpl::bindFramebuffer(%d)", framebufferId);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebufferId);
|
||||
currentFramebufferId = framebufferId;
|
||||
return !checkError("glBindFramebuffer");
|
||||
}
|
||||
|
||||
/// projection matrix
|
||||
private mat4 m;
|
||||
//private float[16] m;
|
||||
/// current gl buffer width
|
||||
private int bufferDx;
|
||||
/// current gl buffer height
|
||||
private int bufferDy;
|
||||
|
||||
void setOrthoProjection(int dx, int dy) {
|
||||
//myGlOrtho(0, dx, 0, dy, -1.0f, 5.0f);
|
||||
bufferDx = dx;
|
||||
bufferDy = dy;
|
||||
//myGlOrtho(0, dx, 0, dy, -0.1f, 5.0f);
|
||||
|
||||
m = mat4.orthographic(0, dx, 0, dy, 0.5f, 5.0f);
|
||||
glViewport(0, 0, dx, dy);
|
||||
checkError("glViewport");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class GLProgram {
|
||||
@property abstract string vertexSource();
|
||||
@property abstract string fragmentSource();
|
||||
GLuint vertexShader;
|
||||
GLuint fragmentShader;
|
||||
GLuint program;
|
||||
bool initialized;
|
||||
bool error;
|
||||
this() {
|
||||
}
|
||||
private GLuint compileShader(string src, GLuint type) {
|
||||
import core.stdc.stdlib;
|
||||
import std.string;
|
||||
GLuint shader = glCreateShader(type);//GL_VERTEX_SHADER
|
||||
const char * psrc = src.toStringz;
|
||||
GLuint len = src.length;
|
||||
glShaderSource(shader, 1, &psrc, cast(const(int)*)&len);
|
||||
glCompileShader(shader);
|
||||
GLint compiled;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
||||
if (compiled) {
|
||||
// compiled successfully
|
||||
return shader;
|
||||
} else {
|
||||
GLint blen = 0;
|
||||
GLsizei slen = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH , &blen);
|
||||
if (blen > 1)
|
||||
{
|
||||
GLchar[] msg = new GLchar[blen + 1];
|
||||
GLchar * pmsg = &msg[0];
|
||||
glGetShaderInfoLog(shader, blen, &slen, pmsg);
|
||||
Log.d("Shader compilation error: ", fromStringz(pmsg));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
bool compile() {
|
||||
vertexShader = compileShader(vertexSource, GL_VERTEX_SHADER);
|
||||
fragmentShader = compileShader(fragmentSource, GL_FRAGMENT_SHADER);
|
||||
if (!vertexShader || !fragmentShader) {
|
||||
error = true;
|
||||
return false;
|
||||
}
|
||||
program = glCreateProgram();
|
||||
glAttachShader(program, vertexShader);
|
||||
glAttachShader(program, fragmentShader);
|
||||
glLinkProgram(program);
|
||||
GLint isLinked = 0;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
|
||||
if (!isLinked) {
|
||||
GLint maxLength = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
GLchar[] msg = new GLchar[maxLength + 1];
|
||||
GLchar * pmsg = &msg[0];
|
||||
glGetProgramInfoLog(program, maxLength, &maxLength, pmsg);
|
||||
Log.e("Error while linking program: ", fromStringz(pmsg));
|
||||
error = true;
|
||||
return false;
|
||||
}
|
||||
glDetachShader(program, vertexShader);
|
||||
glDetachShader(program, fragmentShader);
|
||||
glUseProgram(program);
|
||||
if (!initLocations()) {
|
||||
Log.e("some of locations were not found");
|
||||
error = true;
|
||||
}
|
||||
initialized = true;
|
||||
return true;
|
||||
}
|
||||
bool initLocations() {
|
||||
return true;
|
||||
}
|
||||
bool use() {
|
||||
if (!initialized)
|
||||
return false;
|
||||
glUseProgram(program);
|
||||
checkError("glUseProgram");
|
||||
return true;
|
||||
}
|
||||
void release() {
|
||||
glUseProgram(0);
|
||||
checkError("glUseProgram(0)");
|
||||
}
|
||||
~this() {
|
||||
clear();
|
||||
}
|
||||
void clear() {
|
||||
// TODO: cleanup
|
||||
if (program)
|
||||
glDeleteProgram(program);
|
||||
if (vertexShader)
|
||||
glDeleteShader(vertexShader);
|
||||
if (fragmentShader)
|
||||
glDeleteShader(fragmentShader);
|
||||
program = vertexShader = fragmentShader = 0;
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
class SolidFillProgram : GLProgram {
|
||||
@property override string vertexSource() {
|
||||
return
|
||||
"attribute highp vec4 vertex;\n"
|
||||
"attribute lowp vec4 colAttr;\n"
|
||||
"varying lowp vec4 col;\n"
|
||||
"uniform mediump mat4 matrix;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" gl_Position = matrix * vertex;\n"
|
||||
" col = colAttr;\n"
|
||||
"}\n";
|
||||
|
||||
}
|
||||
@property override string fragmentSource() {
|
||||
return
|
||||
"uniform sampler2D texture;\n"
|
||||
"varying lowp vec4 col;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" gl_FragColor = col;\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
void beforeExecute() {
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_CULL_FACE);
|
||||
checkError("glEnable(GL_BLEND)");
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
checkError("glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)");
|
||||
use();
|
||||
glUniformMatrix4fv(matrixLocation, 1, false, m.value_ptr);
|
||||
}
|
||||
|
||||
void afterExecute() {
|
||||
release();
|
||||
}
|
||||
|
||||
protected GLint matrixLocation;
|
||||
protected GLint vertexLocation;
|
||||
protected GLint colAttrLocation;
|
||||
override bool initLocations() {
|
||||
bool res = super.initLocations();
|
||||
matrixLocation = glGetUniformLocation(program, "matrix");
|
||||
vertexLocation = glGetAttribLocation(program, "vertex");
|
||||
colAttrLocation = glGetAttribLocation(program, "colAttr");
|
||||
return res && matrixLocation >= 0 && vertexLocation >= 0 && colAttrLocation >= 0;
|
||||
}
|
||||
|
||||
bool execute(float[] vertices, float[] colors) {
|
||||
if (error)
|
||||
return false;
|
||||
if (!initialized)
|
||||
if (!compile())
|
||||
return false;
|
||||
beforeExecute();
|
||||
|
||||
glEnableVertexAttribArray(vertexLocation);
|
||||
glEnableVertexAttribArray(colAttrLocation);
|
||||
|
||||
glVertexAttribPointer(vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, vertices.ptr);
|
||||
glVertexAttribPointer(colAttrLocation, 4, GL_FLOAT, GL_FALSE, 0, colors.ptr);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
checkError("glDrawArrays");
|
||||
glDisableVertexAttribArray(vertexLocation);
|
||||
glDisableVertexAttribArray(colAttrLocation);
|
||||
|
||||
afterExecute();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
checkError("glBindTexture");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class TextureProgram : SolidFillProgram {
|
||||
@property override string vertexSource() {
|
||||
return
|
||||
"attribute highp vec4 vertex;\n"
|
||||
"attribute lowp vec4 colAttr;\n"
|
||||
"attribute mediump vec4 texCoord;\n"
|
||||
"varying lowp vec4 col;\n"
|
||||
"varying mediump vec4 texc;\n"
|
||||
"uniform mediump mat4 matrix;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" gl_Position = matrix * vertex;\n"
|
||||
" col = colAttr;\n"
|
||||
" texc = texCoord;\n"
|
||||
"}\n";
|
||||
|
||||
}
|
||||
@property override string fragmentSource() {
|
||||
return
|
||||
"uniform sampler2D texture;\n"
|
||||
"varying lowp vec4 col;\n"
|
||||
"varying mediump vec4 texc;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" gl_FragColor = texture2D(texture, texc.st) * col;\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
GLint texCoordLocation;
|
||||
override bool initLocations() {
|
||||
bool res = super.initLocations();
|
||||
texCoordLocation = glGetAttribLocation(program, "texCoord");
|
||||
return res && texCoordLocation >= 0;
|
||||
}
|
||||
|
||||
bool execute(float[] vertices, float[] texcoords, float[] colors, uint textureId, bool linear) {
|
||||
if (error)
|
||||
return false;
|
||||
if (!initialized)
|
||||
if (!compile())
|
||||
return false;
|
||||
beforeExecute();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
checkError("glActiveTexture GL_TEXTURE0");
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
checkError("glBindTexture");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST);
|
||||
checkError("drawColorAndTextureRect - glTexParameteri");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST);
|
||||
checkError("drawColorAndTextureRect - glTexParameteri");
|
||||
|
||||
glEnableVertexAttribArray(vertexLocation);
|
||||
glEnableVertexAttribArray(colAttrLocation);
|
||||
glEnableVertexAttribArray(texCoordLocation);
|
||||
|
||||
glVertexAttribPointer(vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, vertices.ptr);
|
||||
glVertexAttribPointer(colAttrLocation, 4, GL_FLOAT, GL_FALSE, 0, colors.ptr);
|
||||
glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords.ptr);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
checkError("glDrawArrays");
|
||||
|
||||
glDisableVertexAttribArray(vertexLocation);
|
||||
glDisableVertexAttribArray(colAttrLocation);
|
||||
glDisableVertexAttribArray(texCoordLocation);
|
||||
|
||||
afterExecute();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
checkError("glBindTexture");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
__gshared TextureProgram _textureProgram;
|
||||
__gshared SolidFillProgram _solidFillProgram;
|
||||
|
||||
bool initShaders() {
|
||||
if (_textureProgram is null) {
|
||||
_textureProgram = new TextureProgram();
|
||||
if (!_textureProgram.compile())
|
||||
return false;
|
||||
}
|
||||
if (_solidFillProgram is null) {
|
||||
_solidFillProgram = new SolidFillProgram();
|
||||
if (!_solidFillProgram.compile())
|
||||
return false;
|
||||
}
|
||||
Log.d("Shaders compiled successfully");
|
||||
return true;
|
||||
}
|
|
@ -50,6 +50,14 @@ public class Platform {
|
|||
abstract public int enterMessageLoop();
|
||||
}
|
||||
|
||||
private __gshared bool _OPENGL_ENABLED = false;
|
||||
/// check if hardware acceleration is enabled
|
||||
@property bool openglEnabled() { return _OPENGL_ENABLED; }
|
||||
/// call on app initialization if OpenGL support is detected
|
||||
void setOpenglEnabled() {
|
||||
_OPENGL_ENABLED = true;
|
||||
}
|
||||
|
||||
version (Windows) {
|
||||
immutable char PATH_DELIMITER = '\\';
|
||||
}
|
||||
|
|
|
@ -14,7 +14,9 @@ import dlangui.platforms.windows.win32fonts;
|
|||
import dlangui.platforms.windows.win32drawbuf;
|
||||
import dlangui.graphics.drawbuf;
|
||||
import dlangui.graphics.fonts;
|
||||
import dlangui.graphics.glsupport;
|
||||
import dlangui.core.logger;
|
||||
//import derelict.opengl3.wgl;
|
||||
|
||||
pragma(lib, "gdi32.lib");
|
||||
pragma(lib, "user32.lib");
|
||||
|
@ -27,11 +29,105 @@ immutable WIN_CLASS_NAME = "DLANGUI_APP";
|
|||
__gshared HINSTANCE _hInstance;
|
||||
__gshared int _cmdShow;
|
||||
|
||||
bool setupPixelFormat(HDC hDC)
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR pfd = {
|
||||
PIXELFORMATDESCRIPTOR.sizeof, /* size */
|
||||
1, /* version */
|
||||
PFD_SUPPORT_OPENGL |
|
||||
PFD_DRAW_TO_WINDOW |
|
||||
PFD_DOUBLEBUFFER, /* support double-buffering */
|
||||
PFD_TYPE_RGBA, /* color type */
|
||||
16, /* prefered color depth */
|
||||
0, 0, 0, 0, 0, 0, /* color bits (ignored) */
|
||||
0, /* no alpha buffer */
|
||||
0, /* alpha bits (ignored) */
|
||||
0, /* no accumulation buffer */
|
||||
0, 0, 0, 0, /* accum bits (ignored) */
|
||||
16, /* depth buffer */
|
||||
0, /* no stencil buffer */
|
||||
0, /* no auxiliary buffers */
|
||||
0, /* main layer PFD_MAIN_PLANE */
|
||||
0, /* reserved */
|
||||
0, 0, 0, /* no layer, visible, damage masks */
|
||||
};
|
||||
int pixelFormat;
|
||||
|
||||
pixelFormat = ChoosePixelFormat(hDC, &pfd);
|
||||
if (pixelFormat == 0) {
|
||||
Log.e("ChoosePixelFormat failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) {
|
||||
Log.e("SetPixelFormat failed.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
HPALETTE setupPalette(HDC hDC)
|
||||
{
|
||||
import core.stdc.stdlib;
|
||||
HPALETTE hPalette = NULL;
|
||||
int pixelFormat = GetPixelFormat(hDC);
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
LOGPALETTE* pPal;
|
||||
int paletteSize;
|
||||
|
||||
DescribePixelFormat(hDC, pixelFormat, PIXELFORMATDESCRIPTOR.sizeof, &pfd);
|
||||
|
||||
if (pfd.dwFlags & PFD_NEED_PALETTE) {
|
||||
paletteSize = 1 << pfd.cColorBits;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
pPal = cast(LOGPALETTE*)
|
||||
malloc(LOGPALETTE.sizeof + paletteSize * PALETTEENTRY.sizeof);
|
||||
pPal.palVersion = 0x300;
|
||||
pPal.palNumEntries = cast(ushort)paletteSize;
|
||||
|
||||
/* build a simple RGB color palette */
|
||||
{
|
||||
int redMask = (1 << pfd.cRedBits) - 1;
|
||||
int greenMask = (1 << pfd.cGreenBits) - 1;
|
||||
int blueMask = (1 << pfd.cBlueBits) - 1;
|
||||
int i;
|
||||
|
||||
for (i=0; i<paletteSize; ++i) {
|
||||
pPal.palPalEntry[i].peRed = cast(ubyte)(
|
||||
(((i >> pfd.cRedShift) & redMask) * 255) / redMask);
|
||||
pPal.palPalEntry[i].peGreen = cast(ubyte)(
|
||||
(((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask);
|
||||
pPal.palPalEntry[i].peBlue = cast(ubyte)(
|
||||
(((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask);
|
||||
pPal.palPalEntry[i].peFlags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
hPalette = CreatePalette(pPal);
|
||||
free(pPal);
|
||||
|
||||
if (hPalette) {
|
||||
SelectPalette(hDC, hPalette, FALSE);
|
||||
RealizePalette(hDC);
|
||||
}
|
||||
|
||||
return hPalette;
|
||||
}
|
||||
|
||||
private __gshared bool DERELICT_GL3_RELOADED = false;
|
||||
|
||||
class Win32Window : Window {
|
||||
private HWND _hwnd;
|
||||
HGLRC _hGLRC; // opengl context
|
||||
HPALETTE _hPalette;
|
||||
string _caption;
|
||||
Win32ColorDrawBuf _drawbuf;
|
||||
bool useOpengl;
|
||||
this(string windowCaption, Window parent) {
|
||||
import derelict.opengl3.wgl;
|
||||
_caption = windowCaption;
|
||||
_hwnd = CreateWindow(toUTF16z(WIN_CLASS_NAME), // window class name
|
||||
toUTF16z(windowCaption), // window caption
|
||||
|
@ -44,6 +140,54 @@ class Win32Window : Window {
|
|||
null, // window menu handle
|
||||
_hInstance, // program instance handle
|
||||
cast(void*)this); // creation parameters
|
||||
/* initialize OpenGL rendering */
|
||||
HDC hDC = GetDC(_hwnd);
|
||||
|
||||
if (!DERELICT_GL3_RELOADED || openglEnabled) {
|
||||
if (setupPixelFormat(hDC)) {
|
||||
_hPalette = setupPalette(hDC);
|
||||
_hGLRC = wglCreateContext(hDC);
|
||||
if (_hGLRC) {
|
||||
wglMakeCurrent(hDC, _hGLRC);
|
||||
|
||||
if (!DERELICT_GL3_RELOADED) {
|
||||
// run this code only once
|
||||
DERELICT_GL3_RELOADED = true;
|
||||
try {
|
||||
import derelict.opengl3.gl3;
|
||||
DerelictGL3.reload();
|
||||
// successful
|
||||
if (initShaders()) {
|
||||
setOpenglEnabled();
|
||||
useOpengl = true;
|
||||
} else {
|
||||
Log.e("Failed to compile shaders");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("Derelict exception", e);
|
||||
}
|
||||
} else {
|
||||
useOpengl = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.e("Pixelformat failed");
|
||||
// disable GL
|
||||
DERELICT_GL3_RELOADED = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
~this() {
|
||||
Log.d("Window destructor");
|
||||
import derelict.opengl3.wgl;
|
||||
if (_hGLRC) {
|
||||
wglMakeCurrent (null, null) ;
|
||||
wglDeleteContext(_hGLRC);
|
||||
_hGLRC = null;
|
||||
}
|
||||
if (_hwnd)
|
||||
DestroyWindow(_hwnd);
|
||||
_hwnd = null;
|
||||
}
|
||||
Win32ColorDrawBuf getDrawBuf() {
|
||||
//RECT rect;
|
||||
|
@ -68,10 +212,39 @@ class Win32Window : Window {
|
|||
SetWindowTextW(_hwnd, toUTF16z(_caption));
|
||||
}
|
||||
void onCreate() {
|
||||
writeln("Window onCreate");
|
||||
Log.d("Window onCreate");
|
||||
}
|
||||
void onDestroy() {
|
||||
writeln("Window onDestroy");
|
||||
Log.d("Window onDestroy");
|
||||
}
|
||||
void onPaint() {
|
||||
Log.d("onPaint()");
|
||||
if (useOpengl && _hGLRC) {
|
||||
import derelict.opengl3.gl3;
|
||||
import derelict.opengl3.wgl;
|
||||
//Log.d("onPaint() start drawing opengl viewport: ", _dx, "x", _dy);
|
||||
//PAINTSTRUCT ps;
|
||||
//HDC hdc = BeginPaint(_hwnd, &ps);
|
||||
//scope(exit) EndPaint(_hwnd, &ps);
|
||||
HDC hdc = GetDC(_hwnd);
|
||||
wglMakeCurrent(hdc, _hGLRC);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glViewport(0, 0, _dx, _dy);
|
||||
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
//Log.d("onPaint() end drawing opengl");
|
||||
glFlush();
|
||||
SwapBuffers(hdc);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,6 +358,24 @@ int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
|
|||
Win32FontManager fontMan = new Win32FontManager();
|
||||
FontManager.instance = fontMan;
|
||||
|
||||
{
|
||||
import derelict.opengl3.gl3;
|
||||
DerelictGL3.load();
|
||||
|
||||
// just to check OpenGL context
|
||||
Log.i("Trying to setup OpenGL context");
|
||||
Win32Window tmpWindow = new Win32Window("", null);
|
||||
destroy(tmpWindow);
|
||||
if (openglEnabled)
|
||||
Log.i("OpenGL support is enabled");
|
||||
else
|
||||
Log.w("OpenGL support is disabled");
|
||||
// process messages
|
||||
platform.enterMessageLoop();
|
||||
}
|
||||
|
||||
// Load versions 1.2+ and all supported ARB and EXT extensions.
|
||||
|
||||
Log.i("Entering UIAppMain: ", args);
|
||||
int result = UIAppMain(args);
|
||||
Log.i("UIAppMain returned ", result);
|
||||
|
@ -196,7 +387,6 @@ extern(Windows)
|
|||
LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HDC hdc;
|
||||
PAINTSTRUCT ps;
|
||||
RECT rect;
|
||||
void * p = cast(void*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
Win32Window window = p is null ? null : cast(Win32Window)(p);
|
||||
|
@ -232,14 +422,8 @@ LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
//int dx = rect.right - rect.left;
|
||||
//int dy = rect.bottom - rect.top;
|
||||
//window.onResize(dx, dy);
|
||||
|
||||
hdc = BeginPaint(hwnd, &ps);
|
||||
scope(exit) EndPaint(hwnd, &ps);
|
||||
|
||||
Win32ColorDrawBuf buf = window.getDrawBuf();
|
||||
buf.fill(0x808080);
|
||||
window.onDraw(buf);
|
||||
buf.drawTo(hdc, 0, 0);
|
||||
if (window !is null)
|
||||
window.onPaint();
|
||||
|
||||
}
|
||||
return 0; // processed
|
||||
|
|
Loading…
Reference in New Issue