mirror of https://github.com/buggins/dlangui.git
fix OpenGL support in additional windows under pure win32 - issue #27
This commit is contained in:
parent
359ac8d0ba
commit
83b4e98390
|
@ -66,7 +66,7 @@
|
||||||
<debuglevel>0</debuglevel>
|
<debuglevel>0</debuglevel>
|
||||||
<debugids>DebugFocus</debugids>
|
<debugids>DebugFocus</debugids>
|
||||||
<versionlevel>0</versionlevel>
|
<versionlevel>0</versionlevel>
|
||||||
<versionids>USE_OPENGL Unicode</versionids>
|
<versionids>USE_OPENGL USE_SDL Unicode</versionids>
|
||||||
<dump_source>0</dump_source>
|
<dump_source>0</dump_source>
|
||||||
<mapverbosity>0</mapverbosity>
|
<mapverbosity>0</mapverbosity>
|
||||||
<createImplib>1</createImplib>
|
<createImplib>1</createImplib>
|
||||||
|
@ -89,7 +89,6 @@
|
||||||
<resfile />
|
<resfile />
|
||||||
<exefile>$(OutDir)\$(ProjectName).lib</exefile>
|
<exefile>$(OutDir)\$(ProjectName).lib</exefile>
|
||||||
<useStdLibPath>1</useStdLibPath>
|
<useStdLibPath>1</useStdLibPath>
|
||||||
<cRuntime>2</cRuntime>
|
|
||||||
<additionalOptions />
|
<additionalOptions />
|
||||||
<preBuildCommand />
|
<preBuildCommand />
|
||||||
<postBuildCommand />
|
<postBuildCommand />
|
||||||
|
@ -184,7 +183,6 @@
|
||||||
<resfile />
|
<resfile />
|
||||||
<exefile>$(OutDir)\$(ProjectName).lib</exefile>
|
<exefile>$(OutDir)\$(ProjectName).lib</exefile>
|
||||||
<useStdLibPath>1</useStdLibPath>
|
<useStdLibPath>1</useStdLibPath>
|
||||||
<cRuntime>1</cRuntime>
|
|
||||||
<additionalOptions />
|
<additionalOptions />
|
||||||
<preBuildCommand />
|
<preBuildCommand />
|
||||||
<postBuildCommand />
|
<postBuildCommand />
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
<debuglevel>0</debuglevel>
|
<debuglevel>0</debuglevel>
|
||||||
<debugids />
|
<debugids />
|
||||||
<versionlevel>0</versionlevel>
|
<versionlevel>0</versionlevel>
|
||||||
<versionids>USE_OPENGL Unicode</versionids>
|
<versionids>USE_OPENGL USE_SDL Unicode</versionids>
|
||||||
<dump_source>0</dump_source>
|
<dump_source>0</dump_source>
|
||||||
<mapverbosity>3</mapverbosity>
|
<mapverbosity>3</mapverbosity>
|
||||||
<createImplib>0</createImplib>
|
<createImplib>0</createImplib>
|
||||||
|
@ -89,7 +89,6 @@
|
||||||
<resfile />
|
<resfile />
|
||||||
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
|
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
|
||||||
<useStdLibPath>1</useStdLibPath>
|
<useStdLibPath>1</useStdLibPath>
|
||||||
<cRuntime>2</cRuntime>
|
|
||||||
<additionalOptions>-profile</additionalOptions>
|
<additionalOptions>-profile</additionalOptions>
|
||||||
<preBuildCommand />
|
<preBuildCommand />
|
||||||
<postBuildCommand />
|
<postBuildCommand />
|
||||||
|
@ -184,7 +183,6 @@
|
||||||
<resfile />
|
<resfile />
|
||||||
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
|
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
|
||||||
<useStdLibPath>1</useStdLibPath>
|
<useStdLibPath>1</useStdLibPath>
|
||||||
<cRuntime>1</cRuntime>
|
|
||||||
<additionalOptions />
|
<additionalOptions />
|
||||||
<preBuildCommand />
|
<preBuildCommand />
|
||||||
<postBuildCommand />
|
<postBuildCommand />
|
||||||
|
|
|
@ -62,9 +62,9 @@ class GLDrawBuf : DrawBuf {
|
||||||
|
|
||||||
/// reserved for hardware-accelerated drawing - ends drawing batch
|
/// reserved for hardware-accelerated drawing - ends drawing batch
|
||||||
override void afterDrawing() {
|
override void afterDrawing() {
|
||||||
setOrthoProjection(_dx, _dy);
|
glSupport.setOrthoProjection(_dx, _dy);
|
||||||
_scene.draw();
|
_scene.draw();
|
||||||
flushGL();
|
glSupport.flushGL();
|
||||||
destroy(_scene);
|
destroy(_scene);
|
||||||
_scene = null;
|
_scene = null;
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ private class GLImageCache {
|
||||||
_drawbuf = null;
|
_drawbuf = null;
|
||||||
}
|
}
|
||||||
if (_textureId != 0) {
|
if (_textureId != 0) {
|
||||||
deleteTexture(_textureId);
|
glSupport.deleteTexture(_textureId);
|
||||||
_textureId = 0;
|
_textureId = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,14 +254,14 @@ private class GLImageCache {
|
||||||
return; // no draw buffer!!!
|
return; // no draw buffer!!!
|
||||||
if (_textureId == 0) {
|
if (_textureId == 0) {
|
||||||
//CRLog::debug("updateTexture - new texture");
|
//CRLog::debug("updateTexture - new texture");
|
||||||
_textureId = genTexture();
|
_textureId = glSupport.genTexture();
|
||||||
if (!_textureId)
|
if (!_textureId)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//CRLog::debug("updateTexture - setting image %dx%d", _drawbuf.width, _drawbuf.height);
|
//CRLog::debug("updateTexture - setting image %dx%d", _drawbuf.width, _drawbuf.height);
|
||||||
uint * pixels = _drawbuf.scanLine(0);
|
uint * pixels = _drawbuf.scanLine(0);
|
||||||
if (!setTextureImage(_textureId, _drawbuf.width, _drawbuf.height, cast(ubyte*)pixels)) {
|
if (!glSupport.setTextureImage(_textureId, _drawbuf.width, _drawbuf.height, cast(ubyte*)pixels)) {
|
||||||
deleteTexture(_textureId);
|
glSupport.deleteTexture(_textureId);
|
||||||
_textureId = 0;
|
_textureId = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ private class GLImageCache {
|
||||||
if (_needUpdateTexture)
|
if (_needUpdateTexture)
|
||||||
updateTexture();
|
updateTexture();
|
||||||
if (_textureId != 0) {
|
if (_textureId != 0) {
|
||||||
if (!isTexture(_textureId)) {
|
if (!glSupport.isTexture(_textureId)) {
|
||||||
Log.e("Invalid texture ", _textureId);
|
Log.e("Invalid texture ", _textureId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -371,12 +371,12 @@ private class GLImageCache {
|
||||||
dstrc.bottom -= clip.bottom;
|
dstrc.bottom -= clip.bottom;
|
||||||
}
|
}
|
||||||
if (!dstrc.empty)
|
if (!dstrc.empty)
|
||||||
drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, srcrc.width() != dstrc.width() || srcrc.height() != dstrc.height());
|
glSupport.drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, srcrc.width() != dstrc.width() || srcrc.height() != dstrc.height());
|
||||||
//drawColorAndTextureRect(vertices, texcoords, color, _textureId);
|
//drawColorAndTextureRect(vertices, texcoords, color, _textureId);
|
||||||
|
|
||||||
if (rotationAngle) {
|
if (rotationAngle) {
|
||||||
// unset rotation
|
// unset rotation
|
||||||
setRotation(rx, ry, 0);
|
glSupport.setRotation(rx, ry, 0);
|
||||||
// glMatrixMode(GL_PROJECTION);
|
// glMatrixMode(GL_PROJECTION);
|
||||||
// glPopMatrix();
|
// glPopMatrix();
|
||||||
// checkError("pop matrix");
|
// checkError("pop matrix");
|
||||||
|
@ -576,7 +576,7 @@ private class GLGlyphCache {
|
||||||
_drawbuf = null;
|
_drawbuf = null;
|
||||||
}
|
}
|
||||||
if (_textureId != 0) {
|
if (_textureId != 0) {
|
||||||
deleteTexture(_textureId);
|
glSupport.deleteTexture(_textureId);
|
||||||
_textureId = 0;
|
_textureId = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -589,7 +589,7 @@ private class GLGlyphCache {
|
||||||
return; // no draw buffer!!!
|
return; // no draw buffer!!!
|
||||||
if (_textureId == 0) {
|
if (_textureId == 0) {
|
||||||
//CRLog::debug("updateTexture - new texture");
|
//CRLog::debug("updateTexture - new texture");
|
||||||
_textureId = genTexture();
|
_textureId = glSupport.genTexture();
|
||||||
if (!_textureId)
|
if (!_textureId)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -600,8 +600,8 @@ private class GLGlyphCache {
|
||||||
_rgbaBuffer.length = len;
|
_rgbaBuffer.length = len;
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
_rgbaBuffer[i] = ((cast(uint)pixels[i]) << 24) | 0x00FFFFFF;
|
_rgbaBuffer[i] = ((cast(uint)pixels[i]) << 24) | 0x00FFFFFF;
|
||||||
if (!setTextureImage(_textureId, _drawbuf.width, _drawbuf.height, cast(ubyte*)_rgbaBuffer.ptr)) {
|
if (!glSupport.setTextureImage(_textureId, _drawbuf.width, _drawbuf.height, cast(ubyte*)_rgbaBuffer.ptr)) {
|
||||||
deleteTexture(_textureId);
|
glSupport.deleteTexture(_textureId);
|
||||||
_textureId = 0;
|
_textureId = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -667,7 +667,7 @@ private class GLGlyphCache {
|
||||||
if (_needUpdateTexture)
|
if (_needUpdateTexture)
|
||||||
updateTexture();
|
updateTexture();
|
||||||
if (_textureId != 0) {
|
if (_textureId != 0) {
|
||||||
if (!isTexture(_textureId)) {
|
if (!glSupport.isTexture(_textureId)) {
|
||||||
Log.e("Invalid texture ", _textureId);
|
Log.e("Invalid texture ", _textureId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -693,7 +693,7 @@ private class GLGlyphCache {
|
||||||
}
|
}
|
||||||
if (!dstrc.empty) {
|
if (!dstrc.empty) {
|
||||||
//Log.d("drawing glyph with color ", color);
|
//Log.d("drawing glyph with color ", color);
|
||||||
drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, false);
|
glSupport.drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -818,7 +818,7 @@ class SolidRectSceneItem : SceneItem {
|
||||||
_color = color;
|
_color = color;
|
||||||
}
|
}
|
||||||
override void draw() {
|
override void draw() {
|
||||||
drawSolidFillRect(_rc, _color, _color, _color, _color);
|
glSupport.drawSolidFillRect(_rc, _color, _color, _color, _color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,8 @@ static this() {
|
||||||
0x0505: "GL_OUT_OF_MEMORY"
|
0x0505: "GL_OUT_OF_MEMORY"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
/* Convenient wrapper around glGetError()
|
/**
|
||||||
|
* Convenient wrapper around glGetError()
|
||||||
* TODO use one of the DEBUG extensions instead
|
* TODO use one of the DEBUG extensions instead
|
||||||
*/
|
*/
|
||||||
bool checkError(string context="", string file=__FILE__, int line=__LINE__)
|
bool checkError(string context="", string file=__FILE__, int line=__LINE__)
|
||||||
|
@ -67,7 +68,427 @@ bool checkError(string context="", string file=__FILE__, int line=__LINE__)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
immutable float Z_2D = -2.0f;
|
|
||||||
|
class GLProgram {
|
||||||
|
@property abstract string vertexSource();
|
||||||
|
@property abstract string fragmentSource();
|
||||||
|
protected GLuint vertexShader;
|
||||||
|
protected GLuint fragmentShader;
|
||||||
|
protected GLuint program;
|
||||||
|
protected bool initialized;
|
||||||
|
protected bool error;
|
||||||
|
protected string glslversion;
|
||||||
|
this() {
|
||||||
|
}
|
||||||
|
private GLuint compileShader(string src, GLuint type) {
|
||||||
|
import core.stdc.stdlib;
|
||||||
|
import std.string;
|
||||||
|
|
||||||
|
Log.d("compileShader glsl=", glslversion, " code: ", src);
|
||||||
|
|
||||||
|
GLuint shader = glCreateShader(type);//GL_VERTEX_SHADER
|
||||||
|
const char * psrc = src.toStringz;
|
||||||
|
GLuint len = cast(uint)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() {
|
||||||
|
glslversion = cast(string)std.string.fromStringz(glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
Log.d("Program compiled successfully");
|
||||||
|
//glDetachShader(program, vertexShader);
|
||||||
|
//glDetachShader(program, fragmentShader);
|
||||||
|
glUseProgram(program);
|
||||||
|
checkError("glUseProgram " ~ to!string(program));
|
||||||
|
if (!initLocations()) {
|
||||||
|
Log.e("some of locations were not found");
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool initLocations() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool bind() {
|
||||||
|
if (!initialized)
|
||||||
|
return false;
|
||||||
|
if (!glIsProgram(program))
|
||||||
|
Log.e("!glIsProgram(program)");
|
||||||
|
glUseProgram(program);
|
||||||
|
checkError("glUseProgram " ~ to!string(program));
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
immutable string HIGHP = "";
|
||||||
|
immutable string LOWP = "";
|
||||||
|
immutable string MEDIUMP = "";
|
||||||
|
|
||||||
|
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
|
||||||
|
"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("glDisable(GL_CULL_FACE)");
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
checkError("glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)");
|
||||||
|
bind();
|
||||||
|
//glUniformMatrix4fv(matrixLocation, 1, false, m.value_ptr);
|
||||||
|
//glUniformMatrix4fv(matrixLocation, 1, false, matrix.ptr);
|
||||||
|
glUniformMatrix4fv(matrixLocation, 1, false, glSupport.qtmatrix.ptr);
|
||||||
|
checkError("glUniformMatrix4fv");
|
||||||
|
}
|
||||||
|
|
||||||
|
void afterExecute() {
|
||||||
|
release();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected GLint matrixLocation;
|
||||||
|
protected GLint vertexLocation;
|
||||||
|
protected GLint colAttrLocation;
|
||||||
|
protected GLuint vertexBuffer;
|
||||||
|
protected GLuint colAttrBuffer;
|
||||||
|
override bool initLocations() {
|
||||||
|
bool res = super.initLocations();
|
||||||
|
|
||||||
|
//glGenBuffers(1, &vertexBuffer);
|
||||||
|
//glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||||
|
//glBufferData(GL_ARRAY_BUFFER, float.sizeof * 3 * 6, null, GL_DYNAMIC_DRAW);
|
||||||
|
//glGenBuffers(1, &colAttrBuffer);
|
||||||
|
//glBindBuffer(GL_ARRAY_BUFFER, colAttrBuffer);
|
||||||
|
//glBufferData(GL_ARRAY_BUFFER, float.sizeof * 4 * 6, null, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
matrixLocation = glGetUniformLocation(program, "matrix");
|
||||||
|
checkError("glGetUniformLocation matrix");
|
||||||
|
vertexLocation = glGetAttribLocation(program, "vertex");
|
||||||
|
checkError("glGetAttribLocation vertex");
|
||||||
|
colAttrLocation = glGetAttribLocation(program, "colAttr");
|
||||||
|
checkError("glGetAttribLocation 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();
|
||||||
|
|
||||||
|
GLuint vao;
|
||||||
|
glGenVertexArrays(1, &vao);
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
|
GLuint vbo;
|
||||||
|
glGenBuffers(1, &vbo);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
glBufferData(
|
||||||
|
GL_ARRAY_BUFFER,
|
||||||
|
vertices.length * vertices[0].sizeof + colors.length * colors[0].sizeof,
|
||||||
|
null,
|
||||||
|
GL_STREAM_DRAW);
|
||||||
|
glBufferSubData(
|
||||||
|
GL_ARRAY_BUFFER,
|
||||||
|
0,
|
||||||
|
vertices.length * vertices[0].sizeof,
|
||||||
|
vertices.ptr);
|
||||||
|
glBufferSubData(
|
||||||
|
GL_ARRAY_BUFFER,
|
||||||
|
vertices.length * vertices[0].sizeof,
|
||||||
|
colors.length * colors[0].sizeof, colors.ptr);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(vertexLocation);
|
||||||
|
checkError("glEnableVertexAttribArray");
|
||||||
|
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cast(void*) 0);
|
||||||
|
checkError("glVertexAttribPointer");
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(colAttrLocation);
|
||||||
|
checkError("glEnableVertexAttribArray");
|
||||||
|
glVertexAttribPointer(colAttrLocation, 4, GL_FLOAT, GL_FALSE, 0, cast(void*) (float.sizeof*3*6));
|
||||||
|
checkError("glVertexAttribPointer");
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
checkError("glDrawArrays");
|
||||||
|
|
||||||
|
glDisableVertexAttribArray(vertexLocation);
|
||||||
|
checkError("glDisableVertexAttribArray");
|
||||||
|
glDisableVertexAttribArray(colAttrLocation);
|
||||||
|
checkError("glDisableVertexAttribArray");
|
||||||
|
|
||||||
|
afterExecute();
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glDeleteBuffers(1, &vbo);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glDeleteVertexArrays(1, &vao);
|
||||||
|
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");
|
||||||
|
|
||||||
|
GLuint vao;
|
||||||
|
glGenVertexArrays(1, &vao);
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
|
GLuint vbo;
|
||||||
|
glGenBuffers(1, &vbo);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
glBufferData(
|
||||||
|
GL_ARRAY_BUFFER,
|
||||||
|
vertices.length * vertices[0].sizeof +
|
||||||
|
colors.length * colors[0].sizeof +
|
||||||
|
texcoords.length * texcoords[0].sizeof,
|
||||||
|
null,
|
||||||
|
GL_STREAM_DRAW);
|
||||||
|
glBufferSubData(
|
||||||
|
GL_ARRAY_BUFFER,
|
||||||
|
0,
|
||||||
|
vertices.length * vertices[0].sizeof,
|
||||||
|
vertices.ptr);
|
||||||
|
glBufferSubData(
|
||||||
|
GL_ARRAY_BUFFER,
|
||||||
|
vertices.length * vertices[0].sizeof,
|
||||||
|
colors.length * colors[0].sizeof,
|
||||||
|
colors.ptr);
|
||||||
|
glBufferSubData(
|
||||||
|
GL_ARRAY_BUFFER,
|
||||||
|
vertices.length * vertices[0].sizeof + colors.length * colors[0].sizeof,
|
||||||
|
texcoords.length * texcoords[0].sizeof,
|
||||||
|
texcoords.ptr);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(vertexLocation);
|
||||||
|
glEnableVertexAttribArray(colAttrLocation);
|
||||||
|
glEnableVertexAttribArray(texCoordLocation);
|
||||||
|
|
||||||
|
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cast(void*) 0);
|
||||||
|
glVertexAttribPointer(colAttrLocation, 4, GL_FLOAT, GL_FALSE, 0, cast(void*) (vertices.length * vertices[0].sizeof));
|
||||||
|
glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, cast(void*) (vertices.length * vertices[0].sizeof + colors.length * colors[0].sizeof));
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
checkError("glDrawArrays");
|
||||||
|
|
||||||
|
glDisableVertexAttribArray(vertexLocation);
|
||||||
|
glDisableVertexAttribArray(colAttrLocation);
|
||||||
|
glDisableVertexAttribArray(texCoordLocation);
|
||||||
|
|
||||||
|
afterExecute();
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glDeleteBuffers(1, &vbo);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glDeleteVertexArrays(1, &vao);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
checkError("glBindTexture");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__gshared GLSupport _glSupport;
|
||||||
|
@property GLSupport glSupport() {
|
||||||
|
if (!_glSupport) {
|
||||||
|
Log.f("GLSupport is not initialized");
|
||||||
|
assert(false, "GLSupport is not initialized");
|
||||||
|
}
|
||||||
|
if (!_glSupport.valid) {
|
||||||
|
Log.e("GLSupport programs are not initialized");
|
||||||
|
}
|
||||||
|
return _glSupport;
|
||||||
|
}
|
||||||
|
|
||||||
|
class GLSupport {
|
||||||
|
|
||||||
|
TextureProgram _textureProgram;
|
||||||
|
SolidFillProgram _solidFillProgram;
|
||||||
|
|
||||||
|
@property bool valid() {
|
||||||
|
return _textureProgram && _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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool uninitShaders() {
|
||||||
|
Log.d("Uniniting shaders");
|
||||||
|
if (_textureProgram !is null) {
|
||||||
|
destroy(_textureProgram);
|
||||||
|
_textureProgram = null;
|
||||||
|
}
|
||||||
|
if (_solidFillProgram !is null) {
|
||||||
|
destroy(_solidFillProgram);
|
||||||
|
_solidFillProgram = null;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTexture(uint textureId) {
|
||||||
|
return glIsTexture(textureId) == GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRotation(int x, int y, int rotationAngle) {
|
||||||
|
/*
|
||||||
|
this->rotationAngle = rotationAngle;
|
||||||
|
rotationX = x;
|
||||||
|
rotationY = y;
|
||||||
|
if (!currentFramebufferId) {
|
||||||
|
rotationY = bufferDy - rotationY;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMatrix4x4 matrix2;
|
||||||
|
matrix2.ortho(0, bufferDx, 0, bufferDy, 0.5f, 5.0f);
|
||||||
|
if (rotationAngle) {
|
||||||
|
matrix2.translate(rotationX, rotationY, 0);
|
||||||
|
matrix2.rotate(rotationAngle, 0, 0, 1);
|
||||||
|
matrix2.translate(-rotationX, -rotationY, 0);
|
||||||
|
}
|
||||||
|
matrix2.copyDataTo(m);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
static immutable float Z_2D = -2.0f;
|
||||||
void drawSolidFillRect(Rect rc, uint color1, uint color2, uint color3, uint color4) {
|
void drawSolidFillRect(Rect rc, uint color1, uint color2, uint color3, uint color4) {
|
||||||
float[6 * 4] colors;
|
float[6 * 4] colors;
|
||||||
LVGLFillColor(color1, colors.ptr + 4*0, 1);
|
LVGLFillColor(color1, colors.ptr + 4*0, 1);
|
||||||
|
@ -313,7 +734,6 @@ bool bindFramebuffer(uint framebufferId) {
|
||||||
private int bufferDx;
|
private int bufferDx;
|
||||||
/// current gl buffer height
|
/// current gl buffer height
|
||||||
private int bufferDy;
|
private int bufferDy;
|
||||||
|
|
||||||
//private float[16] matrix;
|
//private float[16] matrix;
|
||||||
private float[16] qtmatrix;
|
private float[16] qtmatrix;
|
||||||
|
|
||||||
|
@ -357,404 +777,5 @@ void setOrthoProjection(int dx, int dy) {
|
||||||
checkError("glViewport");
|
checkError("glViewport");
|
||||||
}
|
}
|
||||||
|
|
||||||
class GLProgram {
|
|
||||||
@property abstract string vertexSource();
|
|
||||||
@property abstract string fragmentSource();
|
|
||||||
protected GLuint vertexShader;
|
|
||||||
protected GLuint fragmentShader;
|
|
||||||
protected GLuint program;
|
|
||||||
protected bool initialized;
|
|
||||||
protected bool error;
|
|
||||||
protected string glslversion;
|
|
||||||
this() {
|
|
||||||
}
|
|
||||||
private GLuint compileShader(string src, GLuint type) {
|
|
||||||
import core.stdc.stdlib;
|
|
||||||
import std.string;
|
|
||||||
|
|
||||||
Log.d("compileShader glsl=", glslversion, " code: ", src);
|
|
||||||
|
|
||||||
GLuint shader = glCreateShader(type);//GL_VERTEX_SHADER
|
|
||||||
const char * psrc = src.toStringz;
|
|
||||||
GLuint len = cast(uint)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() {
|
|
||||||
glslversion = cast(string)std.string.fromStringz(glGetString(GL_SHADING_LANGUAGE_VERSION));
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
Log.d("Program compiled successfully");
|
|
||||||
//glDetachShader(program, vertexShader);
|
|
||||||
//glDetachShader(program, fragmentShader);
|
|
||||||
glUseProgram(program);
|
|
||||||
checkError("glUseProgram " ~ to!string(program));
|
|
||||||
if (!initLocations()) {
|
|
||||||
Log.e("some of locations were not found");
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
initialized = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool initLocations() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool bind() {
|
|
||||||
if (!initialized)
|
|
||||||
return false;
|
|
||||||
if (!glIsProgram(program))
|
|
||||||
Log.e("!glIsProgram(program)");
|
|
||||||
glUseProgram(program);
|
|
||||||
checkError("glUseProgram " ~ to!string(program));
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
immutable string HIGHP = "";
|
|
||||||
immutable string LOWP = "";
|
|
||||||
immutable string MEDIUMP = "";
|
|
||||||
|
|
||||||
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
|
|
||||||
"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("glDisable(GL_CULL_FACE)");
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
||||||
checkError("glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)");
|
|
||||||
bind();
|
|
||||||
//glUniformMatrix4fv(matrixLocation, 1, false, m.value_ptr);
|
|
||||||
//glUniformMatrix4fv(matrixLocation, 1, false, matrix.ptr);
|
|
||||||
glUniformMatrix4fv(matrixLocation, 1, false, qtmatrix.ptr);
|
|
||||||
checkError("glUniformMatrix4fv");
|
|
||||||
}
|
|
||||||
|
|
||||||
void afterExecute() {
|
|
||||||
release();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected GLint matrixLocation;
|
|
||||||
protected GLint vertexLocation;
|
|
||||||
protected GLint colAttrLocation;
|
|
||||||
protected GLuint vertexBuffer;
|
|
||||||
protected GLuint colAttrBuffer;
|
|
||||||
override bool initLocations() {
|
|
||||||
bool res = super.initLocations();
|
|
||||||
|
|
||||||
//glGenBuffers(1, &vertexBuffer);
|
|
||||||
//glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
|
||||||
//glBufferData(GL_ARRAY_BUFFER, float.sizeof * 3 * 6, null, GL_DYNAMIC_DRAW);
|
|
||||||
//glGenBuffers(1, &colAttrBuffer);
|
|
||||||
//glBindBuffer(GL_ARRAY_BUFFER, colAttrBuffer);
|
|
||||||
//glBufferData(GL_ARRAY_BUFFER, float.sizeof * 4 * 6, null, GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
matrixLocation = glGetUniformLocation(program, "matrix");
|
|
||||||
checkError("glGetUniformLocation matrix");
|
|
||||||
vertexLocation = glGetAttribLocation(program, "vertex");
|
|
||||||
checkError("glGetAttribLocation vertex");
|
|
||||||
colAttrLocation = glGetAttribLocation(program, "colAttr");
|
|
||||||
checkError("glGetAttribLocation 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();
|
|
||||||
|
|
||||||
GLuint vao;
|
|
||||||
glGenVertexArrays(1, &vao);
|
|
||||||
glBindVertexArray(vao);
|
|
||||||
|
|
||||||
GLuint vbo;
|
|
||||||
glGenBuffers(1, &vbo);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
glBufferData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
vertices.length * vertices[0].sizeof + colors.length * colors[0].sizeof,
|
|
||||||
null,
|
|
||||||
GL_STREAM_DRAW);
|
|
||||||
glBufferSubData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
0,
|
|
||||||
vertices.length * vertices[0].sizeof,
|
|
||||||
vertices.ptr);
|
|
||||||
glBufferSubData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
vertices.length * vertices[0].sizeof,
|
|
||||||
colors.length * colors[0].sizeof, colors.ptr);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(vertexLocation);
|
|
||||||
checkError("glEnableVertexAttribArray");
|
|
||||||
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cast(void*) 0);
|
|
||||||
checkError("glVertexAttribPointer");
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(colAttrLocation);
|
|
||||||
checkError("glEnableVertexAttribArray");
|
|
||||||
glVertexAttribPointer(colAttrLocation, 4, GL_FLOAT, GL_FALSE, 0, cast(void*) (float.sizeof*3*6));
|
|
||||||
checkError("glVertexAttribPointer");
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
||||||
checkError("glDrawArrays");
|
|
||||||
|
|
||||||
glDisableVertexAttribArray(vertexLocation);
|
|
||||||
checkError("glDisableVertexAttribArray");
|
|
||||||
glDisableVertexAttribArray(colAttrLocation);
|
|
||||||
checkError("glDisableVertexAttribArray");
|
|
||||||
|
|
||||||
afterExecute();
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glDeleteBuffers(1, &vbo);
|
|
||||||
|
|
||||||
glBindVertexArray(0);
|
|
||||||
glDeleteVertexArrays(1, &vao);
|
|
||||||
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");
|
|
||||||
|
|
||||||
GLuint vao;
|
|
||||||
glGenVertexArrays(1, &vao);
|
|
||||||
glBindVertexArray(vao);
|
|
||||||
|
|
||||||
GLuint vbo;
|
|
||||||
glGenBuffers(1, &vbo);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
glBufferData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
vertices.length * vertices[0].sizeof +
|
|
||||||
colors.length * colors[0].sizeof +
|
|
||||||
texcoords.length * texcoords[0].sizeof,
|
|
||||||
null,
|
|
||||||
GL_STREAM_DRAW);
|
|
||||||
glBufferSubData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
0,
|
|
||||||
vertices.length * vertices[0].sizeof,
|
|
||||||
vertices.ptr);
|
|
||||||
glBufferSubData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
vertices.length * vertices[0].sizeof,
|
|
||||||
colors.length * colors[0].sizeof,
|
|
||||||
colors.ptr);
|
|
||||||
glBufferSubData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
vertices.length * vertices[0].sizeof + colors.length * colors[0].sizeof,
|
|
||||||
texcoords.length * texcoords[0].sizeof,
|
|
||||||
texcoords.ptr);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(vertexLocation);
|
|
||||||
glEnableVertexAttribArray(colAttrLocation);
|
|
||||||
glEnableVertexAttribArray(texCoordLocation);
|
|
||||||
|
|
||||||
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cast(void*) 0);
|
|
||||||
glVertexAttribPointer(colAttrLocation, 4, GL_FLOAT, GL_FALSE, 0, cast(void*) (vertices.length * vertices[0].sizeof));
|
|
||||||
glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, cast(void*) (vertices.length * vertices[0].sizeof + colors.length * colors[0].sizeof));
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
||||||
checkError("glDrawArrays");
|
|
||||||
|
|
||||||
glDisableVertexAttribArray(vertexLocation);
|
|
||||||
glDisableVertexAttribArray(colAttrLocation);
|
|
||||||
glDisableVertexAttribArray(texCoordLocation);
|
|
||||||
|
|
||||||
afterExecute();
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glDeleteBuffers(1, &vbo);
|
|
||||||
|
|
||||||
glBindVertexArray(0);
|
|
||||||
glDeleteVertexArrays(1, &vao);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool uninitShaders() {
|
|
||||||
Log.d("Uniniting shaders");
|
|
||||||
if (_textureProgram !is null) {
|
|
||||||
destroy(_textureProgram);
|
|
||||||
_textureProgram = null;
|
|
||||||
}
|
|
||||||
if (_solidFillProgram !is null) {
|
|
||||||
destroy(_solidFillProgram);
|
|
||||||
_solidFillProgram = null;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isTexture(uint textureId) {
|
|
||||||
return glIsTexture(textureId) == GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRotation(int x, int y, int rotationAngle) {
|
|
||||||
/*
|
|
||||||
this->rotationAngle = rotationAngle;
|
|
||||||
rotationX = x;
|
|
||||||
rotationY = y;
|
|
||||||
if (!currentFramebufferId) {
|
|
||||||
rotationY = bufferDy - rotationY;
|
|
||||||
}
|
|
||||||
|
|
||||||
QMatrix4x4 matrix2;
|
|
||||||
matrix2.ortho(0, bufferDx, 0, bufferDy, 0.5f, 5.0f);
|
|
||||||
if (rotationAngle) {
|
|
||||||
matrix2.translate(rotationX, rotationY, 0);
|
|
||||||
matrix2.rotate(rotationAngle, 0, 0, 1);
|
|
||||||
matrix2.translate(-rotationX, -rotationY, 0);
|
|
||||||
}
|
|
||||||
matrix2.copyDataTo(m);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
|
@ -97,6 +97,8 @@ class SDLWindow : Window {
|
||||||
version(USE_OPENGL) {
|
version(USE_OPENGL) {
|
||||||
if (_enableOpengl)
|
if (_enableOpengl)
|
||||||
windowFlags |= SDL_WINDOW_OPENGL;
|
windowFlags |= SDL_WINDOW_OPENGL;
|
||||||
|
if (!_glSupport)
|
||||||
|
_glSupport = new GLSupport();
|
||||||
}
|
}
|
||||||
_win = SDL_CreateWindow(toUTF8(_caption).toStringz, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
_win = SDL_CreateWindow(toUTF8(_caption).toStringz, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||||
700, 500,
|
700, 500,
|
||||||
|
@ -127,7 +129,7 @@ class SDLWindow : Window {
|
||||||
} else if (!_gl3Reloaded) {
|
} else if (!_gl3Reloaded) {
|
||||||
DerelictGL3.reload();
|
DerelictGL3.reload();
|
||||||
_gl3Reloaded = true;
|
_gl3Reloaded = true;
|
||||||
if (!initShaders())
|
if (!glSupport.valid && !glSupport.initShaders())
|
||||||
_enableOpengl = false;
|
_enableOpengl = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,10 +154,12 @@ version (USE_OPENGL) {
|
||||||
|
|
||||||
class Win32Window : Window {
|
class Win32Window : Window {
|
||||||
Win32Platform _platform;
|
Win32Platform _platform;
|
||||||
|
|
||||||
HWND _hwnd;
|
HWND _hwnd;
|
||||||
version (USE_OPENGL) {
|
version (USE_OPENGL) {
|
||||||
HGLRC _hGLRC; // opengl context
|
HGLRC _hGLRC; // opengl context
|
||||||
HPALETTE _hPalette;
|
HPALETTE _hPalette;
|
||||||
|
GLSupport _gl;
|
||||||
}
|
}
|
||||||
dstring _caption;
|
dstring _caption;
|
||||||
Win32ColorDrawBuf _drawbuf;
|
Win32ColorDrawBuf _drawbuf;
|
||||||
|
@ -167,6 +169,7 @@ class Win32Window : Window {
|
||||||
Win32Window w32parent = cast(Win32Window)parent;
|
Win32Window w32parent = cast(Win32Window)parent;
|
||||||
HWND parenthwnd = w32parent ? w32parent._hwnd : null;
|
HWND parenthwnd = w32parent ? w32parent._hwnd : null;
|
||||||
_platform = platform;
|
_platform = platform;
|
||||||
|
_gl = new GLSupport();
|
||||||
_caption = windowCaption;
|
_caption = windowCaption;
|
||||||
_flags = flags;
|
_flags = flags;
|
||||||
uint ws = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
uint ws = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||||
|
@ -199,7 +202,9 @@ class Win32Window : Window {
|
||||||
_hPalette = setupPalette(hDC);
|
_hPalette = setupPalette(hDC);
|
||||||
_hGLRC = wglCreateContext(hDC);
|
_hGLRC = wglCreateContext(hDC);
|
||||||
if (_hGLRC) {
|
if (_hGLRC) {
|
||||||
|
|
||||||
wglMakeCurrent(hDC, _hGLRC);
|
wglMakeCurrent(hDC, _hGLRC);
|
||||||
|
_glSupport = _gl;
|
||||||
|
|
||||||
if (!DERELICT_GL3_RELOADED) {
|
if (!DERELICT_GL3_RELOADED) {
|
||||||
// run this code only once
|
// run this code only once
|
||||||
|
@ -208,7 +213,7 @@ class Win32Window : Window {
|
||||||
import derelict.opengl3.gl3;
|
import derelict.opengl3.gl3;
|
||||||
DerelictGL3.reload();
|
DerelictGL3.reload();
|
||||||
// successful
|
// successful
|
||||||
if (initShaders()) {
|
if (glSupport.initShaders()) {
|
||||||
setOpenglEnabled();
|
setOpenglEnabled();
|
||||||
useOpengl = true;
|
useOpengl = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -218,7 +223,7 @@ class Win32Window : Window {
|
||||||
Log.e("Derelict exception", e);
|
Log.e("Derelict exception", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (initShaders()) {
|
if (glSupport.initShaders()) {
|
||||||
setOpenglEnabled();
|
setOpenglEnabled();
|
||||||
useOpengl = true;
|
useOpengl = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -252,6 +257,7 @@ class Win32Window : Window {
|
||||||
//scope(exit) EndPaint(_hwnd, &ps);
|
//scope(exit) EndPaint(_hwnd, &ps);
|
||||||
HDC hdc = GetDC(_hwnd);
|
HDC hdc = GetDC(_hwnd);
|
||||||
wglMakeCurrent(hdc, _hGLRC);
|
wglMakeCurrent(hdc, _hGLRC);
|
||||||
|
_glSupport = _gl;
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glViewport(0, 0, _dx, _dy);
|
glViewport(0, 0, _dx, _dy);
|
||||||
float a = 1.0f;
|
float a = 1.0f;
|
||||||
|
@ -288,7 +294,10 @@ class Win32Window : Window {
|
||||||
version (USE_OPENGL) {
|
version (USE_OPENGL) {
|
||||||
import derelict.opengl3.wgl;
|
import derelict.opengl3.wgl;
|
||||||
if (_hGLRC) {
|
if (_hGLRC) {
|
||||||
uninitShaders();
|
glSupport.uninitShaders();
|
||||||
|
delete _glSupport;
|
||||||
|
_glSupport = null;
|
||||||
|
_gl = null;
|
||||||
wglMakeCurrent (null, null) ;
|
wglMakeCurrent (null, null) ;
|
||||||
wglDeleteContext(_hGLRC);
|
wglDeleteContext(_hGLRC);
|
||||||
_hGLRC = null;
|
_hGLRC = null;
|
||||||
|
@ -470,7 +479,7 @@ class Win32Window : Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
void onPaint() {
|
void onPaint() {
|
||||||
Log.d("onPaint()");
|
debug(DebugRedraw) Log.d("onPaint()");
|
||||||
long paintStart = currentTimeMillis;
|
long paintStart = currentTimeMillis;
|
||||||
version (USE_OPENGL) {
|
version (USE_OPENGL) {
|
||||||
if (useOpengl && _hGLRC) {
|
if (useOpengl && _hGLRC) {
|
||||||
|
@ -482,7 +491,7 @@ class Win32Window : Window {
|
||||||
paintUsingGDI();
|
paintUsingGDI();
|
||||||
}
|
}
|
||||||
long paintEnd = currentTimeMillis;
|
long paintEnd = currentTimeMillis;
|
||||||
Log.d("WM_PAINT handling took ", paintEnd - paintStart, " ms");
|
debug(DebugRedraw) Log.d("WM_PAINT handling took ", paintEnd - paintStart, " ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ButtonDetails _lbutton;
|
protected ButtonDetails _lbutton;
|
||||||
|
|
Loading…
Reference in New Issue