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()