diff --git a/binaries/data/mods/public/shaders/effects/gui_text.xml b/binaries/data/mods/public/shaders/effects/gui_text.xml new file mode 100644 index 0000000000..cc2f8f36db --- /dev/null +++ b/binaries/data/mods/public/shaders/effects/gui_text.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/binaries/data/mods/public/shaders/gui_text.fs b/binaries/data/mods/public/shaders/gui_text.fs new file mode 100644 index 0000000000..0333ee3de0 --- /dev/null +++ b/binaries/data/mods/public/shaders/gui_text.fs @@ -0,0 +1,10 @@ +uniform vec4 colorAdd; +uniform vec4 colorMul; +uniform sampler2D tex; + +varying vec2 v_texcoord; + +void main() +{ + gl_FragColor = (texture2D(tex, v_texcoord) + colorAdd) * colorMul; +} diff --git a/binaries/data/mods/public/shaders/gui_text.vs b/binaries/data/mods/public/shaders/gui_text.vs new file mode 100644 index 0000000000..a27db1f8f8 --- /dev/null +++ b/binaries/data/mods/public/shaders/gui_text.vs @@ -0,0 +1,9 @@ +uniform mat4 transform; + +varying vec2 v_texcoord; + +void main() +{ + gl_Position = transform * gl_Vertex; + v_texcoord = gl_MultiTexCoord0.xy; +} diff --git a/binaries/data/mods/public/shaders/gui_text.xml b/binaries/data/mods/public/shaders/gui_text.xml new file mode 100644 index 0000000000..dd125a9b13 --- /dev/null +++ b/binaries/data/mods/public/shaders/gui_text.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/source/graphics/ShaderManager.cpp b/source/graphics/ShaderManager.cpp index 566fc5a5f2..4a2638eca1 100644 --- a/source/graphics/ShaderManager.cpp +++ b/source/graphics/ShaderManager.cpp @@ -212,6 +212,41 @@ bool CShaderManager::NewProgram(const char* name, const std::map& ba return true; } +static GLenum ParseBlendFunc(const CStr& str) +{ + if (str == "zero") + return GL_ZERO; + if (str == "one") + return GL_ONE; + if (str == "src_color") + return GL_SRC_COLOR; + if (str == "one_minus_src_color") + return GL_ONE_MINUS_SRC_COLOR; + if (str == "dst_color") + return GL_DST_COLOR; + if (str == "one_minus_dst_color") + return GL_ONE_MINUS_DST_COLOR; + if (str == "src_alpha") + return GL_SRC_ALPHA; + if (str == "one_minus_src_alpha") + return GL_ONE_MINUS_SRC_ALPHA; + if (str == "dst_alpha") + return GL_DST_ALPHA; + if (str == "one_minus_dst_alpha") + return GL_ONE_MINUS_DST_ALPHA; + if (str == "constant_color") + return GL_CONSTANT_COLOR; + if (str == "one_minus_constant_color") + return GL_ONE_MINUS_CONSTANT_COLOR; + if (str == "constant_alpha") + return GL_CONSTANT_ALPHA; + if (str == "one_minus_constant_alpha") + return GL_ONE_MINUS_CONSTANT_ALPHA; + if (str == "src_alpha_saturate") + return GL_SRC_ALPHA_SATURATE; + return GL_ZERO; +} + CShaderTechnique CShaderManager::LoadEffect(const char* name, const std::map& baseDefines) { PROFILE2("loading effect"); @@ -229,8 +264,11 @@ CShaderTechnique CShaderManager::LoadEffect(const char* name, const std::map #include "graphics/ShaderProgram.h" +#include "graphics/ShaderTechnique.h" #if USE_SHADER_XML_VALIDATION # include "ps/XML/RelaxNG.h" @@ -31,8 +32,6 @@ #include -class CShaderTechnique; - /** * Shader manager: loads and caches shader programs. */ @@ -48,7 +47,7 @@ public: * @param defines key/value set of preprocessor definitions * @return loaded program, or null pointer on error */ - CShaderProgramPtr LoadProgram(const char* name, const std::map& defines); + CShaderProgramPtr LoadProgram(const char* name, const std::map& defines = std::map()); /** * Load a shader effect. @@ -57,7 +56,7 @@ public: * @param defines key/value set of preprocessor definitions * @return loaded technique, or empty technique on error */ - CShaderTechnique LoadEffect(const char* name, const std::map& defines); + CShaderTechnique LoadEffect(const char* name, const std::map& defines = std::map()); private: bool NewProgram(const char* name, const std::map& defines, CShaderProgramPtr& program); diff --git a/source/graphics/ShaderProgram.cpp b/source/graphics/ShaderProgram.cpp index 24f536f245..59d6c4618e 100644 --- a/source/graphics/ShaderProgram.cpp +++ b/source/graphics/ShaderProgram.cpp @@ -173,6 +173,11 @@ public: } } + virtual int GetTextureUnit(texture_id_t id) + { + return GetUniformFragmentIndex(id); + } + virtual Binding GetUniformBinding(uniform_id_t id) { return Binding(GetUniformVertexIndex(id), GetUniformFragmentIndex(id)); @@ -438,6 +443,15 @@ public: glBindTexture(it->second.first, tex); } + virtual int GetTextureUnit(texture_id_t id) + { + std::map >::iterator it = m_Samplers.find(id); + if (it == m_Samplers.end()) + return -1; + + return it->second.second; + } + virtual Binding GetUniformBinding(uniform_id_t id) { int loc = GetUniformLocation(id); diff --git a/source/graphics/ShaderProgram.h b/source/graphics/ShaderProgram.h index 6baed6ce85..56e12af62f 100644 --- a/source/graphics/ShaderProgram.h +++ b/source/graphics/ShaderProgram.h @@ -149,6 +149,8 @@ public: virtual void BindTexture(texture_id_t id, GLuint tex) = 0; + virtual int GetTextureUnit(texture_id_t) = 0; + virtual Binding GetUniformBinding(uniform_id_t id) = 0; // Uniform-setting methods that subclasses must define: diff --git a/source/graphics/ShaderProgramFFP.cpp b/source/graphics/ShaderProgramFFP.cpp index 0a816d63cc..913853ddd4 100644 --- a/source/graphics/ShaderProgramFFP.cpp +++ b/source/graphics/ShaderProgramFFP.cpp @@ -20,6 +20,7 @@ #include "ShaderProgram.h" #include "lib/res/graphics/ogl_tex.h" +#include "maths/Matrix3D.h" #include "maths/Vector3D.h" #include "ps/CLogger.h" #include "ps/Overlay.h" @@ -82,6 +83,11 @@ public: } } + virtual int GetTextureUnit(texture_id_t id) + { + return GetUniformIndex(id); + } + virtual Binding GetUniformBinding(uniform_id_t id) { return Binding(-1, GetUniformIndex(id)); @@ -91,6 +97,8 @@ protected: std::map m_UniformIndexes; }; +////////////////////////////////////////////////////////////////////////// + class CShaderProgramFFP_OverlayLine : public CShaderProgramFFP { // Uniforms @@ -248,10 +256,79 @@ public: } }; +////////////////////////////////////////////////////////////////////////// + +class CShaderProgramFFP_GuiText : public CShaderProgramFFP +{ + // Uniforms + enum + { + ID_transform, + ID_colorMul + }; + + bool m_IgnoreLos; + +public: + CShaderProgramFFP_GuiText() : + CShaderProgramFFP(STREAM_POS | STREAM_UV0) + { + m_UniformIndexes["transform"] = ID_transform; + m_UniformIndexes["colorMul"] = ID_colorMul; + + // Texture units: + m_UniformIndexes["tex"] = 0; + } + + virtual void Uniform(Binding id, float v0, float v1, float v2, float v3) + { + if (id.second == ID_colorMul) + { + glColor4f(v0, v1, v2, v3); + } + } + + virtual void Uniform(Binding id, const CMatrix3D& v) + { + if (id.second == ID_transform) + { + glLoadMatrixf(&v._11); + } + } + + virtual void Bind() + { + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + pglActiveTextureARB(GL_TEXTURE0); + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + + virtual void Unbind() + { + pglActiveTextureARB(GL_TEXTURE0); + glDisable(GL_TEXTURE_2D); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } +}; + +////////////////////////////////////////////////////////////////////////// + /*static*/ CShaderProgram* CShaderProgram::ConstructFFP(const std::string& id, const std::map& defines) { if (id == "overlayline") return new CShaderProgramFFP_OverlayLine(defines); + if (id == "gui_text") + return new CShaderProgramFFP_GuiText(); LOGERROR(L"CShaderProgram::ConstructFFP: Invalid id '%hs'", id.c_str()); return NULL; diff --git a/source/graphics/ShaderTechnique.cpp b/source/graphics/ShaderTechnique.cpp index 0a57a49527..24b7bf6337 100644 --- a/source/graphics/ShaderTechnique.cpp +++ b/source/graphics/ShaderTechnique.cpp @@ -146,5 +146,4 @@ CShaderProgramPtr CShaderTechnique::GetShader(int pass) { ENSURE(0 <= pass && pass < (int)m_Passes.size()); return m_Passes[pass].GetShader(); - } diff --git a/source/graphics/TextRenderer.cpp b/source/graphics/TextRenderer.cpp index 68b11d516f..1b8588c710 100644 --- a/source/graphics/TextRenderer.cpp +++ b/source/graphics/TextRenderer.cpp @@ -23,9 +23,10 @@ #include "lib/res/graphics/unifont.h" #include "ps/Font.h" -extern int g_yres; +extern int g_xres, g_yres; -CTextRenderer::CTextRenderer() +CTextRenderer::CTextRenderer(const CShaderProgramPtr& shader) : + m_Shader(shader) { ResetTransform(); Color(CColor(1.0f, 1.0f, 1.0f, 1.0f)); @@ -37,6 +38,10 @@ void CTextRenderer::ResetTransform() m_Transform.SetIdentity(); m_Transform.Scale(1.0f, -1.f, 1.0f); m_Transform.Translate(0.0f, (float)g_yres, -1000.0f); + + CMatrix3D proj; + proj.SetOrtho(0.f, (float)g_xres, 0.f, (float)g_yres, -1.f, 1000.f); + m_Transform = proj * m_Transform; } CMatrix3D CTextRenderer::GetTransform() @@ -101,16 +106,24 @@ void CTextRenderer::Render() { SBatch& batch = m_Batches[i]; - batch.font->Bind(); + int unit = m_Shader->GetTextureUnit("tex"); + if (unit == -1) // just in case the shader doesn't use the sampler + continue; - glPushMatrix(); - glLoadMatrixf(&batch.transform._11); + batch.font->Bind(unit); - glColor4fv(batch.color.FloatArray()); - - glwprintf(L"%ls", batch.text.c_str()); + m_Shader->Uniform("transform", batch.transform); - glPopMatrix(); + // ALPHA-only textures will have .rgb sampled as 0, so we need to + // replace it with white (but not affect RGBA textures) + if (batch.font->HasRGB()) + m_Shader->Uniform("colorAdd", CColor(0.0f, 0.0f, 0.0f, 0.0f)); + else + m_Shader->Uniform("colorAdd", CColor(1.0f, 1.0f, 1.0f, 0.0f)); + + m_Shader->Uniform("colorMul", batch.color); + + unifont_render(batch.text.c_str()); } m_Batches.clear(); diff --git a/source/graphics/TextRenderer.h b/source/graphics/TextRenderer.h index 22394601a2..394010c617 100644 --- a/source/graphics/TextRenderer.h +++ b/source/graphics/TextRenderer.h @@ -18,6 +18,7 @@ #ifndef INCLUDED_TEXTRENDERER #define INCLUDED_TEXTRENDERER +#include "graphics/ShaderProgram.h" #include "maths/Matrix3D.h" #include "ps/CStr.h" #include "ps/Overlay.h" @@ -27,7 +28,7 @@ class CFont; class CTextRenderer { public: - CTextRenderer(); + CTextRenderer(const CShaderProgramPtr& shader); void ResetTransform(); CMatrix3D GetTransform(); @@ -51,6 +52,8 @@ private: std::wstring text; }; + CShaderProgramPtr m_Shader; + CMatrix3D m_Transform; CColor m_Color; diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index 9628cada66..5e063f8a6e 100644 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -43,6 +43,7 @@ CGUI #include "MiniMap.h" #include "scripting/JSInterface_GUITypes.h" +#include "graphics/ShaderManager.h" #include "graphics/TextRenderer.h" #include "lib/input.h" #include "lib/bits.h" @@ -57,6 +58,7 @@ CGUI #include "ps/Profile.h" #include "ps/Pyrogenesis.h" #include "ps/XML/Xeromyces.h" +#include "renderer/Renderer.h" #include "scripting/ScriptingHost.h" #include "scriptinterface/ScriptInterface.h" @@ -902,18 +904,9 @@ SGUIText CGUI::GenerateText(const CGUIString &string, void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor, const CPos &pos, const float &z, const CRect &clipping) { - // TODO Gee: All these really necessary? Some - // are defaults and if you changed them - // the opposite value at the end of the functions, - // some things won't be drawn correctly. - glEnable(GL_TEXTURE_2D); - glDisable(GL_CULL_FACE); + CShaderTechnique tech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + tech.BeginPass(0); if (clipping != CRect()) { @@ -921,7 +914,7 @@ void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor, glScissor(clipping.left, g_yres - clipping.bottom, clipping.GetWidth(), clipping.GetHeight()); } - CTextRenderer textRenderer; + CTextRenderer textRenderer(tech.GetShader(0)); for (std::vector::const_iterator it = Text.m_TextCalls.begin(); it != Text.m_TextCalls.end(); @@ -952,7 +945,7 @@ void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor, if (clipping != CRect()) glDisable(GL_SCISSOR_TEST); - glDisable(GL_TEXTURE_2D); + tech.EndPass(0); } bool CGUI::GetPreDefinedColor(const CStr& name, CColor &Output) diff --git a/source/gui/CInput.cpp b/source/gui/CInput.cpp index 2ca034b4e6..9a56c81603 100644 --- a/source/gui/CInput.cpp +++ b/source/gui/CInput.cpp @@ -24,6 +24,7 @@ CInput #include "CInput.h" #include "CGUIScrollBarVertical.h" +#include "graphics/ShaderManager.h" #include "graphics/TextRenderer.h" #include "lib/ogl.h" #include "lib/res/graphics/unifont.h" @@ -32,6 +33,7 @@ CInput #include "ps/Font.h" #include "ps/Globals.h" #include "ps/Hotkey.h" +#include "renderer/Renderer.h" #include @@ -1078,7 +1080,9 @@ void CInput::Draw() float h = (float)font.GetHeight(); float ls = (float)font.GetLineSpacing(); - CTextRenderer textRenderer; + CShaderTechnique tech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); + + CTextRenderer textRenderer(tech.GetShader(0)); textRenderer.Font(font_name); // Set the Z to somewhat more, so we can draw a selected area between the @@ -1243,13 +1247,7 @@ void CInput::Draw() // Setup initial color (then it might change and change back, when drawing selected area) textRenderer.Color(color); - // Setup state for text rendering - - glEnable(GL_TEXTURE_2D); - glDisable(GL_CULL_FACE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + tech.BeginPass(0); bool using_selected_color = false; @@ -1351,7 +1349,7 @@ void CInput::Draw() if (cliparea != CRect()) glDisable(GL_SCISSOR_TEST); - glDisable(GL_TEXTURE_2D); + tech.EndPass(0); } } diff --git a/source/gui/GUIRenderer.cpp b/source/gui/GUIRenderer.cpp index 4b18ddc50a..a3c46be799 100644 --- a/source/gui/GUIRenderer.cpp +++ b/source/gui/GUIRenderer.cpp @@ -634,18 +634,18 @@ void GUIRenderer::Draw(DrawCalls &Calls, float Z) glBegin(GL_QUADS); - glTexCoord2f(TexCoords.right, TexCoords.bottom); - glVertex3f(cit->m_Vertices.right, cit->m_Vertices.bottom, cit->m_DeltaZ); - glTexCoord2f(TexCoords.left, TexCoords.bottom); glVertex3f(cit->m_Vertices.left, cit->m_Vertices.bottom, cit->m_DeltaZ); - glTexCoord2f(TexCoords.left, TexCoords.top); - glVertex3f(cit->m_Vertices.left, cit->m_Vertices.top, cit->m_DeltaZ); + glTexCoord2f(TexCoords.right, TexCoords.bottom); + glVertex3f(cit->m_Vertices.right, cit->m_Vertices.bottom, cit->m_DeltaZ); glTexCoord2f(TexCoords.right, TexCoords.top); glVertex3f(cit->m_Vertices.right, cit->m_Vertices.top, cit->m_DeltaZ); + glTexCoord2f(TexCoords.left, TexCoords.top); + glVertex3f(cit->m_Vertices.left, cit->m_Vertices.top, cit->m_DeltaZ); + glEnd(); if (cit->m_Effects) @@ -664,10 +664,10 @@ void GUIRenderer::Draw(DrawCalls &Calls, float Z) glColor4fv(cit->m_BackColor.FloatArray()); glBegin(GL_QUADS); - glVertex3f(cit->m_Vertices.right, cit->m_Vertices.bottom, cit->m_DeltaZ); glVertex3f(cit->m_Vertices.left, cit->m_Vertices.bottom, cit->m_DeltaZ); - glVertex3f(cit->m_Vertices.left, cit->m_Vertices.top, cit->m_DeltaZ); + glVertex3f(cit->m_Vertices.right, cit->m_Vertices.bottom, cit->m_DeltaZ); glVertex3f(cit->m_Vertices.right, cit->m_Vertices.top, cit->m_DeltaZ); + glVertex3f(cit->m_Vertices.left, cit->m_Vertices.top, cit->m_DeltaZ); glEnd(); diff --git a/source/lib/res/graphics/unifont.cpp b/source/lib/res/graphics/unifont.cpp index 913fe671e0..726b48f9f1 100644 --- a/source/lib/res/graphics/unifont.cpp +++ b/source/lib/res/graphics/unifont.cpp @@ -50,6 +50,8 @@ struct UniFont { Handle ht; // Handle to font texture + bool HasRGB; // true if RGBA, false if ALPHA + glyphmap* glyphs; int LineSpacing; @@ -102,9 +104,15 @@ static Status UniFont_reload(UniFont* f, const PIVFS& vfs, const VfsPath& basena std::string Format; FNTStream >> Format; if (Format == "rgba") + { + f->HasRGB = true; fmt_ovr = GL_RGBA; + } else if (Format == "a") + { + f->HasRGB = false; fmt_ovr = GL_ALPHA; + } else debug_warn(L"Invalid .fnt format string"); } @@ -214,11 +222,11 @@ Status unifont_unload(Handle& h) } -Status unifont_bind(const Handle h) +Status unifont_bind(const Handle h, size_t unit) { H_DEREF(h, UniFont, f); - ogl_tex_bind(f->ht); + ogl_tex_bind(f->ht, unit); BoundGlyphs = f->glyphs; return INFO::OK; @@ -239,6 +247,15 @@ int unifont_height(const Handle h) } +bool unifont_has_rgb(const Handle h) +{ + UniFont* const f = H_USER_DATA(h, UniFont); + if(!f) + return false; + return f->HasRGB; +} + + int unifont_character_width(const Handle h, wchar_t c) { H_DEREF(h, UniFont, f); @@ -270,10 +287,19 @@ void glvwprintf(const wchar_t* fmt, va_list args) // Make sure there's always null termination buf[buf_size-1] = 0; + int advance = 0; + unifont_render(buf, &advance); + + // Move into position for subsequent prints + glTranslatef((float)advance, 0, 0); +} + +void unifont_render(const wchar_t* str, int* advance) +{ ENSURE(BoundGlyphs != NULL); // You always need to bind something first // Count the number of characters - size_t len = wcslen(buf); + size_t len = wcslen(str); // 0 glyphs -> nothing to do (avoid BoundsChecker warning) if (!len) @@ -281,11 +307,11 @@ void glvwprintf(const wchar_t* fmt, va_list args) t2f_v2i* vertexes = new t2f_v2i[len*4]; - i32 x = 0; + i16 x = 0; for (size_t i = 0; i < len; ++i) { - glyphmap::iterator it = BoundGlyphs->find(buf[i]); + glyphmap::iterator it = BoundGlyphs->find(str[i]); if (it == BoundGlyphs->end()) it = BoundGlyphs->find(0xFFFD); // Use the missing glyph symbol @@ -295,24 +321,24 @@ void glvwprintf(const wchar_t* fmt, va_list args) const GlyphData& g = it->second; - vertexes[i*4].u = g.u0; + vertexes[i*4].u = g.u1; vertexes[i*4].v = g.v0; - vertexes[i*4].x = g.x0 + x; + vertexes[i*4].x = g.x1 + x; vertexes[i*4].y = g.y0; - vertexes[i*4+1].u = g.u1; + vertexes[i*4+1].u = g.u0; vertexes[i*4+1].v = g.v0; - vertexes[i*4+1].x = g.x1 + x; + vertexes[i*4+1].x = g.x0 + x; vertexes[i*4+1].y = g.y0; - vertexes[i*4+2].u = g.u1; + vertexes[i*4+2].u = g.u0; vertexes[i*4+2].v = g.v1; - vertexes[i*4+2].x = g.x1 + x; + vertexes[i*4+2].x = g.x0 + x; vertexes[i*4+2].y = g.y1; - vertexes[i*4+3].u = g.u0; + vertexes[i*4+3].u = g.u1; vertexes[i*4+3].v = g.v1; - vertexes[i*4+3].x = g.x0 + x; + vertexes[i*4+3].x = g.x1 + x; vertexes[i*4+3].y = g.y1; x += g.xadvance; @@ -335,11 +361,11 @@ void glvwprintf(const wchar_t* fmt, va_list args) glDisableClientState(GL_TEXTURE_COORD_ARRAY); ogl_WarnIfError(); - - // Move into position for subsequent prints - glTranslatef((float)x, 0, 0); #endif + if (advance) + *advance = x; + delete[] vertexes; } diff --git a/source/lib/res/graphics/unifont.h b/source/lib/res/graphics/unifont.h index bdf5ce26dd..bd8fd6740b 100644 --- a/source/lib/res/graphics/unifont.h +++ b/source/lib/res/graphics/unifont.h @@ -53,7 +53,7 @@ extern Status unifont_unload(Handle& h); * * Must be called before any glwprintf(). **/ -extern Status unifont_bind(Handle h); +extern Status unifont_bind(Handle h, size_t unit); /** * Output text at current OpenGL modelview pos. @@ -79,6 +79,11 @@ extern void glwprintf(const wchar_t* fmt, ...) WPRINTF_ARGS(1); **/ extern void glvwprintf(const wchar_t* fmt, va_list args) VWPRINTF_ARGS(1); +/** + * Output text, and return advance distance (if @p advance not NULL). + */ +extern void unifont_render(const wchar_t* str, int* advance = NULL); + /** * Determine pixel extents of a string. * @@ -92,6 +97,11 @@ extern void glvwprintf(const wchar_t* fmt, va_list args) VWPRINTF_ARGS(1); **/ Status unifont_stringsize(const Handle h, const wchar_t* text, int& width, int& height); +/** + * @return whether the font is an RGBA texture, not an ALPHA texture. + **/ +bool unifont_has_rgb(const Handle h); + /** * @return height [pixels] of the font. **/ diff --git a/source/maths/Matrix3D.cpp b/source/maths/Matrix3D.cpp index 8e38024553..f6ebbfcd7d 100644 --- a/source/maths/Matrix3D.cpp +++ b/source/maths/Matrix3D.cpp @@ -44,6 +44,17 @@ void CMatrix3D::SetZero () _41=0.0f; _42=0.0f; _43=0.0f; _44=0.0f; } +void CMatrix3D::SetOrtho (float l, float r, float b, float t, float n, float f) +{ + // Based on OpenGL spec + *this = CMatrix3D( + 2/(r-l), 0, 0, -(r+l)/(r-l), + 0, 2/(t-b), 0, -(t+b)/(t-b), + 0, 0, -2/(f-n), -(f+n)/(f-n), + 0, 0, 0, 1 + ); +} + //The following clear the matrix and set the //rotation of each of the 3 axes diff --git a/source/maths/Matrix3D.h b/source/maths/Matrix3D.h index 7e6855d318..ed9a2840ec 100644 --- a/source/maths/Matrix3D.h +++ b/source/maths/Matrix3D.h @@ -177,6 +177,8 @@ public: void SetIdentity(); // set this matrix to the zero matrix void SetZero(); + // set this matrix to the orthogonal projection matrix (as with glOrtho) + void SetOrtho(float l, float r, float b, float t, float n, float f); // concatenate arbitrary matrix onto this matrix void Concatenate(const CMatrix3D& m) diff --git a/source/ps/Font.cpp b/source/ps/Font.cpp index 844be17260..0a15fe9b54 100644 --- a/source/ps/Font.cpp +++ b/source/ps/Font.cpp @@ -48,9 +48,14 @@ CFont::~CFont() unifont_unload(h); } -void CFont::Bind() +void CFont::Bind(size_t unit) { - unifont_bind(h); + unifont_bind(h, unit); +} + +bool CFont::HasRGB() +{ + return unifont_has_rgb(h); } int CFont::GetLineSpacing() diff --git a/source/ps/Font.h b/source/ps/Font.h index 32055c0e29..016cfc92ff 100644 --- a/source/ps/Font.h +++ b/source/ps/Font.h @@ -38,7 +38,8 @@ public: CFont(const CStrW& name); ~CFont(); - void Bind(); + void Bind(size_t unit = 0); + bool HasRGB(); int GetLineSpacing(); int GetHeight(); int GetCharacterWidth(wchar_t c); diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index f252c0367b..8e335eee32 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -226,7 +226,6 @@ void Render() // set up overlay mode glPushAttrib(GL_ENABLE_BIT); glEnable(GL_TEXTURE_2D); - glDisable(GL_CULL_FACE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); diff --git a/source/ps/ProfileViewer.cpp b/source/ps/ProfileViewer.cpp index 0d673e3a4a..24377e4fd4 100644 --- a/source/ps/ProfileViewer.cpp +++ b/source/ps/ProfileViewer.cpp @@ -188,10 +188,10 @@ void CProfileViewer::RenderProfile() glDisable(GL_TEXTURE_2D); glColor4ub(0,0,0,128); glBegin(GL_QUADS); - glVertex2i(0, g_yres); glVertex2i(estimate_width, g_yres); - glVertex2i(estimate_width, g_yres-estimate_height); + glVertex2i(0, g_yres); glVertex2i(0, g_yres-estimate_height); + glVertex2i(estimate_width, g_yres-estimate_height); glEnd(); glEnable(GL_TEXTURE_2D); diff --git a/source/renderer/OverlayRenderer.cpp b/source/renderer/OverlayRenderer.cpp index b33c6a7904..53d6b59ce2 100644 --- a/source/renderer/OverlayRenderer.cpp +++ b/source/renderer/OverlayRenderer.cpp @@ -209,7 +209,7 @@ void OverlayRenderer::RenderOverlaysAfterWater() CLOSTexture& los = g_Renderer.GetScene().GetLOSTexture(); CShaderManager& shaderManager = g_Renderer.GetShaderManager(); - CShaderProgramPtr shaderTexLineNormal(shaderManager.LoadProgram(shaderName, std::map())); + CShaderProgramPtr shaderTexLineNormal(shaderManager.LoadProgram(shaderName)); CShaderProgramPtr shaderTexLineAlwaysVisible(shaderManager.LoadProgram(shaderName, defAlwaysVisible)); // ---------------------------------------------------------------------------------------- diff --git a/source/renderer/ParticleRenderer.cpp b/source/renderer/ParticleRenderer.cpp index 1aa7b95459..ccbf3ff346 100644 --- a/source/renderer/ParticleRenderer.cpp +++ b/source/renderer/ParticleRenderer.cpp @@ -86,10 +86,8 @@ void ParticleRenderer::PrepareForRendering() // RenderParticles will never be called so it's safe to leave the shaders as null if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) { - typedef std::map Defines; - Defines defNull; - m->shader = g_Renderer.GetShaderManager().LoadProgram("particle", defNull); - m->shaderSolid = g_Renderer.GetShaderManager().LoadProgram("particle_solid", defNull); + m->shader = g_Renderer.GetShaderManager().LoadProgram("particle"); + m->shaderSolid = g_Renderer.GetShaderManager().LoadProgram("particle_solid"); } } diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 493cd636df..72a78b06cc 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -50,7 +50,6 @@ #include "graphics/ModelDef.h" #include "graphics/ParticleManager.h" #include "graphics/ShaderManager.h" -#include "graphics/ShaderTechnique.h" #include "graphics/Terrain.h" #include "graphics/Texture.h" #include "graphics/TextureManager.h"