From 9e63fb6b643d982dfeab5fb60e000b81da404b25 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Mon, 23 Sep 2013 07:15:01 +0200 Subject: [PATCH] Remove the remaining bits of deprecated GL usage The drawing is now completely shader based, which makes away with all usage of the depracted matrix stack. This also allows us to do things like simple translations and texture coordinate translation directly instead of doing everything indirectly through matrices. Fixed vertex attributes ('vertexPointer()' etc) are also replaced with user defined attribute arrays. --- shader/bitmapBlit.frag | 6 +- shader/hue.frag | 46 ++++---- shader/plane.frag | 36 ++++++ shader/simple.frag | 9 ++ shader/simple.vert | 18 +++ shader/simpleAlpha.frag | 11 ++ shader/simpleColor.frag | 7 ++ shader/simpleColor.vert | 20 ++++ shader/sprite.frag | 16 +-- shader/sprite.vert | 17 +++ shader/trans.frag | 10 +- shader/transSimple.frag | 9 +- src/bitmap.cpp | 59 ++++++---- src/bitmap.h | 6 +- src/etc-internal.h | 20 +++- src/gl-util.h | 18 +-- src/globalstate.cpp | 15 ++- src/globalstate.h | 14 ++- src/glstate.cpp | 31 ----- src/glstate.h | 7 -- src/graphics.cpp | 26 ++-- src/plane.cpp | 22 +++- src/quad.h | 13 +- src/quadarray.h | 22 ++-- src/shader.cpp | 255 ++++++++++++++++++++++++++++++++-------- src/shader.h | 117 +++++++++++++++--- src/sprite.cpp | 37 ++++-- src/tilemap.cpp | 64 +++++----- src/window.cpp | 65 +++++----- 29 files changed, 701 insertions(+), 295 deletions(-) create mode 100644 shader/plane.frag create mode 100644 shader/simple.frag create mode 100644 shader/simple.vert create mode 100644 shader/simpleAlpha.frag create mode 100644 shader/simpleColor.frag create mode 100644 shader/simpleColor.vert create mode 100644 shader/sprite.vert diff --git a/shader/bitmapBlit.frag b/shader/bitmapBlit.frag index bf0031c..902c88b 100644 --- a/shader/bitmapBlit.frag +++ b/shader/bitmapBlit.frag @@ -1,3 +1,5 @@ +/* Shader for approximating the way RMXP does bitmap + * blending via DirectDraw */ uniform sampler2D source; uniform sampler2D destination; @@ -6,9 +8,11 @@ uniform vec4 subRect; uniform float opacity; +varying vec2 v_texCoord; + void main() { - vec2 coor = gl_TexCoord[0].xy; + vec2 coor = v_texCoord; vec2 dstCoor = (coor - subRect.xy) * subRect.zw; vec4 srcFrag = texture2D(source, coor); diff --git a/shader/hue.frag b/shader/hue.frag index 0f4bd7d..416ee9b 100644 --- a/shader/hue.frag +++ b/shader/hue.frag @@ -1,40 +1,44 @@ + uniform sampler2D inputTexture; -uniform float hueAdjust; +uniform float hueAdjust; + +varying vec2 v_texCoord; + void main () { const vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0); - const vec4 kRGBToI = vec4 (0.596, -0.275, -0.321, 0.0); - const vec4 kRGBToQ = vec4 (0.212, -0.523, 0.311, 0.0); + const vec4 kRGBToI = vec4 (0.596, -0.275, -0.321, 0.0); + const vec4 kRGBToQ = vec4 (0.212, -0.523, 0.311, 0.0); - const vec4 kYIQToR = vec4 (1.0, 0.956, 0.621, 0.0); - const vec4 kYIQToG = vec4 (1.0, -0.272, -0.647, 0.0); - const vec4 kYIQToB = vec4 (1.0, -1.107, 1.704, 0.0); + const vec4 kYIQToR = vec4 (1.0, 0.956, 0.621, 0.0); + const vec4 kYIQToG = vec4 (1.0, -0.272, -0.647, 0.0); + const vec4 kYIQToB = vec4 (1.0, -1.107, 1.704, 0.0); - // Sample the input pixel - vec4 color = texture2D (inputTexture, gl_TexCoord [ 0 ].xy); + /* Sample the input pixel */ + vec4 color = texture2D (inputTexture, v_texCoord.xy); - // Convert to YIQ - float YPrime = dot (color, kRGBToYPrime); - float I = dot (color, kRGBToI); - float Q = dot (color, kRGBToQ); + /* Convert to YIQ */ + float YPrime = dot (color, kRGBToYPrime); + float I = dot (color, kRGBToI); + float Q = dot (color, kRGBToQ); - // Calculate the hue and chroma + /* Calculate the hue and chroma */ float hue = atan (Q, I); float chroma = sqrt (I * I + Q * Q); - // Make the user's adjustments + /* Make the user's adjustments */ hue += hueAdjust; // Convert back to YIQ Q = chroma * sin (hue); I = chroma * cos (hue); - // Convert back to RGB - vec4 yIQ = vec4 (YPrime, I, Q, 0.0); - color.r = dot (yIQ, kYIQToR); - color.g = dot (yIQ, kYIQToG); - color.b = dot (yIQ, kYIQToB); + /* Convert back to RGB */ + vec4 yIQ = vec4 (YPrime, I, Q, 0.0); + color.r = dot (yIQ, kYIQToR); + color.g = dot (yIQ, kYIQToG); + color.b = dot (yIQ, kYIQToB); - // Save the result - gl_FragColor = color; + /* Save the result */ + gl_FragColor = color; } diff --git a/shader/plane.frag b/shader/plane.frag new file mode 100644 index 0000000..02a82b8 --- /dev/null +++ b/shader/plane.frag @@ -0,0 +1,36 @@ + +uniform sampler2D texture; + +uniform vec4 tone; + +uniform float opacity; +uniform vec4 color; +uniform vec4 flash; + +varying vec2 v_texCoord; + +const vec3 lumaF = { .299, .587, .114 }; + +void main() +{ + /* Sample source color */ + vec4 frag = texture2D(texture, v_texCoord); + + /* Apply gray */ + const float luma = dot(frag.rgb, lumaF); + frag.rgb = mix(frag.rgb, vec3(luma), tone.w); + + /* Apply tone */ + frag.rgb += tone.rgb; + + /* Apply opacity */ + frag.a *= opacity; + + /* Apply color */ + frag.rgb = mix(frag.rgb, color.rgb, color.a); + + /* Apply flash */ + frag.rgb = mix(frag.rgb, flash.rgb, flash.a); + + gl_FragColor = frag; +} diff --git a/shader/simple.frag b/shader/simple.frag new file mode 100644 index 0000000..e00b11c --- /dev/null +++ b/shader/simple.frag @@ -0,0 +1,9 @@ + +uniform sampler2D texture; + +varying vec2 v_texCoord; + +void main() +{ + gl_FragColor = texture2D(texture, v_texCoord); +} diff --git a/shader/simple.vert b/shader/simple.vert new file mode 100644 index 0000000..477cb4e --- /dev/null +++ b/shader/simple.vert @@ -0,0 +1,18 @@ + +uniform mat4 projMat; + +uniform vec2 texSizeInv; +uniform float texOffsetX; +uniform vec2 translation; + +attribute vec2 position; +attribute vec2 texCoord; + +varying vec2 v_texCoord; + +void main() +{ + gl_Position = projMat * vec4(position + translation, 0, 1); + + v_texCoord = vec2(texCoord.x + texOffsetX, texCoord.y) * texSizeInv; +} diff --git a/shader/simpleAlpha.frag b/shader/simpleAlpha.frag new file mode 100644 index 0000000..4214e2b --- /dev/null +++ b/shader/simpleAlpha.frag @@ -0,0 +1,11 @@ + +uniform sampler2D texture; + +varying vec2 v_texCoord; +varying vec4 v_color; + +void main() +{ + gl_FragColor = texture2D(texture, v_texCoord); + gl_FragColor.a *= v_color.a; +} diff --git a/shader/simpleColor.frag b/shader/simpleColor.frag new file mode 100644 index 0000000..3e0dcba --- /dev/null +++ b/shader/simpleColor.frag @@ -0,0 +1,7 @@ + +varying vec4 v_color; + +void main() +{ + gl_FragColor = v_color; +} diff --git a/shader/simpleColor.vert b/shader/simpleColor.vert new file mode 100644 index 0000000..837cd1b --- /dev/null +++ b/shader/simpleColor.vert @@ -0,0 +1,20 @@ + +uniform mat4 projMat; + +uniform vec2 texSizeInv; +uniform vec2 translation; + +attribute vec2 position; +attribute vec2 texCoord; +attribute vec4 color; + +varying vec2 v_texCoord; +varying vec4 v_color; + +void main() +{ + gl_Position = projMat * vec4(position + translation, 0, 1); + + v_texCoord = texCoord * texSizeInv; + v_color = color; +} diff --git a/shader/sprite.frag b/shader/sprite.frag index 33ab689..9bb3591 100644 --- a/shader/sprite.frag +++ b/shader/sprite.frag @@ -5,19 +5,18 @@ uniform vec4 tone; uniform float opacity; uniform vec4 color; -uniform vec4 flash; uniform float bushDepth; -uniform float bushOpacity; - +uniform float bushOpacity; + +varying vec2 v_texCoord; + const vec3 lumaF = { .299, .587, .114 }; void main() { - vec2 coor = gl_TexCoord[0].xy; - /* Sample source color */ - vec4 frag = texture2D(texture, coor); + vec4 frag = texture2D(texture, v_texCoord); /* Apply gray */ const float luma = dot(frag.rgb, lumaF); @@ -32,11 +31,8 @@ void main() /* Apply color */ frag.rgb = mix(frag.rgb, color.rgb, color.a); - /* Apply flash */ - frag.rgb = mix(frag.rgb, flash.rgb, flash.a); - /* Apply bush alpha by mathematical if */ - float underBush = float(coor.y < bushDepth); + float underBush = float(v_texCoord.y < bushDepth); frag.a *= clamp(bushOpacity + underBush, 0, 1); gl_FragColor = frag; diff --git a/shader/sprite.vert b/shader/sprite.vert new file mode 100644 index 0000000..a048ae5 --- /dev/null +++ b/shader/sprite.vert @@ -0,0 +1,17 @@ + +uniform mat4 projMat; + +uniform mat4 spriteMat; + +uniform vec2 texSizeInv; + +attribute vec2 position; +attribute vec2 texCoord; + +varying vec2 v_texCoord; + +void main() +{ + gl_Position = projMat * spriteMat * vec4(position, 0, 1); + v_texCoord = texCoord * texSizeInv; +} diff --git a/shader/trans.frag b/shader/trans.frag index 1f743f1..8f2cdd7 100644 --- a/shader/trans.frag +++ b/shader/trans.frag @@ -1,4 +1,3 @@ - /* Fragment shader dealing with transitions */ uniform sampler2D currentScene; @@ -9,15 +8,16 @@ uniform float prog; /* Vague [0, 512] normalized */ uniform float vague; +varying vec2 v_texCoord; + void main() { - vec2 texCoor = gl_TexCoord[0].st; - float transV = texture2D(transMap, texCoor).r; + float transV = texture2D(transMap, v_texCoord).r; float cTransV = clamp(transV, prog, prog+vague); float alpha = (cTransV - prog) / vague; - vec4 newFrag = texture2D(currentScene, texCoor); - vec4 oldFrag = texture2D(frozenScene, texCoor); + vec4 newFrag = texture2D(currentScene, v_texCoord); + vec4 oldFrag = texture2D(frozenScene, v_texCoord); gl_FragColor = mix(newFrag, oldFrag, alpha); } diff --git a/shader/transSimple.frag b/shader/transSimple.frag index 2186318..a5aac7d 100644 --- a/shader/transSimple.frag +++ b/shader/transSimple.frag @@ -1,13 +1,16 @@ +/* Fragment shader that produces a simple + * fade in / fade out type transition */ uniform sampler2D frozenScene; uniform sampler2D currentScene; uniform float prog; +varying vec2 v_texCoord; + void main() { - vec2 texCoor = gl_TexCoord[0].st; - vec4 newPixel = texture2D(currentScene, texCoor); - vec4 oldPixel = texture2D(frozenScene, texCoor); + vec4 newPixel = texture2D(currentScene, v_texCoord); + vec4 oldPixel = texture2D(frozenScene, v_texCoord); gl_FragColor = mix(oldPixel, newPixel, prog); } diff --git a/src/bitmap.cpp b/src/bitmap.cpp index e1c9577..dcaa302 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -55,10 +55,10 @@ struct BitmapPrivate font = &gState->defaultFont(); } - void bindTextureWithMatrix() + void bindTexture(ShaderBase &shader) { TEX::bind(tex.tex); - TEX::bindMatrix(tex.width, tex.height); + shader.setTexSize(Vec2i(tex.width, tex.height)); } void bindFBO() @@ -66,14 +66,15 @@ struct BitmapPrivate FBO::bind(tex.fbo, FBO::Draw); } - void pushSetViewport() const + void pushSetViewport(ShaderBase &shader) const { - glState.pushSetViewport(tex.width, tex.height); + glState.viewport.pushSet(IntRect(0, 0, tex.width, tex.height)); + shader.applyViewportProj(); } void popViewport() const { - glState.popViewport(); + glState.viewport.pop(); } void blitQuad(Quad &quad) @@ -88,9 +89,12 @@ struct BitmapPrivate if (pointArray.count() == 0) return; - TEX::unbind(); + SimpleColorShader &shader = gState->simpleColorShader(); + shader.bind(); + shader.setTranslation(Vec2i()); + bindFBO(); - pushSetViewport(); + pushSetViewport(shader); glState.blendMode.pushSet(BlendNone); pointArray.commit(); @@ -266,14 +270,13 @@ void Bitmap::stretchBlt(const IntRect &destRect, quad.setTexPosRect(sourceRect, destRect); quad.setColor(Vec4(1, 1, 1, normOpacity)); - source.p->bindTextureWithMatrix(); + source.p->bindTexture(shader); p->bindFBO(); - p->pushSetViewport(); + p->pushSetViewport(shader); p->blitQuad(quad); p->popViewport(); - shader.unbind(); } modified(); @@ -311,6 +314,10 @@ void Bitmap::gradientFillRect(const IntRect &rect, flush(); + SimpleColorShader &shader = gState->simpleColorShader(); + shader.bind(); + shader.setTranslation(Vec2i()); + Quad &quad = gState->gpQuad(); if (vertical) @@ -330,9 +337,8 @@ void Bitmap::gradientFillRect(const IntRect &rect, quad.setPosRect(rect); - TEX::unbind(); p->bindFBO(); - p->pushSetViewport(); + p->pushSetViewport(shader); p->blitQuad(quad); @@ -384,8 +390,8 @@ Vec4 Bitmap::getPixel(int x, int y) const p->bindFBO(); - glState.viewport.push(); - Vec4 pixel = FBO::getPixel(x, y, width(), height()); + glState.viewport.pushSet(IntRect(0, 0, width(), height())); + Vec4 pixel = FBO::getPixel(x, y); glState.viewport.pop(); return pixel; @@ -424,11 +430,10 @@ void Bitmap::hueChange(int hue) HueShader &shader = gState->hueShader(); shader.bind(); shader.setHueAdjust(hueAdj); - shader.setInputTexture(p->tex.tex); FBO::bind(newTex.fbo, FBO::Draw); - TEX::bindMatrix(width(), height()); - p->pushSetViewport(); + p->pushSetViewport(shader); + p->bindTexture(shader); p->blitQuad(quad); @@ -436,6 +441,8 @@ void Bitmap::hueChange(int hue) p->popViewport(); + TEX::unbind(); + gState->texPool().release(p->tex); p->tex = newTex; @@ -501,7 +508,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align) FloatRect posRect(alignX, alignY, txtSurf->w * squeeze, txtSurf->h); - Vec2 gpTexSize; + Vec2i gpTexSize; gState->ensureTexSize(txtSurf->w, txtSurf->h, gpTexSize); // if (str[1] != '\0') @@ -515,11 +522,12 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align) FBO::blit(posRect.x, posRect.y, 0, 0, posRect.w, posRect.h); FloatRect bltRect(0, 0, - gpTexSize.x / gpTex2.width, - gpTexSize.y / gpTex2.height); + (float) gpTexSize.x / gpTex2.width, + (float) gpTexSize.y / gpTex2.height); BltShader &shader = gState->bltShader(); shader.bind(); + shader.setTexSize(gpTexSize); shader.setSource(); shader.setDestination(gpTex2.tex); shader.setSubRect(bltRect); @@ -536,7 +544,7 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align) SDL_FreeSurface(txtSurf); p->bindFBO(); - p->pushSetViewport(); + p->pushSetViewport(gState->bltShader()); glState.blendMode.pushSet(BlendNone); quad.draw(); @@ -544,8 +552,6 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align) glState.blendMode.pop(); p->popViewport(); - FragShader::unbind(); - modified(); } @@ -568,6 +574,9 @@ DEF_ATTR_SIMPLE(Bitmap, Font, Font*, p->font) void Bitmap::flush() const { + if (isDisposed()) + return; + p->flushPoints(); } @@ -576,9 +585,9 @@ TEXFBO &Bitmap::getGLTypes() return p->tex; } -void Bitmap::bindTexWithMatrix() +void Bitmap::bindTex(ShaderBase &shader) { - p->bindTextureWithMatrix(); + p->bindTexture(shader); } void Bitmap::releaseResources() diff --git a/src/bitmap.h b/src/bitmap.h index a7fffe5..0fa8cef 100644 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -29,6 +29,7 @@ #include "sigc++/signal.h" class Font; +class ShaderBase; struct TEXFBO; struct BitmapPrivate; @@ -103,7 +104,10 @@ public: /* */ void flush() const; TEXFBO &getGLTypes(); - void bindTexWithMatrix(); + + /* Binds the backing texture and sets the correct + * texture size uniform in shader */ + void bindTex(ShaderBase &shader); sigc::signal modified; diff --git a/src/etc-internal.h b/src/etc-internal.h index 7c3319c..67c0a25 100644 --- a/src/etc-internal.h +++ b/src/etc-internal.h @@ -72,11 +72,19 @@ struct Vec2i : x(x), y(y) {} - bool operator==(const Vec2i &other) + bool operator==(const Vec2i &other) const { return x == other.x && y == other.y; } + Vec2i &operator+=(const Vec2i &other) + { + x += other.x; + y += other.y; + + return *this; + } + operator Vec2() const { return Vec2(x, y); @@ -164,6 +172,16 @@ struct IntRect return (x == other.x && y == other.y && w == other.w && h == other.h); } + + Vec2i pos() const + { + return Vec2i(x, y); + } + + Vec2i size() const + { + return Vec2i(w, h); + } }; struct StaticRect { float x, y, w, h; }; diff --git a/src/gl-util.h b/src/gl-util.h index f2ee5c6..ffd65e3 100644 --- a/src/gl-util.h +++ b/src/gl-util.h @@ -74,21 +74,6 @@ namespace TEX bind(ID(0)); } - inline void bindMatrix(int width, int height, int xOffset = 0) - { - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glScalef(1.f / width, 1.f / height, 1.f); - glTranslatef(xOffset, 0, 0); - glMatrixMode(GL_MODELVIEW); - } - - inline void bindWithMatrix(ID id, int width, int height, int xOffset = 0) - { - bind(id); - bindMatrix(width, height, xOffset); - } - inline void uploadImage(GLsizei width, GLsizei height, const void *data, GLenum format) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, format, GL_UNSIGNED_BYTE, data); @@ -218,11 +203,10 @@ namespace FBO blit(srcX, srcY, srcW, srcH, dstX, dstY, srcW, srcH); } - inline Vec4 getPixel(int x, int y, int texWidth, int texHeight) + inline Vec4 getPixel(int x, int y) { Vec4 pixel; - glViewport(0, 0, texWidth, texHeight); glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, &pixel.x); return pixel; diff --git a/src/globalstate.cpp b/src/globalstate.cpp index d967e9a..193b31f 100644 --- a/src/globalstate.cpp +++ b/src/globalstate.cpp @@ -65,7 +65,12 @@ struct GlobalStatePrivate GLState _glState; + SimpleShader simpleShader; + SimpleColorShader simpleColorShader; + SimpleAlphaShader simpleAlphaShader; + SimpleSpriteShader simpleSpriteShader; SpriteShader spriteShader; + PlaneShader planeShader; TransShader transShader; SimpleTransShader sTransShader; HueShader hueShader; @@ -176,7 +181,12 @@ GSATT(Graphics&, graphics) GSATT(Input&, input) GSATT(Audio&, audio) GSATT(GLState&, _glState) +GSATT(SimpleShader&, simpleShader) +GSATT(SimpleColorShader&, simpleColorShader) +GSATT(SimpleAlphaShader&, simpleAlphaShader) +GSATT(SimpleSpriteShader&, simpleSpriteShader) GSATT(SpriteShader&, spriteShader) +GSATT(PlaneShader&, planeShader) GSATT(TransShader&, transShader) GSATT(SimpleTransShader&, sTransShader) GSATT(HueShader&, hueShader) @@ -204,10 +214,9 @@ void GlobalState::bindTex() { TEX::bind(p->globalTex); TEX::allocEmpty(p->globalTexW, p->globalTexH); - TEX::bindMatrix(p->globalTexW, p->globalTexH); } -void GlobalState::ensureTexSize(int minW, int minH, Vec2 ¤tSizeOut) +void GlobalState::ensureTexSize(int minW, int minH, Vec2i ¤tSizeOut) { if (minW > p->globalTexW) p->globalTexW = findNextPow2(minW); @@ -215,7 +224,7 @@ void GlobalState::ensureTexSize(int minW, int minH, Vec2 ¤tSizeOut) if (minH > p->globalTexH) p->globalTexH = findNextPow2(minH); - currentSizeOut = Vec2(p->globalTexW, p->globalTexH); + currentSizeOut = Vec2i(p->globalTexW, p->globalTexH); } TEXFBO &GlobalState::gpTexFBO(int minW, int minH) diff --git a/src/globalstate.h b/src/globalstate.h index 718b998..1bbeb90 100644 --- a/src/globalstate.h +++ b/src/globalstate.h @@ -42,7 +42,12 @@ class Graphics; class Input; class Audio; class GLState; +class SimpleShader; +class SimpleColorShader; +class SimpleAlphaShader; +class SimpleSpriteShader; class SpriteShader; +class PlaneShader; class TransShader; class SimpleTransShader; class HueShader; @@ -52,7 +57,7 @@ class FontPool; class Font; struct GlobalIBO; struct Config; -struct Vec2; +struct Vec2i; struct GlobalState { @@ -76,7 +81,12 @@ struct GlobalState GLState &_glState(); + SimpleShader &simpleShader(); + SimpleColorShader &simpleColorShader(); + SimpleAlphaShader &simpleAlphaShader(); + SimpleSpriteShader &simpleSpriteShader(); SpriteShader &spriteShader(); + PlaneShader &planeShader(); TransShader &transShader(); SimpleTransShader &sTransShader(); HueShader &hueShader(); @@ -98,7 +108,7 @@ struct GlobalState /* Global general purpose texture */ void bindTex(); - void ensureTexSize(int minW, int minH, Vec2 ¤tSizeOut); + void ensureTexSize(int minW, int minH, Vec2i ¤tSizeOut); TEXFBO &gpTexFBO(int minW, int minH); diff --git a/src/glstate.cpp b/src/glstate.cpp index 229120a..011eb24 100644 --- a/src/glstate.cpp +++ b/src/glstate.cpp @@ -93,37 +93,6 @@ void GLViewport::apply(const IntRect &value) glViewport(value.x, value.y, value.w, value.h); } - -void GLState::setViewport(int width, int height) -{ - viewport.set(IntRect(0, 0, width, height)); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, width, 0, height, 0, 1); - glMatrixMode(GL_MODELVIEW); -} - -void GLState::pushSetViewport(int width, int height) -{ - viewport.pushSet(IntRect(0, 0, width, height)); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0, width, 0, height, 0, 1); - glMatrixMode(GL_MODELVIEW); -} - -void GLState::popViewport() -{ - viewport.pop(); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); -} - GLState::Caps::Caps() { glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); diff --git a/src/glstate.h b/src/glstate.h index 361d075..963cc9f 100644 --- a/src/glstate.h +++ b/src/glstate.h @@ -124,13 +124,6 @@ public: GLBlendMode blendMode; GLViewport viewport; - /* These functions pushSet/pop both the viewport - * and a glOrtho projection matrix. - * Useful for setting up rendering to FBOs of differing sizes */ - void setViewport(int width, int height); - void pushSetViewport(int width, int height); - void popViewport(); - struct Caps { int maxTexSize; diff --git a/src/graphics.cpp b/src/graphics.cpp index 9ae825c..a0199f0 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -288,7 +288,7 @@ struct PingPong private: void bind() { - TEX::bindWithMatrix(rt[srcInd].tex, screenW, screenH, true); + TEX::bind(rt[srcInd].tex); FBO::bind(rt[srcInd].fbo, FBO::Read); FBO::bind(rt[dstInd].fbo, FBO::Draw); } @@ -322,7 +322,7 @@ public: pp.startRender(); - glState.setViewport(w, h); + glState.viewport.set(IntRect(0, 0, w, h)); glClear(GL_COLOR_BUFFER_BIT); @@ -330,9 +330,12 @@ public: if (brightEffect) { - glState.texture2D.pushSet(false); + SimpleColorShader &shader = gState->simpleColorShader(); + shader.bind(); + shader.applyViewportProj(); + shader.setTranslation(Vec2i()); + brightnessQuad.draw(); - glState.texture2D.pop(); } pp.finishRender(); @@ -343,16 +346,16 @@ public: pp.swapRender(); pp.blitFBOs(); - SpriteShader &shader = gState->spriteShader(); + PlaneShader &shader = gState->planeShader(); shader.bind(); - shader.resetUniforms(); shader.setColor(c); shader.setFlash(f); shader.setTone(t); + shader.applyViewportProj(); + shader.setTexSize(geometry.rect.size()); glState.blendMode.pushSet(BlendNone); - TEX::bindMatrix(geometry.rect.w, geometry.rect.h); screenQuad.draw(); glState.blendMode.pop(); @@ -687,28 +690,29 @@ void Graphics::transition(int duration, { TransShader &shader = gState->transShader(); shader.bind(); + shader.applyViewportProj(); shader.setFrozenScene(p->frozenScene.tex); shader.setCurrentScene(p->currentScene.tex); shader.setTransMap(transMap->getGLTypes().tex); shader.setVague(vague / 512.0f); + shader.setTexSize(p->scRes); } else { SimpleTransShader &shader = gState->sTransShader(); shader.bind(); + shader.applyViewportProj(); shader.setFrozenScene(p->frozenScene.tex); shader.setCurrentScene(p->currentScene.tex); + shader.setTexSize(p->scRes); } - TEX::bindMatrix(p->scRes.x, p->scRes.y); - glState.blendMode.pushSet(BlendNone); for (int i = 0; i < duration; ++i) { if (p->threadData->rqTerm) { - FragShader::unbind(); delete transMap; p->shutdown(); } @@ -737,8 +741,6 @@ void Graphics::transition(int duration, glState.blendMode.pop(); - FragShader::unbind(); - delete transMap; p->frozen = false; diff --git a/src/plane.cpp b/src/plane.cpp index bad6acd..1ebc267 100644 --- a/src/plane.cpp +++ b/src/plane.cpp @@ -170,29 +170,41 @@ void Plane::draw() p->quadSourceDirty = false; } + ShaderBase *base; + if (p->color->hasEffect() || p->tone->hasEffect() || p->opacity != 255) { - SpriteShader &shader = gState->spriteShader(); + PlaneShader &shader = gState->planeShader(); shader.bind(); + shader.applyViewportProj(); shader.setTone(p->tone->norm); shader.setColor(p->color->norm); shader.setFlash(Vec4()); shader.setOpacity(p->opacity.norm); - shader.setBushOpacity(1); - shader.setBushDepth(0); + + base = &shader; + } + else + { + SimpleShader &shader = gState->simpleShader(); + + shader.bind(); + shader.applyViewportProj(); + shader.setTranslation(Vec2i()); + + base = &shader; } glState.blendMode.pushSet(p->blendType); p->bitmap->flush(); - p->bitmap->bindTexWithMatrix(); + p->bitmap->bindTex(*base); TEX::setRepeat(true); p->quad.draw(); TEX::setRepeat(false); - FragShader::unbind(); } void Plane::onGeometryChange(const Scene::Geometry &geo) diff --git a/src/quad.h b/src/quad.h index c0b7beb..e1a53ff 100644 --- a/src/quad.h +++ b/src/quad.h @@ -27,6 +27,7 @@ #include "gl-util.h" #include "globalstate.h" #include "global-ibo.h" +#include "shader.h" struct Quad { @@ -111,13 +112,13 @@ struct Quad VBO::bind(vbo); gState->bindQuadIBO(); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableVertexAttribArray(Shader::Color); + glEnableVertexAttribArray(Shader::Position); + glEnableVertexAttribArray(Shader::TexCoord); - glColorPointer (4, GL_FLOAT, sizeof(Vertex), Vertex::colorOffset()); - glVertexPointer (2, GL_FLOAT, sizeof(Vertex), Vertex::posOffset()); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), Vertex::texPosOffset()); + glVertexAttribPointer(Shader::Color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::colorOffset()); + glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::posOffset()); + glVertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::texPosOffset()); VAO::unbind(); VBO::unbind(); diff --git a/src/quadarray.h b/src/quadarray.h index 65bb476..f6be899 100644 --- a/src/quadarray.h +++ b/src/quadarray.h @@ -26,6 +26,7 @@ #include "gl-util.h" #include "globalstate.h" #include "global-ibo.h" +#include "shader.h" typedef uint32_t index_t; #define _GL_INDEX_TYPE GL_UNSIGNED_INT @@ -49,13 +50,13 @@ struct ColorQuadArray VBO::bind(vbo); gState->bindQuadIBO(); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); + glEnableVertexAttribArray(Shader::Color); + glEnableVertexAttribArray(Shader::Position); + glEnableVertexAttribArray(Shader::TexCoord); - glVertexPointer (2, GL_FLOAT, sizeof(Vertex), Vertex::posOffset()); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), Vertex::texPosOffset()); - glColorPointer (4, GL_FLOAT, sizeof(Vertex), Vertex::colorOffset()); + glVertexAttribPointer(Shader::Color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::colorOffset()); + glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::posOffset()); + glVertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::texPosOffset()); VAO::unbind(); IBO::unbind(); @@ -120,12 +121,11 @@ struct PointArray VAO::bind(vao); VBO::bind(vbo); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableVertexAttribArray(Shader::Color); + glEnableVertexAttribArray(Shader::Position); - glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (const GLvoid*) 0); - glColorPointer (4, GL_FLOAT, sizeof(Vertex), (const GLvoid*) sizeof(SVertex)); + glVertexAttribPointer(Shader::Color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::colorOffset()); + glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::posOffset()); VAO::unbind(); VBO::unbind(); diff --git a/src/shader.cpp b/src/shader.cpp index 46c6f5e..b5ce0bc 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -20,72 +20,113 @@ */ #include "shader.h" +#include "globalstate.h" +#include "glstate.h" #include "GL/glew.h" #include -#include "../shader/sprite.frag.xxd" -#include "../shader/hue.frag.xxd" -#include "../shader/trans.frag.xxd" -#include "../shader/transSimple.frag.xxd" -#include "../shader/bitmapBlit.frag.xxd" +#include "../sprite.frag.xxd" +#include "../hue.frag.xxd" +#include "../trans.frag.xxd" +#include "../transSimple.frag.xxd" +#include "../bitmapBlit.frag.xxd" +#include "../plane.frag.xxd" +#include "../simple.frag.xxd" +#include "../simpleColor.frag.xxd" +#include "../simpleAlpha.frag.xxd" +#include "../simple.vert.xxd" +#include "../simpleColor.vert.xxd" +#include "../sprite.vert.xxd" + +#define INIT_SHADER(vert, frag) \ + Shader::init(shader_##vert##_vert, shader_##vert##_vert_len, shader_##frag##_frag, shader_##frag##_frag_len) #define GET_U(name) u_##name = glGetUniformLocation(program, #name) -FragShader::~FragShader() +Shader::Shader() +{ + vertShader = glCreateShader(GL_VERTEX_SHADER); + fragShader = glCreateShader(GL_FRAGMENT_SHADER); + + program = glCreateProgram(); +} + +Shader::~Shader() { glUseProgram(0); glDeleteProgram(program); - glDeleteShader(shader); + glDeleteShader(vertShader); + glDeleteShader(fragShader); } -void FragShader::bind() +void Shader::bind() { glUseProgram(program); } -void FragShader::unbind() +void Shader::unbind() { glActiveTexture(GL_TEXTURE0); glUseProgram(0); } -void FragShader::init(const unsigned char *source, int length) +void Shader::init(const unsigned char *vert, int vertSize, + const unsigned char *frag, int fragSize) { GLint success; - shader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(shader, 1, (const GLchar**) &source, (const GLint*) &length); - glCompileShader(shader); + /* Compile vertex shader */ + glShaderSource(vertShader, 1, (const GLchar**) &vert, (const GLint*) &vertSize); + glCompileShader(vertShader); - glGetObjectParameterivARB(shader, GL_COMPILE_STATUS, &success); + glGetObjectParameterivARB(vertShader, GL_COMPILE_STATUS, &success); Q_ASSERT(success); - program = glCreateProgram(); - glAttachShader(program, shader); + /* Compile fragment shader */ + glShaderSource(fragShader, 1, (const GLchar**) &frag, (const GLint*) &fragSize); + glCompileShader(fragShader); + + glGetObjectParameterivARB(fragShader, GL_COMPILE_STATUS, &success); + Q_ASSERT(success); + + /* Link shader program */ + glAttachShader(program, vertShader); + glAttachShader(program, fragShader); + + glBindAttribLocation(program, Position, "position"); + glBindAttribLocation(program, TexCoord, "texCoord"); + glBindAttribLocation(program, Color, "color"); + glLinkProgram(program); glGetObjectParameterivARB(program, GL_LINK_STATUS, &success); Q_ASSERT(success); } -void FragShader::initFromFile(const char *filename) +void Shader::initFromFile(const char *_vertFile, const char *_fragFile) { - QFile shaderFile(filename); - shaderFile.open(QFile::ReadOnly); - QByteArray contents = shaderFile.readAll(); - shaderFile.close(); + QFile vertFile(_vertFile); + vertFile.open(QFile::ReadOnly); + QByteArray vertContents = vertFile.readAll(); + vertFile.close(); - init((const unsigned char*) contents.constData(), contents.size()); + QFile fragFile(_fragFile); + fragFile.open(QFile::ReadOnly); + QByteArray fragContents = fragFile.readAll(); + fragFile.close(); + + init((const unsigned char*) vertContents.constData(), vertContents.size(), + (const unsigned char*) fragContents.constData(), fragContents.size()); } -void FragShader::setVec4Uniform(GLint location, const Vec4 &vec) +void Shader::setVec4Uniform(GLint location, const Vec4 &vec) { glUniform4f(location, vec.x, vec.y, vec.z, vec.w); } -void FragShader::setTexUniform(GLint location, unsigned unitIndex, TEX::ID texture) +void Shader::setTexUniform(GLint location, unsigned unitIndex, TEX::ID texture) { GLenum texUnit = GL_TEXTURE0 + unitIndex; @@ -95,11 +136,100 @@ void FragShader::setTexUniform(GLint location, unsigned unitIndex, TEX::ID textu glActiveTexture(GL_TEXTURE0); } +void ShaderBase::GLProjMat::apply(const Vec2i &value) +{ + /* glOrtho replacement */ + const float a = 2.f / value.x; + const float b = 2.f / value.y; + const float c = -2.f; + + GLfloat mat[16] = + { + a, 0, 0, 0, + 0, b, 0, 0, + 0, 0, c, 0, + -1, -1, -1, 1 + }; + + glUniformMatrix4fv(u_mat, 1, GL_FALSE, mat); +} + +void ShaderBase::init() +{ + GET_U(texSizeInv); + GET_U(translation); + + projMat.u_mat = glGetUniformLocation(program, "projMat"); +} + +void ShaderBase::applyViewportProj() +{ + const IntRect &vp = glState.viewport.get(); + projMat.set(Vec2i(vp.w, vp.h)); +} + +void ShaderBase::setTexSize(const Vec2i &value) +{ + glUniform2f(u_texSizeInv, 1.f / value.x, 1.f / value.y); +} + +void ShaderBase::setTranslation(const Vec2i &value) +{ + glUniform2f(u_translation, value.x, value.y); +} + + +SimpleShader::SimpleShader() +{ + INIT_SHADER(simple, simple); + + ShaderBase::init(); + + GET_U(texOffsetX); +} + +void SimpleShader::setTexOffsetX(int value) +{ + glUniform1f(u_texOffsetX, value); +} + + +SimpleColorShader::SimpleColorShader() +{ + INIT_SHADER(simpleColor, simpleColor); + + ShaderBase::init(); +} + + +SimpleAlphaShader::SimpleAlphaShader() +{ + INIT_SHADER(simpleColor, simpleAlpha); + + ShaderBase::init(); +} + + +SimpleSpriteShader::SimpleSpriteShader() +{ + INIT_SHADER(sprite, simple); + + ShaderBase::init(); + + GET_U(spriteMat); +} + +void SimpleSpriteShader::setSpriteMat(const float value[16]) +{ + glUniformMatrix4fv(u_spriteMat, 1, GL_FALSE, value); +} + TransShader::TransShader() { - init(shader_trans_frag, - shader_trans_frag_len); + INIT_SHADER(simple, trans); + + ShaderBase::init(); GET_U(currentScene); GET_U(frozenScene); @@ -136,8 +266,9 @@ void TransShader::setVague(float value) SimpleTransShader::SimpleTransShader() { - init(shader_transSimple_frag, - shader_transSimple_frag_len); + INIT_SHADER(simple, transSimple); + + ShaderBase::init(); GET_U(currentScene); GET_U(frozenScene); @@ -162,29 +293,21 @@ void SimpleTransShader::setProg(float value) SpriteShader::SpriteShader() { - init(shader_sprite_frag, - shader_sprite_frag_len); + INIT_SHADER(sprite, sprite); + ShaderBase::init(); + + GET_U(spriteMat); GET_U(tone); GET_U(color); - GET_U(flash); GET_U(opacity); GET_U(bushDepth); GET_U(bushOpacity); - - bind(); - resetUniforms(); - unbind(); } -void SpriteShader::resetUniforms() +void SpriteShader::setSpriteMat(const float value[16]) { - setTone(Vec4()); - setColor(Vec4()); - setFlash(Vec4()); - setOpacity(1); - setBushDepth(0); - setBushOpacity(0.5); + glUniformMatrix4fv(u_spriteMat, 1, GL_FALSE, value); } void SpriteShader::setTone(const Vec4 &tone) @@ -197,11 +320,6 @@ void SpriteShader::setColor(const Vec4 &color) setVec4Uniform(u_color, color); } -void SpriteShader::setFlash(const Vec4 &flash) -{ - setVec4Uniform(u_flash, flash); -} - void SpriteShader::setOpacity(float value) { glUniform1f(u_opacity, value); @@ -218,10 +336,44 @@ void SpriteShader::setBushOpacity(float value) } +PlaneShader::PlaneShader() +{ + INIT_SHADER(simple, plane); + + ShaderBase::init(); + + GET_U(tone); + GET_U(color); + GET_U(flash); + GET_U(opacity); +} + +void PlaneShader::setTone(const Vec4 &tone) +{ + setVec4Uniform(u_tone, tone); +} + +void PlaneShader::setColor(const Vec4 &color) +{ + setVec4Uniform(u_color, color); +} + +void PlaneShader::setFlash(const Vec4 &flash) +{ + setVec4Uniform(u_flash, flash); +} + +void PlaneShader::setOpacity(float value) +{ + glUniform1f(u_opacity, value); +} + + HueShader::HueShader() { - init(shader_hue_frag, - shader_hue_frag_len); + INIT_SHADER(simple, hue); + + ShaderBase::init(); GET_U(hueAdjust); GET_U(inputTexture); @@ -240,8 +392,9 @@ void HueShader::setInputTexture(TEX::ID tex) BltShader::BltShader() { - init(shader_bitmapBlit_frag, - shader_bitmapBlit_frag_len); + INIT_SHADER(simple, bitmapBlit); + + ShaderBase::init(); GET_U(source); GET_U(destination); diff --git a/src/shader.h b/src/shader.h index 1d39bb3..8bb99b6 100644 --- a/src/shader.h +++ b/src/shader.h @@ -24,27 +24,101 @@ #include "etc-internal.h" #include "gl-util.h" +#include "glstate.h" -class FragShader +class Shader { public: void bind(); static void unbind(); + enum Attribute + { + Position = 0, + TexCoord = 1, + Color = 2 + }; + protected: - ~FragShader(); + Shader(); + ~Shader(); - void init(const unsigned char *source, int length); - void initFromFile(const char *filename); + void init(const unsigned char *vert, int vertSize, + const unsigned char *frag, int fragSize); + void initFromFile(const char *vertFile, const char *fragFile); - void setVec4Uniform(GLint location, const Vec4 &vec); - void setTexUniform(GLint location, unsigned unitIndex, TEX::ID texture); + static void setVec4Uniform(GLint location, const Vec4 &vec); + static void setTexUniform(GLint location, unsigned unitIndex, TEX::ID texture); - GLuint shader; + GLuint vertShader, fragShader; GLuint program; }; -class TransShader : public FragShader +class ShaderBase : public Shader +{ +public: + + struct GLProjMat : public GLProperty + { + private: + void apply(const Vec2i &value); + GLint u_mat; + + friend class ShaderBase; + }; + + /* Stack is not used (only 'set()') */ + GLProjMat projMat; + + /* Retrieves the current glState.viewport size, + * calculates the corresponding ortho projection matrix + * and loads it into the shaders uniform */ + void applyViewportProj(); + + void setTexSize(const Vec2i &value); + void setTranslation(const Vec2i &value); + +protected: + void init(); + + GLint u_texSizeInv, u_translation; +}; + +class SimpleShader : public ShaderBase +{ +public: + SimpleShader(); + + void setTexOffsetX(int value); + +private: + GLint u_texOffsetX; +}; + +class SimpleColorShader : public ShaderBase +{ +public: + SimpleColorShader(); +}; + +class SimpleAlphaShader : public ShaderBase +{ +public: + SimpleAlphaShader(); +}; + +class SimpleSpriteShader : public ShaderBase +{ +public: + SimpleSpriteShader(); + + void setSpriteMat(const float value[16]); + +private: + GLint u_spriteMat; +}; + +class TransShader : public ShaderBase { public: TransShader(); @@ -59,7 +133,7 @@ private: GLint u_currentScene, u_frozenScene, u_transMap, u_prog, u_vague; }; -class SimpleTransShader : public FragShader +class SimpleTransShader : public ShaderBase { public: SimpleTransShader(); @@ -72,24 +146,37 @@ private: GLint u_currentScene, u_frozenScene, u_prog; }; -class SpriteShader : public FragShader +class SpriteShader : public ShaderBase { public: SpriteShader(); - void resetUniforms(); + void setSpriteMat(const float value[16]); void setTone(const Vec4 &value); void setColor(const Vec4 &value); - void setFlash(const Vec4 &value); void setOpacity(float value); void setBushDepth(float value); void setBushOpacity(float value); private: - GLint u_tone, u_opacity, u_color, u_flash, u_bushDepth, u_bushOpacity; + GLint u_spriteMat, u_tone, u_opacity, u_color, u_bushDepth, u_bushOpacity; }; -class HueShader : public FragShader +class PlaneShader : public ShaderBase +{ +public: + PlaneShader(); + + void setTone(const Vec4 &value); + void setColor(const Vec4 &value); + void setFlash(const Vec4 &value); + void setOpacity(float value); + +private: + GLint u_tone, u_color, u_flash, u_opacity; +}; + +class HueShader : public ShaderBase { public: HueShader(); @@ -102,7 +189,7 @@ private: }; /* Bitmap blit */ -class BltShader : public FragShader +class BltShader : public ShaderBase { public: BltShader(); diff --git a/src/sprite.cpp b/src/sprite.cpp index 57d9d45..5b52f74 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -304,12 +304,24 @@ void Sprite::draw() if (emptyFlashFlag) return; - if (p->color->hasEffect() || p->tone->hasEffect() || p->opacity != 255 || flashing || p->bushDepth != 0) + p->bitmap->flush(); + + ShaderBase *base; + + bool renderEffect = p->color->hasEffect() || + p->tone->hasEffect() || + p->opacity != 255 || + flashing || + p->bushDepth != 0; + + if (renderEffect) { SpriteShader &shader = gState->spriteShader(); shader.bind(); - shader.setFlash(Vec4()); + shader.applyViewportProj(); + shader.setSpriteMat(p->trans.getMatrix()); + shader.setTone(p->tone->norm); shader.setOpacity(p->opacity.norm); shader.setBushDepth(p->efBushDepth); @@ -321,23 +333,26 @@ void Sprite::draw() &flashColor : &p->color->norm; shader.setColor(*blend); + + base = &shader; + } + else + { + SimpleSpriteShader &shader = gState->simpleSpriteShader(); + shader.bind(); + + shader.setSpriteMat(p->trans.getMatrix()); + shader.applyViewportProj(); + base = &shader; } glState.blendMode.pushSet(p->blendType); - glPushMatrix(); - glLoadMatrixf(p->trans.getMatrix()); - - p->bitmap->flush(); - p->bitmap->bindTexWithMatrix(); + p->bitmap->bindTex(*base); p->quad.draw(); - glPopMatrix(); - glState.blendMode.pop(); - - FragShader::unbind(); } void Sprite::onGeometryChange(const Scene::Geometry &geo) diff --git a/src/tilemap.cpp b/src/tilemap.cpp index 216a70c..11d100b 100644 --- a/src/tilemap.cpp +++ b/src/tilemap.cpp @@ -301,14 +301,15 @@ struct TilemapPrivate tiles.vao = VAO::gen(); VAO::bind(tiles.vao); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnableVertexAttribArray(Shader::Position); + glEnableVertexAttribArray(Shader::TexCoord); VBO::bind(tiles.vbo); gState->bindQuadIBO(); - glVertexPointer (2, GL_FLOAT, sizeof(SVertex), SVertex::posOffset()); - glTexCoordPointer(2, GL_FLOAT, sizeof(SVertex), SVertex::texPosOffset()); + glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), SVertex::posOffset()); + glVertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), SVertex::texPosOffset()); VAO::unbind(); VBO::unbind(); @@ -321,14 +322,14 @@ struct TilemapPrivate VAO::bind(flash.vao); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); + glEnableVertexAttribArray(Shader::Color); + glEnableVertexAttribArray(Shader::Position); VBO::bind(flash.vbo); gState->bindQuadIBO(); - glVertexPointer(2, GL_FLOAT, sizeof(CVertex), CVertex::posOffset()); - glColorPointer(4, GL_FLOAT, sizeof(CVertex), CVertex::colorOffset()); + glVertexAttribPointer(Shader::Color, 4, GL_FLOAT, GL_FALSE, sizeof(CVertex), CVertex::colorOffset()); + glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(CVertex), CVertex::posOffset()); VAO::unbind(); VBO::unbind(); @@ -709,11 +710,11 @@ struct TilemapPrivate gState->ensureQuadIBO(quadCount); } - void bindAtlasWithMatrix() + void bindAtlas(SimpleShader &shader) { TEX::bind(atlas.gl.tex); - TEX::bindMatrix(atlas.animated ? atlasFrameW * 4 : atlasFrameW, atlas.frameH, - atlas.frameIdx * atlasFrameW); + shader.setTexSize(Vec2i(atlas.animated ? atlasFrameW * 4 : atlasFrameW, atlas.frameH)); + shader.setTexOffsetX(atlas.frameIdx * atlasFrameW); } Vec2i getReplicaOffset(Position pos) @@ -732,12 +733,12 @@ struct TilemapPrivate return offset; } - void translateMatrix(Position replicaPos) + void setTranslation(Position replicaPos, ShaderBase &shader) { Vec2i repOff = getReplicaOffset(replicaPos); + repOff += dispPos; - glTranslatef(dispPos.x + repOff.x, - dispPos.y + repOff.y, 0); + shader.setTranslation(repOff); } bool sampleFlashColor(Vec4 &out, int x, int y) @@ -894,11 +895,15 @@ GroundLayer::GroundLayer(TilemapPrivate *p, Viewport *viewport) void GroundLayer::draw() { - p->bindAtlasWithMatrix(); + SimpleShader &shader = gState->simpleShader(); + shader.bind(); + shader.applyViewportProj(); + + p->bindAtlas(shader); VAO::bind(p->tiles.vao); - glPushMatrix(); + p->setTranslation(Normal, shader); for (int i = 0; i < positionsN; ++i) { @@ -907,8 +912,7 @@ void GroundLayer::draw() if (!(p->replicas & pos)) continue; - glLoadIdentity(); - p->translateMatrix(pos); + p->setTranslation(pos, shader); drawInt(); } @@ -919,6 +923,10 @@ void GroundLayer::draw() glState.blendMode.pushSet(BlendAddition); glState.texture2D.pushSet(false); + SimpleColorShader &shader = gState->simpleColorShader(); + shader.bind(); + shader.applyViewportProj(); + for (int i = 0; i < positionsN; ++i) { const Position pos = positions[i]; @@ -926,8 +934,7 @@ void GroundLayer::draw() if (!(p->replicas & pos)) continue; - glLoadIdentity(); - p->translateMatrix(pos); + p->setTranslation(pos, shader); drawFlashInt(); } @@ -936,8 +943,6 @@ void GroundLayer::draw() glState.blendMode.pop(); } - glPopMatrix(); - VAO::unbind(); } @@ -970,13 +975,15 @@ ScanRow::ScanRow(TilemapPrivate *p, Viewport *viewport, int index) void ScanRow::draw() { - p->bindAtlasWithMatrix(); + SimpleShader &shader = gState->simpleShader(); + shader.bind(); + shader.applyViewportProj(); + + p->bindAtlas(shader); VAO::bind(p->tiles.vao); - glPushMatrix(); - glLoadIdentity(); - p->translateMatrix(Normal); + p->setTranslation(Normal, shader); for (int i = 0; i < positionsN; ++i) { @@ -985,14 +992,11 @@ void ScanRow::draw() if (!(p->replicas & pos)) continue; - glLoadIdentity(); - p->translateMatrix(pos); + p->setTranslation(pos, shader); drawInt(); } - glPopMatrix(); - VAO::unbind(); } diff --git a/src/window.cpp b/src/window.cpp index 80ec88e..51d1e66 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -419,17 +419,20 @@ struct WindowPrivate TEX::unbind(); FBO::bind(baseTex.fbo, FBO::Draw); - glState.pushSetViewport(baseTex.width, baseTex.height); + glState.viewport.pushSet(IntRect(0, 0, baseTex.width, baseTex.height)); glState.clearColor.pushSet(Vec4()); + SimpleAlphaShader &shader = gState->simpleAlphaShader(); + shader.bind(); + shader.applyViewportProj(); + shader.setTranslation(Vec2i()); + /* Clear texture */ glClear(GL_COLOR_BUFFER_BIT); /* Repaint base */ - windowskin->flush(); - windowskin->bindTexWithMatrix(); + windowskin->bindTex(shader); TEX::setSmooth(true); - glState.pushSetViewport(baseTex.width, baseTex.height); /* We need to blit the background without blending, * because we want to retain its correct alpha value. @@ -443,12 +446,10 @@ struct WindowPrivate baseQuadArray.draw(backgroundVert.count, baseQuadArray.count()-backgroundVert.count); - glState.blendMode.pop(); - glState.popViewport(); - TEX::setSmooth(false); - glState.clearColor.pop(); - glState.popViewport(); + glState.blendMode.pop(); + glState.viewport.pop(); + TEX::setSmooth(false); } void buildControlsVert() @@ -508,6 +509,12 @@ struct WindowPrivate { bool updateBaseQuadArray = false; + if (windowskin) + windowskin->flush(); + + if (contents) + contents->flush(); + if (baseVertDirty) { buildBaseVert(); @@ -548,28 +555,30 @@ struct WindowPrivate if (size == Vec2i(0, 0)) return; - glPushMatrix(); - glLoadIdentity(); - glTranslatef(position.x + sceneOffset.x, - position.y + sceneOffset.y, 0); + Vec2i trans(position.x + sceneOffset.x, + position.y + sceneOffset.y); + + SimpleAlphaShader &shader = gState->simpleAlphaShader(); + shader.bind(); + shader.applyViewportProj(); + shader.setTranslation(trans); if (useBaseTex) { - TEX::bindWithMatrix(baseTex.tex, baseTex.width, baseTex.height); + shader.setTexSize(Vec2i(baseTex.width, baseTex.height)); + + TEX::bind(baseTex.tex); baseTexQuad.draw(); } else { - windowskin->flush(); - windowskin->bindTexWithMatrix(); + windowskin->bindTex(shader); TEX::setSmooth(true); baseQuadArray.draw(); TEX::setSmooth(false); } - - glPopMatrix(); } void drawControls() @@ -591,10 +600,6 @@ struct WindowPrivate int effectX = position.x + sceneOffset.x; int effectY = position.y + sceneOffset.y; - glPushMatrix(); - glLoadIdentity(); - glTranslatef(effectX, effectY, 0); - IntRect windowRect(effectX, effectY, size.x, size.y); IntRect contentsRect(effectX+16, effectY+16, size.x-32, size.y-32); @@ -602,24 +607,30 @@ struct WindowPrivate glState.scissorBox.push(); glState.scissorBox.setIntersect(windowRect); + SimpleAlphaShader &shader = gState->simpleAlphaShader(); + shader.bind(); + shader.applyViewportProj(); + shader.setTranslation(Vec2i(effectX, effectY)); + /* Draw arrows / cursors */ - windowskin->bindTexWithMatrix(); + windowskin->bindTex(shader); controlsQuadArray.draw(0, controlsQuadCount); if (contents) { /* Draw contents bitmap */ glState.scissorBox.setIntersect(contentsRect); - glTranslatef(16-contentsOffset.x, 16-contentsOffset.y, 0); - contents->flush(); - contents->bindTexWithMatrix(); + effectX += 16-contentsOffset.x; + effectY += 16-contentsOffset.y; + shader.setTranslation(Vec2i(effectX, effectY)); + + contents->bindTex(shader); contentsQuad.draw(); } glState.scissorBox.pop(); glState.scissorTest.pop(); - glPopMatrix(); } void updateControls()