Merge pull request #116 from g4z3r/master

refactoring in glsupport.d
This commit is contained in:
Vadim Lopatin 2015-12-12 19:20:00 +03:00
commit 3cc896dcac
2 changed files with 254 additions and 406 deletions

View File

@ -105,8 +105,8 @@ class GLDrawBuf : DrawBuf, GLConfigCallback {
if (!isFullyTransparentColor(color) && applyClipping(rc))
_scene.add(new SolidRectSceneItem(rc, color));
}
/// draw pixel at (x, y) with specified color
override void drawPixel(int x, int y, uint color) {
/// draw pixel at (x, y) with specified color
override void drawPixel(int x, int y, uint color) {
assert(_scene !is null);
if (!_clipRect.isPointInside(x, y))
return;
@ -114,7 +114,7 @@ class GLDrawBuf : DrawBuf, GLConfigCallback {
if (isFullyTransparentColor(color))
return;
_scene.add(new SolidRectSceneItem(Rect(x, y, x + 1, y + 1), color));
}
}
/// draw 8bit alpha image - usually font glyph using specified color (clipping is applied)
override void drawGlyph(int x, int y, Glyph * glyph, uint color) {
assert(_scene !is null);
@ -280,7 +280,7 @@ private class GLImageCache {
private GLImageCachePage _page;
@property GLImageCachePage page() { return _page; }
uint _objectId;
Rect _rc;
bool _deleted;
@ -298,7 +298,7 @@ private class GLImageCache {
private int _x;
private bool _closed;
private bool _needUpdateTexture;
private uint _textureId;
private Tex2D _texture;
private int _itemCount;
this(GLImageCache cache, int dx, int dy) {
@ -314,26 +314,26 @@ private class GLImageCache {
destroy(_drawbuf);
_drawbuf = null;
}
if (_textureId != 0) {
glSupport.deleteTexture(_textureId);
_textureId = 0;
if (_texture.ID != 0) {
destroy(_texture);
_texture = null;
}
}
void updateTexture() {
if (_drawbuf is null)
return; // no draw buffer!!!
if (_textureId == 0) {
_textureId = glSupport.genTexture();
Log.d("updateTexture - new texture id=", _textureId);
if (!_textureId)
if (_texture is null || _texture.ID == 0) {
_texture = new Tex2D();
Log.d("updateTexture - new texture id=", _texture.ID);
if (!_texture.ID)
return;
}
Log.d("updateTexture for image cache page - setting image ", _drawbuf.width, "x", _drawbuf.height, " tx=", _textureId);
Log.d("updateTexture for image cache page - setting image ", _drawbuf.width, "x", _drawbuf.height, " tx=", _texture.ID);
uint * pixels = _drawbuf.scanLine(0);
if (!glSupport.setTextureImage(_textureId, _drawbuf.width, _drawbuf.height, cast(ubyte*)pixels)) {
glSupport.deleteTexture(_textureId);
_textureId = 0;
if (!glSupport.setTextureImage(_texture, _drawbuf.width, _drawbuf.height, cast(ubyte*)pixels)) {
destroy(_texture);
_texture = null;
return;
}
_needUpdateTexture = false;
@ -409,11 +409,7 @@ private class GLImageCache {
//CRLog::trace("drawing item at %d,%d %dx%d <= %d,%d %dx%d ", x, y, dx, dy, srcx, srcy, srcdx, srcdy);
if (_needUpdateTexture)
updateTexture();
if (_textureId != 0) {
if (!glSupport.isTexture(_textureId)) {
Log.e("Invalid texture ", _textureId);
return;
}
if (_texture.ID != 0) {
//rotationAngle = 0;
int rx = dstrc.middlex;
int ry = dstrc.middley;
@ -442,8 +438,8 @@ private class GLImageCache {
dstrc.bottom -= clip.bottom;
}
if (!dstrc.empty)
glSupport.drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, srcrc.width() != dstrc.width() || srcrc.height() != dstrc.height());
//drawColorAndTextureRect(vertices, texcoords, color, _textureId);
glSupport.drawColorAndTextureRect(_texture, _tdx, _tdy, srcrc, dstrc, color, srcrc.width() != dstrc.width() || srcrc.height() != dstrc.height());
//drawColorAndTextureRect(vertices, texcoords, color, _texture);
if (rotationAngle) {
// unset rotation
@ -482,7 +478,7 @@ private class GLImageCache {
private void updateTextureSize() {
if (!tdx) {
// TODO
tdx = tdy = 1024; //getMaxTextureSize();
tdx = tdy = 1024; //getMaxTextureSize();
if (tdx > 1024)
tdx = tdy = 1024;
}
@ -627,7 +623,7 @@ private class GLGlyphCache {
private int _x;
private bool _closed;
private bool _needUpdateTexture;
private uint _textureId;
private Tex2D _texture;
private int _itemCount;
this(GLGlyphCache cache, int dx, int dy) {
@ -643,26 +639,26 @@ private class GLGlyphCache {
destroy(_drawbuf);
_drawbuf = null;
}
if (_textureId != 0) {
glSupport.deleteTexture(_textureId);
_textureId = 0;
if (_texture.ID != 0) {
destroy(_texture);
_texture = null;
}
}
void updateTexture() {
if (_drawbuf is null)
return; // no draw buffer!!!
if (_textureId == 0) {
_textureId = glSupport.genTexture();
//Log.d("updateTexture - new texture ", _textureId);
if (!_textureId)
if (_texture is null || _texture.ID == 0) {
_texture = new Tex2D();
//Log.d("updateTexture - new texture ", _texture.ID);
if (!_texture.ID)
return;
}
//Log.d("updateTexture for font glyph page - setting image ", _drawbuf.width, "x", _drawbuf.height, " tx=", _textureId);
//Log.d("updateTexture for font glyph page - setting image ", _drawbuf.width, "x", _drawbuf.height, " tx=", _texture.ID);
int len = _drawbuf.width * _drawbuf.height;
if (!glSupport.setTextureImage(_textureId, _drawbuf.width, _drawbuf.height, cast(ubyte *)_drawbuf.scanLine(0))) {
glSupport.deleteTexture(_textureId);
_textureId = 0;
if (!glSupport.setTextureImage(_texture, _drawbuf.width, _drawbuf.height, cast(ubyte *)_drawbuf.scanLine(0))) {
destroy(_texture);
_texture = null;
return;
}
_needUpdateTexture = false;
@ -724,11 +720,7 @@ private class GLGlyphCache {
//CRLog::trace("drawing item at %d,%d %dx%d <= %d,%d %dx%d ", x, y, dx, dy, srcx, srcy, srcdx, srcdy);
if (_needUpdateTexture)
updateTexture();
if (_textureId != 0) {
if (!glSupport.isTexture(_textureId)) {
Log.e("Invalid texture ", _textureId);
return;
}
if (_texture.ID != 0) {
// convert coordinates to cached texture
srcrc.offset(item._rc.left, item._rc.top);
if (clip) {
@ -751,8 +743,8 @@ private class GLGlyphCache {
}
if (!dstrc.empty) {
//Log.d("drawing glyph with color ", color);
glSupport.drawColorAndTextureGlyphRect(_textureId, _tdx, _tdy, srcrc, dstrc, color);
//glSupport.drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, false);
glSupport.drawColorAndTextureGlyphRect(_texture, _tdx, _tdy, srcrc, dstrc, color);
//glSupport.drawColorAndTextureRect(_texture, _tdx, _tdy, srcrc, dstrc, color, false);
}
}
@ -782,7 +774,7 @@ private class GLGlyphCache {
private void updateTextureSize() {
if (!tdx) {
// TODO
tdx = tdy = 1024; //getMaxTextureSize();
tdx = tdy = 1024; //getMaxTextureSize();
if (tdx > 1024)
tdx = tdy = 1024;
}

View File

@ -31,12 +31,12 @@ import std.array;
derelict.util.exception.ShouldThrow gl3MissingSymFunc( string symName ) {
import std.algorithm : equal;
foreach(s; ["glGetError", "glShaderSource", "glCompileShader",
"glGetShaderiv", "glGetShaderInfoLog", "glGetString",
"glCreateProgram", "glUseProgram", "glDeleteProgram",
"glDeleteShader", "glEnable", "glDisable", "glBlendFunc",
"glUniformMatrix4fv", "glGetAttribLocation", "glGetUniformLocation",
"glGenVertexArrays", "glBindVertexArray", "glBufferData",
foreach(s; ["glGetError", "glShaderSource", "glCompileShader",
"glGetShaderiv", "glGetShaderInfoLog", "glGetString",
"glCreateProgram", "glUseProgram", "glDeleteProgram",
"glDeleteShader", "glEnable", "glDisable", "glBlendFunc",
"glUniformMatrix4fv", "glGetAttribLocation", "glGetUniformLocation",
"glGenVertexArrays", "glBindVertexArray", "glBufferData",
"glBindBuffer", "glBufferSubData"]) {
if (symName.equal(s)) // Symbol is used
return derelict.util.exception.ShouldThrow.Yes;
@ -74,7 +74,7 @@ static this() {
0x0507: "GL_CONTEXT_LOST"
];
}
/**
/**
* Convenient wrapper around glGetError()
* TODO use one of the DEBUG extensions instead
*/
@ -103,7 +103,7 @@ class GLProgram {
protected char[] glslversionString;
this() {
}
private void compatibilityFixes(ref char[] code, GLuint type) {
if (glslversionInt < 150) {
code = replace(code, " texture(", " texture2D(");
@ -111,7 +111,7 @@ class GLProgram {
code = replace(code, "out ", "");
}
}
private GLuint compileShader(string src, GLuint type) {
import core.stdc.stdlib;
import std.string;
@ -122,7 +122,7 @@ class GLProgram {
sourceCode ~= "\n";
sourceCode ~= src;
compatibilityFixes(sourceCode, type);
Log.d("compileShader glsl=", glslversion, " type:", (type == GL_VERTEX_SHADER ? "GL_VERTEX_SHADER" : (type == GL_FRAGMENT_SHADER ? "GL_FRAGMENT_SHADER" : "UNKNOWN")), " code:\n", sourceCode);
GLuint shader = glCreateShader(type);
const char * psrc = sourceCode.toStringz;
@ -134,15 +134,15 @@ class GLProgram {
// compiled successfully
return shader;
} else {
GLint blen = 0;
GLint blen = 0;
GLsizei slen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH , &blen);
glGetShaderiv(shader, GL_INFO_LOG_LENGTH , &blen);
if (blen > 1)
{
GLchar[] msg = new GLchar[blen + 1];
glGetShaderInfoLog(shader, blen, &slen, msg.ptr);
Log.d("Shader compilation error: ", fromStringz(msg.ptr));
}
}
return 0;
}
}
@ -260,12 +260,22 @@ class SolidFillProgram : GLProgram {
};
}
bool check()
{
if (error)
return false;
if (!initialized)
if (!compile())
return false;
return true;
}
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);
//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);
@ -281,18 +291,9 @@ class SolidFillProgram : GLProgram {
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");
if (matrixLocation == -1)
@ -309,121 +310,62 @@ class SolidFillProgram : GLProgram {
}
bool execute(float[] vertices, float[] colors) {
if (error)
if(!check())
return false;
if (!initialized)
if (!compile())
return false;
beforeExecute();
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
VAO vao = new 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);
VBO vbo = new VBO();
vbo.fill([vertices, colors]);
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));
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);
glDrawArrays(GL_TRIANGLES, 0, cast(int)vertices.length/3);
checkError("glDrawArrays");
glDisableVertexAttribArray(vertexLocation);
checkError("glDisableVertexAttribArray");
glDisableVertexAttribArray(colAttrLocation);
checkError("glDisableVertexAttribArray");
afterExecute();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &vbo);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vao);
destroy(vbo);
destroy(vao);
return true;
}
}
class LineProgram : SolidFillProgram {
override bool execute(float[] vertices, float[] colors) {
if (error)
if(!check())
return false;
if (!initialized)
if (!compile())
return false;
beforeExecute();
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
VAO vao = new 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);
VBO vbo = new VBO();
vbo.fill([vertices, colors]);
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));
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*2));
checkError("glVertexAttribPointer");
glDrawArrays(GL_LINES, 0, 2);
glDrawArrays(GL_LINES, 0, cast(int)vertices.length/3);
checkError("glDrawArrays");
glDisableVertexAttribArray(vertexLocation);
checkError("glDisableVertexAttribArray");
glDisableVertexAttribArray(colAttrLocation);
checkError("glDisableVertexAttribArray");
afterExecute();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &vbo);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vao);
destroy(vbo);
destroy(vao);
return true;
}
}
@ -466,61 +408,28 @@ class TextureProgram : SolidFillProgram {
return res && texCoordLocation >= 0;
}
bool execute(float[] vertices, float[] texcoords, float[] colors, uint textureId, bool linear) {
if (error)
bool execute(float[] vertices, float[] texcoords, float[] colors, Tex2D texture, bool linear) {
if(!check())
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);
texture.setup();
texture.setSamplerParams(linear);
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);
VAO vao = new VAO();
glEnableVertexAttribArray(vertexLocation);
glEnableVertexAttribArray(colAttrLocation);
glEnableVertexAttribArray(texCoordLocation);
VBO vbo = new VBO();
vbo.fill([vertices, colors, texcoords]);
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);
glEnableVertexAttribArray(vertexLocation);
glEnableVertexAttribArray(colAttrLocation);
glEnableVertexAttribArray(texCoordLocation);
glDrawArrays(GL_TRIANGLES, 0, cast(int)vertices.length/3);
checkError("glDrawArrays");
glDisableVertexAttribArray(vertexLocation);
@ -529,14 +438,10 @@ class TextureProgram : SolidFillProgram {
afterExecute();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &vbo);
destroy(vbo);
destroy(vao);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vao);
glBindTexture(GL_TEXTURE_2D, 0);
checkError("glBindTexture");
texture.unbind();
return true;
}
}
@ -599,61 +504,28 @@ class FontProgram : SolidFillProgram {
super.afterExecute();
}
bool execute(float[] vertices, float[] texcoords, float[] colors, uint textureId, bool linear) {
if (error)
bool execute(float[] vertices, float[] texcoords, float[] colors, Tex2D texture, bool linear) {
if(!check())
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);
texture.setup();
texture.setSamplerParams(linear);
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);
VAO vao = new VAO();
glEnableVertexAttribArray(vertexLocation);
glEnableVertexAttribArray(colAttrLocation);
glEnableVertexAttribArray(texCoordLocation);
VBO vbo = new VBO();
vbo.fill([vertices, colors, texcoords]);
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);
glEnableVertexAttribArray(vertexLocation);
glEnableVertexAttribArray(colAttrLocation);
glEnableVertexAttribArray(texCoordLocation);
glDrawArrays(GL_TRIANGLES, 0, cast(int)vertices.length/3);
checkError("glDrawArrays");
glDisableVertexAttribArray(vertexLocation);
@ -662,14 +534,10 @@ class FontProgram : SolidFillProgram {
afterExecute();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &vbo);
destroy(vbo);
destroy(vao);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vao);
glBindTexture(GL_TEXTURE_2D, 0);
checkError("glBindTexture");
texture.unbind();
return true;
}
}
@ -754,10 +622,6 @@ class GLSupport {
return true;
}
bool isTexture(uint textureId) {
return glIsTexture(textureId) == GL_TRUE;
}
void setRotation(int x, int y, int rotationAngle) {
/*
this->rotationAngle = rotationAngle;
@ -788,7 +652,7 @@ class GLSupport {
float y1 = cast(float)(bufferDy-p2.y);
// don't flip for framebuffer
if (currentFramebufferId) {
if (currentFBO) {
y0 = cast(float)(p1.y);
y1 = cast(float)(p2.y);
}
@ -819,7 +683,7 @@ class GLSupport {
float y1 = cast(float)(bufferDy-rc.bottom);
// don't flip for framebuffer
if (currentFramebufferId) {
if (currentFBO) {
y0 = cast(float)(rc.top);
y1 = cast(float)(rc.bottom);
}
@ -847,10 +711,10 @@ class GLSupport {
checkError("glVertexPointer(3, GL_FLOAT, 0, vertices)");
glColorPointer(4, GL_FLOAT, 0, cast(void*)colors);
checkError("glColorPointer(4, GL_FLOAT, 0, colors)");
glDrawArrays(GL_TRIANGLES, 0, 6);
checkError("glDrawArrays(GL_TRIANGLES, 0, 6)");
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_ALPHA_TEST);
@ -864,12 +728,12 @@ class GLSupport {
}
}
void drawColorAndTextureGlyphRect(uint textureId, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color) {
//Log.v("drawColorAndGlyphRect tx=", textureId, " src=", srcrc, " dst=", dstrc);
drawColorAndTextureGlyphRect(textureId, tdx, tdy, srcrc.left, srcrc.top, srcrc.width(), srcrc.height(), dstrc.left, dstrc.top, dstrc.width(), dstrc.height(), color);
void drawColorAndTextureGlyphRect(Tex2D texture, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color) {
//Log.v("drawColorAndGlyphRect tx=", texture.ID, " src=", srcrc, " dst=", dstrc);
drawColorAndTextureGlyphRect(texture, tdx, tdy, srcrc.left, srcrc.top, srcrc.width(), srcrc.height(), dstrc.left, dstrc.top, dstrc.width(), dstrc.height(), color);
}
void drawColorAndTextureGlyphRect(uint textureId, int tdx, int tdy, int srcx, int srcy, int srcdx, int srcdy, int xx, int yy, int dx, int dy, uint color) {
void drawColorAndTextureGlyphRect(Tex2D texture, int tdx, int tdy, int srcx, int srcy, int srcdx, int srcdy, int xx, int yy, int dx, int dy, uint color) {
float[6*4] colors;
LVGLFillColor(color, colors.ptr, 6);
float dstx0 = cast(float)xx;
@ -878,7 +742,7 @@ class GLSupport {
float dsty1 = cast(float)(bufferDy - (yy + dy));
// don't flip for framebuffer
if (currentFramebufferId) {
if (currentFBO) {
dsty0 = cast(float)((yy));
dsty1 = cast(float)((yy + dy));
}
@ -887,7 +751,7 @@ class GLSupport {
float srcy0 = srcy / cast(float)tdy;
float srcx1 = (srcx + srcdx) / cast(float)tdx;
float srcy1 = (srcy + srcdy) / cast(float)tdy;
float[3 * 6] vertices =
float[3 * 6] vertices =
[dstx0, dsty0, Z_2D,
dstx0, dsty1, Z_2D,
dstx1, dsty1, Z_2D,
@ -899,24 +763,17 @@ class GLSupport {
if (_legacyMode) {
bool linear = dx != srcdx || dy != srcdy;
glDisable(GL_CULL_FACE);
glActiveTexture(GL_TEXTURE0);
checkError("glActiveTexture");
glEnable(GL_TEXTURE_2D);
checkError("glEnable(GL_TEXTURE_2D)");
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");
texture.setup();
texture.setSamplerParams(linear);
glColor4f(1,1,1,1);
glDisable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
checkError("glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)");
glEnableClientState(GL_COLOR_ARRAY);
checkError("glEnableClientState(GL_COLOR_ARRAY)");
glEnableClientState(GL_VERTEX_ARRAY);
@ -929,10 +786,10 @@ class GLSupport {
checkError("glTexCoordPointer(2, GL_FLOAT, 0, texcoords)");
glColorPointer(4, GL_FLOAT, 0, cast(void*)colors.ptr);
checkError("glColorPointer(4, GL_FLOAT, 0, colors)");
glDrawArrays(GL_TRIANGLES, 0, 6);
checkError("glDrawArrays");
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
@ -940,17 +797,17 @@ class GLSupport {
glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);
} else {
_fontProgram.execute(vertices, texcoords, colors, textureId, false);
_fontProgram.execute(vertices, texcoords, colors, texture, false);
}
//drawColorAndTextureRect(vertices, texcoords, colors, textureId, linear);
//drawColorAndTextureRect(vertices, texcoords, colors, texture, linear);
}
void drawColorAndTextureRect(uint textureId, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color, bool linear) {
//Log.v("drawColorAndTextureRect tx=", textureId, " src=", srcrc, " dst=", dstrc);
drawColorAndTextureRect(textureId, tdx, tdy, srcrc.left, srcrc.top, srcrc.width(), srcrc.height(), dstrc.left, dstrc.top, dstrc.width(), dstrc.height(), color, linear);
void drawColorAndTextureRect(Tex2D texture, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color, bool linear) {
//Log.v("drawColorAndTextureRect tx=", texture.ID, " src=", srcrc, " dst=", dstrc);
drawColorAndTextureRect(texture, tdx, tdy, srcrc.left, srcrc.top, srcrc.width(), srcrc.height(), dstrc.left, dstrc.top, dstrc.width(), dstrc.height(), color, linear);
}
void drawColorAndTextureRect(uint textureId, int tdx, int tdy, int srcx, int srcy, int srcdx, int srcdy, int xx, int yy, int dx, int dy, uint color, bool linear) {
void drawColorAndTextureRect(Tex2D texture, int tdx, int tdy, int srcx, int srcy, int srcdx, int srcdy, int xx, int yy, int dx, int dy, uint color, bool linear) {
float[6*4] colors;
LVGLFillColor(color, colors.ptr, 6);
float dstx0 = cast(float)xx;
@ -959,7 +816,7 @@ class GLSupport {
float dsty1 = cast(float)(bufferDy - (yy + dy));
// don't flip for framebuffer
if (currentFramebufferId) {
if (currentFBO) {
dsty0 = cast(float)((yy));
dsty1 = cast(float)((yy + dy));
}
@ -978,24 +835,17 @@ class GLSupport {
if (_legacyMode) {
glDisable(GL_CULL_FACE);
glActiveTexture(GL_TEXTURE0);
checkError("glActiveTexture");
glEnable(GL_TEXTURE_2D);
checkError("glEnable(GL_TEXTURE_2D)");
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");
texture.setup();
texture.setSamplerParams(linear);
glColor4f(1,1,1,1);
glDisable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
checkError("glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)");
glEnableClientState(GL_COLOR_ARRAY);
checkError("glEnableClientState(GL_COLOR_ARRAY)");
glEnableClientState(GL_VERTEX_ARRAY);
@ -1008,10 +858,10 @@ class GLSupport {
checkError("glTexCoordPointer(2, GL_FLOAT, 0, texcoords)");
glColorPointer(4, GL_FLOAT, 0, cast(void*)colors.ptr);
checkError("glColorPointer(4, GL_FLOAT, 0, colors)");
glDrawArrays(GL_TRIANGLES, 0, 6);
checkError("glDrawArrays");
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
@ -1019,30 +869,9 @@ class GLSupport {
glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);
} else {
_textureProgram.execute(vertices, texcoords, colors, textureId, linear);
_textureProgram.execute(vertices, texcoords, colors, texture, linear);
}
//drawColorAndTextureRect(vertices, texcoords, colors, textureId, linear);
}
/// 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;
//drawColorAndTextureRect(vertices, texcoords, colors, texture, linear);
}
/// call glFlush
@ -1051,32 +880,16 @@ class GLSupport {
checkError("glFlush");
}
bool setTextureImage(uint textureId, int dx, int dy, ubyte * pixels) {
bool setTextureImage(Tex2D texture, 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");
texture.setup();
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");
texture.setSamplerParams(true, true);
// 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) {
if (checkError("updateTexture - glTexImage2D")) {
Log.e("Cannot set image for texture");
return false;
}
@ -1084,72 +897,44 @@ class GLSupport {
return true;
}
bool setTextureImageAlpha(uint textureId, int dx, int dy, ubyte * pixels) {
bool setTextureImageAlpha(Tex2D texture, 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");
texture.setup();
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");
texture.setSamplerParams(true, true);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, dx, dy, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels);
checkError("setTextureImageAlpha - glTexImage2D");
if (glGetError() != GL_NO_ERROR) {
if (checkError("setTextureImageAlpha - glTexImage2D")) {
Log.e("Cannot set image for texture");
return false;
}
glBindTexture(GL_TEXTURE_2D, 0);
checkError("updateTexture - glBindTexture(0)");
texture.unbind();
checkError("after setTextureImageAlpha");
return true;
}
private uint currentFramebufferId;
private FBO currentFBO;
/// returns texture ID for buffer, 0 if failed
bool createFramebuffer(ref uint textureId, ref uint framebufferId, int dx, int dy) {
/// returns texture for buffer, null if failed
bool createFramebuffer(out Tex2D texture, out FBO fbo, int dx, int dy) {
checkError("before createFramebuffer");
bool res = true;
textureId = framebufferId = 0;
textureId = genTexture();
if (!textureId)
texture = new Tex2D();
if (!texture.ID)
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;
checkError("glBindTexture GL_TEXTURE_2D");
FBO f = new FBO();
if (!f.ID)
return false;
fbo = f;
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");
texture.setSamplerParams(true, true);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.ID, 0);
checkError("glFramebufferTexture2D");
// Always check that our framebuffer is ok
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
@ -1164,35 +949,26 @@ class GLSupport {
checkError("glClear");
checkError("after createFramebuffer");
//CRLog::trace("CRGLSupportImpl::createFramebuffer %d,%d texture=%d, buffer=%d", dx, dy, textureId, framebufferId);
currentFramebufferId = framebufferId;
currentFBO = fbo;
glBindTexture(GL_TEXTURE_2D, 0);
checkError("createFramebuffer - glBindTexture(0)");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
checkError("createFramebuffer - glBindFramebuffer(0)");
texture.unbind();
fbo.unbind();
return res;
}
void deleteFramebuffer(ref uint framebufferId) {
void deleteFramebuffer(ref FBO fbo) {
//CRLog::debug("GLDrawBuf::deleteFramebuffer");
if (framebufferId != 0) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
checkError("deleteFramebuffer - glBindFramebuffer");
GLuint fid = framebufferId;
glDeleteFramebuffers(1, &fid);
checkError("deleteFramebuffer - glDeleteFramebuffer");
if (fbo.ID != 0) {
destroy(fbo);
}
//CRLog::trace("CRGLSupportImpl::deleteFramebuffer(%d)", framebufferId);
framebufferId = 0;
checkError("after deleteFramebuffer");
currentFramebufferId = 0;
currentFBO = null;
}
bool bindFramebuffer(uint framebufferId) {
bool bindFramebuffer(FBO fbo) {
//CRLog::trace("CRGLSupportImpl::bindFramebuffer(%d)", framebufferId);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferId);
currentFramebufferId = framebufferId;
fbo.bind();
currentFBO = fbo;
return !checkError("glBindFramebuffer");
}
@ -1301,3 +1077,83 @@ class GLSupport {
}
}
enum GLObjectTypes { Buffer, VertexArray, Texture, Framebuffer };
class GLObject(GLObjectTypes type, GLuint target = 0) {
@property auto ID() const { return id; }
//alias ID this; // good, but it confuses destroy()
private GLuint id;
this() {
mixin("glGen" ~ to!string(type) ~ "s(1, &id);");
checkError("glGen" ~ to!string(type));
bind();
}
~this() {
unbind();
mixin("glDelete" ~ to!string(type) ~ "s(1, &id);");
checkError("glDelete" ~ to!string(type));
}
void bind() {
static if(target != 0)
mixin("glBind" ~ to!string(type) ~ "(" ~ to!string(target) ~ ", id);");
else
mixin("glBind" ~ to!string(type) ~ "(id);");
}
void unbind() {
static if(target != 0)
mixin("glBind" ~ to!string(type) ~ "(" ~ to!string(target) ~ ", 0);");
else
mixin("glBind" ~ to!string(type) ~ "(0);");
checkError("unbind " ~ to!string(type));
}
static if(type == GLObjectTypes.Buffer)
{
void fill(float[][] buffs) {
int length;
foreach(b; buffs)
length += b.length;
glBufferData(target,
length * float.sizeof,
null,
GL_STREAM_DRAW);
int offset;
foreach(b; buffs) {
glBufferSubData(target,
offset,
b.length * float.sizeof,
b.ptr);
offset += b.length * float.sizeof;
}
}
}
static if(type == GLObjectTypes.Texture)
{
void setSamplerParams(bool linear, bool clamp = false) {
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST);
checkError("filtering - glTexParameteri");
if(clamp) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
checkError("clamp - glTexParameteri");
}
}
void setup(GLuint binding = 0) {
glActiveTexture(GL_TEXTURE0 + binding);
glBindTexture(target, id);
checkError("setup texture");
}
}
}
alias VAO = GLObject!(GLObjectTypes.VertexArray);
alias VBO = GLObject!(GLObjectTypes.Buffer, GL_ARRAY_BUFFER);
alias Tex2D = GLObject!(GLObjectTypes.Texture, GL_TEXTURE_2D);
alias FBO = GLObject!(GLObjectTypes.Framebuffer, GL_FRAMEBUFFER);