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.
This commit is contained in:
Jonas Kulla 2013-09-23 07:15:01 +02:00
parent 88c1489554
commit 9e63fb6b64
29 changed files with 701 additions and 295 deletions

View File

@ -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);

View File

@ -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;
}

36
shader/plane.frag Normal file
View File

@ -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;
}

9
shader/simple.frag Normal file
View File

@ -0,0 +1,9 @@
uniform sampler2D texture;
varying vec2 v_texCoord;
void main()
{
gl_FragColor = texture2D(texture, v_texCoord);
}

18
shader/simple.vert Normal file
View File

@ -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;
}

11
shader/simpleAlpha.frag Normal file
View File

@ -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;
}

7
shader/simpleColor.frag Normal file
View File

@ -0,0 +1,7 @@
varying vec4 v_color;
void main()
{
gl_FragColor = v_color;
}

20
shader/simpleColor.vert Normal file
View File

@ -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;
}

View File

@ -5,19 +5,18 @@ uniform vec4 tone;
uniform float opacity;
uniform vec4 color;
uniform vec4 flash;
uniform float bushDepth;
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;

17
shader/sprite.vert Normal file
View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

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

View File

@ -29,6 +29,7 @@
#include "sigc++/signal.h"
class Font;
class ShaderBase;
struct TEXFBO;
struct BitmapPrivate;
@ -103,7 +104,10 @@ public:
/* <internal> */
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<void> modified;

View File

@ -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; };

View File

@ -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;

View File

@ -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 &currentSizeOut)
void GlobalState::ensureTexSize(int minW, int minH, Vec2i &currentSizeOut)
{
if (minW > p->globalTexW)
p->globalTexW = findNextPow2(minW);
@ -215,7 +224,7 @@ void GlobalState::ensureTexSize(int minW, int minH, Vec2 &currentSizeOut)
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)

View File

@ -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 &currentSizeOut);
void ensureTexSize(int minW, int minH, Vec2i &currentSizeOut);
TEXFBO &gpTexFBO(int minW, int minH);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

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

View File

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

View File

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

View File

@ -20,72 +20,113 @@
*/
#include "shader.h"
#include "globalstate.h"
#include "glstate.h"
#include "GL/glew.h"
#include <QFile>
#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);

View File

@ -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<Vec2i>
{
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();

View File

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

View File

@ -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();
}

View File

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