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

View File

@ -260,6 +260,16 @@ class SolidFillProgram : GLProgram {
}; };
} }
bool check()
{
if (error)
return false;
if (!initialized)
if (!compile())
return false;
return true;
}
void beforeExecute() { void beforeExecute() {
glEnable(GL_BLEND); glEnable(GL_BLEND);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
@ -281,18 +291,9 @@ class SolidFillProgram : GLProgram {
protected GLint matrixLocation; protected GLint matrixLocation;
protected GLint vertexLocation; protected GLint vertexLocation;
protected GLint colAttrLocation; protected GLint colAttrLocation;
protected GLuint vertexBuffer;
protected GLuint colAttrBuffer;
override bool initLocations() { override bool initLocations() {
bool res = super.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"); matrixLocation = glGetUniformLocation(program, "matrix");
checkError("glGetUniformLocation matrix"); checkError("glGetUniformLocation matrix");
if (matrixLocation == -1) if (matrixLocation == -1)
@ -309,121 +310,62 @@ class SolidFillProgram : GLProgram {
} }
bool execute(float[] vertices, float[] colors) { bool execute(float[] vertices, float[] colors) {
if (error) if(!check())
return false; return false;
if (!initialized)
if (!compile())
return false;
beforeExecute(); beforeExecute();
GLuint vao; VAO vao = new VAO();
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo; VBO vbo = new VBO();
glGenBuffers(1, &vbo); vbo.fill([vertices, colors]);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData( glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cast(void*) 0);
GL_ARRAY_BUFFER, glVertexAttribPointer(colAttrLocation, 4, GL_FLOAT, GL_FALSE, 0, cast(void*) (vertices.length * vertices[0].sizeof));
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); glEnableVertexAttribArray(vertexLocation);
checkError("glEnableVertexAttribArray");
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cast(void*) 0);
checkError("glVertexAttribPointer");
glEnableVertexAttribArray(colAttrLocation); 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"); checkError("glDrawArrays");
glDisableVertexAttribArray(vertexLocation); glDisableVertexAttribArray(vertexLocation);
checkError("glDisableVertexAttribArray");
glDisableVertexAttribArray(colAttrLocation); glDisableVertexAttribArray(colAttrLocation);
checkError("glDisableVertexAttribArray");
afterExecute(); afterExecute();
glBindBuffer(GL_ARRAY_BUFFER, 0); destroy(vbo);
glDeleteBuffers(1, &vbo); destroy(vao);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vao);
return true; return true;
} }
} }
class LineProgram : SolidFillProgram { class LineProgram : SolidFillProgram {
override bool execute(float[] vertices, float[] colors) { override bool execute(float[] vertices, float[] colors) {
if (error) if(!check())
return false; return false;
if (!initialized)
if (!compile())
return false;
beforeExecute(); beforeExecute();
GLuint vao; VAO vao = new VAO();
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo; VBO vbo = new VBO();
glGenBuffers(1, &vbo); vbo.fill([vertices, colors]);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData( glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cast(void*) 0);
GL_ARRAY_BUFFER, glVertexAttribPointer(colAttrLocation, 4, GL_FLOAT, GL_FALSE, 0, cast(void*) (vertices.length * vertices[0].sizeof));
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); glEnableVertexAttribArray(vertexLocation);
checkError("glEnableVertexAttribArray");
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cast(void*) 0);
checkError("glVertexAttribPointer");
glEnableVertexAttribArray(colAttrLocation); 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"); checkError("glDrawArrays");
glDisableVertexAttribArray(vertexLocation); glDisableVertexAttribArray(vertexLocation);
checkError("glDisableVertexAttribArray");
glDisableVertexAttribArray(colAttrLocation); glDisableVertexAttribArray(colAttrLocation);
checkError("glDisableVertexAttribArray");
afterExecute(); afterExecute();
glBindBuffer(GL_ARRAY_BUFFER, 0); destroy(vbo);
glDeleteBuffers(1, &vbo); destroy(vao);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vao);
return true; return true;
} }
} }
@ -466,61 +408,28 @@ class TextureProgram : SolidFillProgram {
return res && texCoordLocation >= 0; return res && texCoordLocation >= 0;
} }
bool execute(float[] vertices, float[] texcoords, float[] colors, uint textureId, bool linear) { bool execute(float[] vertices, float[] texcoords, float[] colors, Tex2D texture, bool linear) {
if (error) if(!check())
return false; return false;
if (!initialized)
if (!compile())
return false;
beforeExecute(); 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; texture.setup();
glGenVertexArrays(1, &vao); texture.setSamplerParams(linear);
glBindVertexArray(vao);
GLuint vbo; VAO vao = new VAO();
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); VBO vbo = new VBO();
glEnableVertexAttribArray(colAttrLocation); vbo.fill([vertices, colors, texcoords]);
glEnableVertexAttribArray(texCoordLocation);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cast(void*) 0); 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(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)); 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"); checkError("glDrawArrays");
glDisableVertexAttribArray(vertexLocation); glDisableVertexAttribArray(vertexLocation);
@ -529,14 +438,10 @@ class TextureProgram : SolidFillProgram {
afterExecute(); afterExecute();
glBindBuffer(GL_ARRAY_BUFFER, 0); destroy(vbo);
glDeleteBuffers(1, &vbo); destroy(vao);
glBindVertexArray(0); texture.unbind();
glDeleteVertexArrays(1, &vao);
glBindTexture(GL_TEXTURE_2D, 0);
checkError("glBindTexture");
return true; return true;
} }
} }
@ -599,61 +504,28 @@ class FontProgram : SolidFillProgram {
super.afterExecute(); super.afterExecute();
} }
bool execute(float[] vertices, float[] texcoords, float[] colors, uint textureId, bool linear) { bool execute(float[] vertices, float[] texcoords, float[] colors, Tex2D texture, bool linear) {
if (error) if(!check())
return false; return false;
if (!initialized)
if (!compile())
return false;
beforeExecute(); 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; texture.setup();
glGenVertexArrays(1, &vao); texture.setSamplerParams(linear);
glBindVertexArray(vao);
GLuint vbo; VAO vao = new VAO();
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); VBO vbo = new VBO();
glEnableVertexAttribArray(colAttrLocation); vbo.fill([vertices, colors, texcoords]);
glEnableVertexAttribArray(texCoordLocation);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cast(void*) 0); 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(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)); 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"); checkError("glDrawArrays");
glDisableVertexAttribArray(vertexLocation); glDisableVertexAttribArray(vertexLocation);
@ -662,14 +534,10 @@ class FontProgram : SolidFillProgram {
afterExecute(); afterExecute();
glBindBuffer(GL_ARRAY_BUFFER, 0); destroy(vbo);
glDeleteBuffers(1, &vbo); destroy(vao);
glBindVertexArray(0); texture.unbind();
glDeleteVertexArrays(1, &vao);
glBindTexture(GL_TEXTURE_2D, 0);
checkError("glBindTexture");
return true; return true;
} }
} }
@ -754,10 +622,6 @@ class GLSupport {
return true; return true;
} }
bool isTexture(uint textureId) {
return glIsTexture(textureId) == GL_TRUE;
}
void setRotation(int x, int y, int rotationAngle) { void setRotation(int x, int y, int rotationAngle) {
/* /*
this->rotationAngle = rotationAngle; this->rotationAngle = rotationAngle;
@ -788,7 +652,7 @@ class GLSupport {
float y1 = cast(float)(bufferDy-p2.y); float y1 = cast(float)(bufferDy-p2.y);
// don't flip for framebuffer // don't flip for framebuffer
if (currentFramebufferId) { if (currentFBO) {
y0 = cast(float)(p1.y); y0 = cast(float)(p1.y);
y1 = cast(float)(p2.y); y1 = cast(float)(p2.y);
} }
@ -819,7 +683,7 @@ class GLSupport {
float y1 = cast(float)(bufferDy-rc.bottom); float y1 = cast(float)(bufferDy-rc.bottom);
// don't flip for framebuffer // don't flip for framebuffer
if (currentFramebufferId) { if (currentFBO) {
y0 = cast(float)(rc.top); y0 = cast(float)(rc.top);
y1 = cast(float)(rc.bottom); y1 = cast(float)(rc.bottom);
} }
@ -864,12 +728,12 @@ class GLSupport {
} }
} }
void drawColorAndTextureGlyphRect(uint textureId, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color) { void drawColorAndTextureGlyphRect(Tex2D texture, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color) {
//Log.v("drawColorAndGlyphRect tx=", textureId, " src=", srcrc, " dst=", dstrc); //Log.v("drawColorAndGlyphRect tx=", texture.ID, " 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); 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; float[6*4] colors;
LVGLFillColor(color, colors.ptr, 6); LVGLFillColor(color, colors.ptr, 6);
float dstx0 = cast(float)xx; float dstx0 = cast(float)xx;
@ -878,7 +742,7 @@ class GLSupport {
float dsty1 = cast(float)(bufferDy - (yy + dy)); float dsty1 = cast(float)(bufferDy - (yy + dy));
// don't flip for framebuffer // don't flip for framebuffer
if (currentFramebufferId) { if (currentFBO) {
dsty0 = cast(float)((yy)); dsty0 = cast(float)((yy));
dsty1 = cast(float)((yy + dy)); dsty1 = cast(float)((yy + dy));
} }
@ -899,16 +763,9 @@ class GLSupport {
if (_legacyMode) { if (_legacyMode) {
bool linear = dx != srcdx || dy != srcdy; bool linear = dx != srcdx || dy != srcdy;
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glActiveTexture(GL_TEXTURE0);
checkError("glActiveTexture");
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
checkError("glEnable(GL_TEXTURE_2D)"); texture.setup();
glBindTexture(GL_TEXTURE_2D, textureId); texture.setSamplerParams(linear);
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");
glColor4f(1,1,1,1); glColor4f(1,1,1,1);
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);
@ -940,17 +797,17 @@ class GLSupport {
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} else { } 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) { void drawColorAndTextureRect(Tex2D texture, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color, bool linear) {
//Log.v("drawColorAndTextureRect tx=", textureId, " src=", srcrc, " dst=", dstrc); //Log.v("drawColorAndTextureRect tx=", texture.ID, " 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); 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; float[6*4] colors;
LVGLFillColor(color, colors.ptr, 6); LVGLFillColor(color, colors.ptr, 6);
float dstx0 = cast(float)xx; float dstx0 = cast(float)xx;
@ -959,7 +816,7 @@ class GLSupport {
float dsty1 = cast(float)(bufferDy - (yy + dy)); float dsty1 = cast(float)(bufferDy - (yy + dy));
// don't flip for framebuffer // don't flip for framebuffer
if (currentFramebufferId) { if (currentFBO) {
dsty0 = cast(float)((yy)); dsty0 = cast(float)((yy));
dsty1 = cast(float)((yy + dy)); dsty1 = cast(float)((yy + dy));
} }
@ -978,16 +835,9 @@ class GLSupport {
if (_legacyMode) { if (_legacyMode) {
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glActiveTexture(GL_TEXTURE0);
checkError("glActiveTexture");
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
checkError("glEnable(GL_TEXTURE_2D)"); texture.setup();
glBindTexture(GL_TEXTURE_2D, textureId); texture.setSamplerParams(linear);
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");
glColor4f(1,1,1,1); glColor4f(1,1,1,1);
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);
@ -1019,30 +869,9 @@ class GLSupport {
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
} else { } else {
_textureProgram.execute(vertices, texcoords, colors, textureId, linear); _textureProgram.execute(vertices, texcoords, colors, texture, linear);
} }
//drawColorAndTextureRect(vertices, texcoords, colors, textureId, linear); //drawColorAndTextureRect(vertices, texcoords, colors, texture, 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;
} }
/// call glFlush /// call glFlush
@ -1051,32 +880,16 @@ class GLSupport {
checkError("glFlush"); 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"); //checkError("before setTextureImage");
glActiveTexture(GL_TEXTURE0); texture.setup();
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); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
checkError("updateTexture - glPixelStorei"); checkError("updateTexture - glPixelStorei");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); texture.setSamplerParams(true, true);
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); // 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); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dx, dy, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
checkError("updateTexture - glTexImage2D"); if (checkError("updateTexture - glTexImage2D")) {
if (glGetError() != GL_NO_ERROR) {
Log.e("Cannot set image for texture"); Log.e("Cannot set image for texture");
return false; return false;
} }
@ -1084,72 +897,44 @@ class GLSupport {
return true; 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"); checkError("before setTextureImageAlpha");
glActiveTexture(GL_TEXTURE0); texture.setup();
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); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
checkError("setTextureImageAlpha - glPixelStorei"); checkError("setTextureImageAlpha - glPixelStorei");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); texture.setSamplerParams(true, true);
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); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, dx, dy, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels);
checkError("setTextureImageAlpha - glTexImage2D"); if (checkError("setTextureImageAlpha - glTexImage2D")) {
if (glGetError() != GL_NO_ERROR) {
Log.e("Cannot set image for texture"); Log.e("Cannot set image for texture");
return false; return false;
} }
glBindTexture(GL_TEXTURE_2D, 0); texture.unbind();
checkError("updateTexture - glBindTexture(0)");
checkError("after setTextureImageAlpha"); checkError("after setTextureImageAlpha");
return true; return true;
} }
private uint currentFramebufferId; private FBO currentFBO;
/// returns texture ID for buffer, 0 if failed /// returns texture for buffer, null if failed
bool createFramebuffer(ref uint textureId, ref uint framebufferId, int dx, int dy) { bool createFramebuffer(out Tex2D texture, out FBO fbo, int dx, int dy) {
checkError("before createFramebuffer"); checkError("before createFramebuffer");
bool res = true; bool res = true;
textureId = framebufferId = 0; texture = new Tex2D();
textureId = genTexture(); if (!texture.ID)
if (!textureId)
return false; return false;
GLuint fid = 0; checkError("glBindTexture GL_TEXTURE_2D");
glGenFramebuffers(1, &fid); FBO f = new FBO();
if (checkError("createFramebuffer glGenFramebuffersOES")) return false; if (!f.ID)
framebufferId = fid; return false;
glBindFramebuffer(GL_FRAMEBUFFER, framebufferId); fbo = f;
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); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dx, dy, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, null);
checkError("glTexImage2D"); checkError("glTexImage2D");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); texture.setSamplerParams(true, true);
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); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.ID, 0);
checkError("glFramebufferTexture2D"); checkError("glFramebufferTexture2D");
// Always check that our framebuffer is ok // Always check that our framebuffer is ok
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
@ -1164,35 +949,26 @@ class GLSupport {
checkError("glClear"); checkError("glClear");
checkError("after createFramebuffer"); checkError("after createFramebuffer");
//CRLog::trace("CRGLSupportImpl::createFramebuffer %d,%d texture=%d, buffer=%d", dx, dy, textureId, framebufferId); //CRLog::trace("CRGLSupportImpl::createFramebuffer %d,%d texture=%d, buffer=%d", dx, dy, textureId, framebufferId);
currentFramebufferId = framebufferId; currentFBO = fbo;
glBindTexture(GL_TEXTURE_2D, 0); texture.unbind();
checkError("createFramebuffer - glBindTexture(0)"); fbo.unbind();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
checkError("createFramebuffer - glBindFramebuffer(0)");
return res; return res;
} }
void deleteFramebuffer(ref uint framebufferId) { void deleteFramebuffer(ref FBO fbo) {
//CRLog::debug("GLDrawBuf::deleteFramebuffer"); //CRLog::debug("GLDrawBuf::deleteFramebuffer");
if (framebufferId != 0) { if (fbo.ID != 0) {
glBindFramebuffer(GL_FRAMEBUFFER, 0); destroy(fbo);
checkError("deleteFramebuffer - glBindFramebuffer");
GLuint fid = framebufferId;
glDeleteFramebuffers(1, &fid);
checkError("deleteFramebuffer - glDeleteFramebuffer");
} }
//CRLog::trace("CRGLSupportImpl::deleteFramebuffer(%d)", framebufferId); currentFBO = null;
framebufferId = 0;
checkError("after deleteFramebuffer");
currentFramebufferId = 0;
} }
bool bindFramebuffer(uint framebufferId) { bool bindFramebuffer(FBO fbo) {
//CRLog::trace("CRGLSupportImpl::bindFramebuffer(%d)", framebufferId); //CRLog::trace("CRGLSupportImpl::bindFramebuffer(%d)", framebufferId);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferId); fbo.bind();
currentFramebufferId = framebufferId; currentFBO = fbo;
return !checkError("glBindFramebuffer"); 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);