diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg index 107e7fc86b..a2ddc1343f 100644 --- a/binaries/data/config/default.cfg +++ b/binaries/data/config/default.cfg @@ -40,6 +40,9 @@ noautomipmap = true novbo = false noframebufferobject = false +; Disable hardware cursors +nohwcursor = false + ; Linux only: Set the driconf force_s3tc_enable option at startup, ; for compressed texture support force_s3tc_enable = true diff --git a/source/graphics/ShaderTechnique.h b/source/graphics/ShaderTechnique.h index 72691976a5..db887cbf80 100644 --- a/source/graphics/ShaderTechnique.h +++ b/source/graphics/ShaderTechnique.h @@ -85,9 +85,9 @@ public: int GetNumPasses(); - void BeginPass(int pass); - void EndPass(int pass); - CShaderProgramPtr GetShader(int pass); + void BeginPass(int pass = 0); + void EndPass(int pass = 0); + CShaderProgramPtr GetShader(int pass = 0); void Reset(); diff --git a/source/graphics/TextRenderer.cpp b/source/graphics/TextRenderer.cpp index bebb240acb..700577717b 100644 --- a/source/graphics/TextRenderer.cpp +++ b/source/graphics/TextRenderer.cpp @@ -66,6 +66,11 @@ void CTextRenderer::Color(const CColor& color) m_Color = color; } +void CTextRenderer::Color(float r, float g, float b, float a) +{ + m_Color = CColor(r, g, b, a); +} + void CTextRenderer::Font(const CStrW& font) { if (!m_Fonts[font]) diff --git a/source/graphics/TextRenderer.h b/source/graphics/TextRenderer.h index d4cc60e6ae..0079674429 100644 --- a/source/graphics/TextRenderer.h +++ b/source/graphics/TextRenderer.h @@ -46,6 +46,11 @@ public: */ void Color(const CColor& color); + /** + * Set the color for subsequent print calls. + */ + void Color(float r, float g, float b, float a = 1.0); + /** * Set the font for subsequent print calls. */ diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index b7a547809d..16875c0a40 100644 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -913,7 +913,7 @@ void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor, { CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); - tech->BeginPass(0); + tech->BeginPass(); if (clipping != CRect()) { @@ -921,7 +921,7 @@ void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor, glScissor(clipping.left, g_yres - clipping.bottom, clipping.GetWidth(), clipping.GetHeight()); } - CTextRenderer textRenderer(tech->GetShader(0)); + CTextRenderer textRenderer(tech->GetShader()); for (std::vector::const_iterator it = Text.m_TextCalls.begin(); it != Text.m_TextCalls.end(); @@ -952,7 +952,7 @@ void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor, if (clipping != CRect()) glDisable(GL_SCISSOR_TEST); - tech->EndPass(0); + tech->EndPass(); } bool CGUI::GetPreDefinedColor(const CStr& name, CColor &Output) diff --git a/source/gui/CInput.cpp b/source/gui/CInput.cpp index 2c5debf43b..fd49327e53 100644 --- a/source/gui/CInput.cpp +++ b/source/gui/CInput.cpp @@ -1082,7 +1082,7 @@ void CInput::Draw() CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); - CTextRenderer textRenderer(tech->GetShader(0)); + CTextRenderer textRenderer(tech->GetShader()); textRenderer.Font(font_name); // Set the Z to somewhat more, so we can draw a selected area between the @@ -1247,7 +1247,7 @@ void CInput::Draw() // Setup initial color (then it might change and change back, when drawing selected area) textRenderer.Color(color); - tech->BeginPass(0); + tech->BeginPass(); bool using_selected_color = false; @@ -1349,7 +1349,7 @@ void CInput::Draw() if (cliparea != CRect()) glDisable(GL_SCISSOR_TEST); - tech->EndPass(0); + tech->EndPass(); } } diff --git a/source/gui/GUIRenderer.cpp b/source/gui/GUIRenderer.cpp index 34b92334ea..fe22758153 100644 --- a/source/gui/GUIRenderer.cpp +++ b/source/gui/GUIRenderer.cpp @@ -311,11 +311,12 @@ void GUIRenderer::Draw(DrawCalls &Calls, float Z) // Iterate through each DrawCall, and execute whatever drawing code is being called for (DrawCalls::const_iterator cit = Calls.begin(); cit != Calls.end(); ++cit) { + cit->m_Shader->BeginPass(); + CShaderProgramPtr shader = cit->m_Shader->GetShader(); + shader->Uniform("transform", matrix); + if (cit->m_HasTexture) { - cit->m_Shader->BeginPass(0); - CShaderProgramPtr shader = cit->m_Shader->GetShader(0); - shader->Uniform("transform", matrix); shader->Uniform("color", cit->m_ShaderColorParameter); shader->BindTexture("tex", cit->m_Texture); @@ -354,14 +355,9 @@ void GUIRenderer::Draw(DrawCalls &Calls, float Z) shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 5*sizeof(float), &data[0]); shader->VertexPointer(3, GL_FLOAT, 5*sizeof(float), &data[2]); glDrawArrays(GL_TRIANGLES, 0, 6); - - cit->m_Shader->EndPass(0); } else { - cit->m_Shader->BeginPass(0); - CShaderProgramPtr shader = cit->m_Shader->GetShader(0); - shader->Uniform("transform", matrix); shader->Uniform("color", cit->m_BackColor); if (cit->m_EnableBlending) @@ -404,9 +400,9 @@ void GUIRenderer::Draw(DrawCalls &Calls, float Z) glDrawArrays(GL_LINE_LOOP, 0, 4); } #undef ADD - - cit->m_Shader->EndPass(0); } + + cit->m_Shader->EndPass(); glDisable(GL_BLEND); } diff --git a/source/lib/res/graphics/cursor.cpp b/source/lib/res/graphics/cursor.cpp index 8d9039baf2..305a053599 100644 --- a/source/lib/res/graphics/cursor.cpp +++ b/source/lib/res/graphics/cursor.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010 Wildfire Games +/* Copyright (c) 2012 Wildfire Games * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -152,6 +152,9 @@ enum CursorKind struct Cursor { + // require kind == CK_OpenGL after reload + bool forceGL; + CursorKind kind; // valid iff kind == CK_System @@ -164,8 +167,9 @@ struct Cursor H_TYPE_DEFINE(Cursor); -static void Cursor_init(Cursor* UNUSED(c), va_list UNUSED(args)) +static void Cursor_init(Cursor* c, va_list args) { + c->forceGL = va_arg(args, bool); } static void Cursor_dtor(Cursor* c) @@ -208,7 +212,7 @@ static Status Cursor_reload(Cursor* c, const PIVFS& vfs, const VfsPath& name, Ha const VfsPath pathnameImage = pathname.ChangeExtension(L".png"); // try loading as system cursor (2d, hardware accelerated) - if(load_sys_cursor(vfs, pathnameImage, hotspotx, hotspoty, &c->system_cursor) == INFO::OK) + if(!c->forceGL && load_sys_cursor(vfs, pathnameImage, hotspotx, hotspoty, &c->system_cursor) == INFO::OK) c->kind = CK_System; // fall back to GLCursor (system cursor code is disabled or failed) else if(c->gl_cursor.create(vfs, pathnameImage, hotspotx, hotspoty) == INFO::OK) @@ -282,9 +286,9 @@ static Status Cursor_to_string(const Cursor* c, wchar_t* buf) // in other words, we continually create/free the cursor resource in // cursor_draw and trust h_mgr's caching to absorb it. -static Handle cursor_load(const PIVFS& vfs, const VfsPath& name) +static Handle cursor_load(const PIVFS& vfs, const VfsPath& name, bool forceGL) { - return h_alloc(H_Cursor, vfs, name, 0); + return h_alloc(H_Cursor, vfs, name, 0, forceGL); } static Status cursor_free(Handle& h) @@ -293,7 +297,7 @@ static Status cursor_free(Handle& h) } -Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y) +Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y, bool forceGL) { // hide the cursor if(!name) @@ -302,7 +306,9 @@ Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y) return INFO::OK; } - Handle hc = cursor_load(vfs, name); + Handle hc = cursor_load(vfs, name, forceGL); + // TODO: if forceGL changes at runtime after a cursor is first created, + // we might reuse a cached version of the cursor with the old forceGL flag RETURN_STATUS_IF_ERR(hc); // silently ignore failures diff --git a/source/lib/res/graphics/cursor.h b/source/lib/res/graphics/cursor.h index 9b034a4a39..4bd0aee34a 100644 --- a/source/lib/res/graphics/cursor.h +++ b/source/lib/res/graphics/cursor.h @@ -39,10 +39,11 @@ * mouse Y coordinate to be subtracted from the client area height. * Making the caller responsible for this avoids a dependency on * the g_yres global variable.) + * @param forceGL Require the OpenGL cursor implementation, not hardware cursor * * Uses a hardware mouse cursor where available, otherwise a * portable OpenGL implementation. **/ -extern Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y); +extern Status cursor_draw(const PIVFS& vfs, const wchar_t* name, int x, int y, bool forceGL); #endif // #ifndef INCLUDED_GRAPHICS_CURSOR diff --git a/source/ps/CConsole.cpp b/source/ps/CConsole.cpp index 7c35b24de5..fe009f5509 100644 --- a/source/ps/CConsole.cpp +++ b/source/ps/CConsole.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2012 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,6 +24,9 @@ #include "CConsole.h" +#include "graphics/ShaderManager.h" +#include "graphics/TextRenderer.h" +#include "gui/GUIutil.h" #include "lib/ogl.h" #include "lib/res/graphics/unifont.h" #include "lib/sysdep/clipboard.h" @@ -36,6 +39,7 @@ #include "ps/Globals.h" #include "ps/Hotkey.h" #include "ps/Pyrogenesis.h" +#include "renderer/Renderer.h" #include "scripting/ScriptingHost.h" #include "scriptinterface/ScriptInterface.h" @@ -52,7 +56,7 @@ CConsole::CConsole() FlushBuffer(); m_iMsgHistPos = 1; - m_charsPerPage=0; + m_charsPerPage = 0; InsertMessage(L"[ 0 A.D. Console v0.14 ]"); InsertMessage(L""); @@ -60,8 +64,6 @@ CConsole::CConsole() CConsole::~CConsole() { - m_deqMsgHistory.clear(); - m_deqBufHistory.clear(); delete[] m_szBuffer; } @@ -77,7 +79,7 @@ void CConsole::SetSize(float X, float Y, float W, float H) void CConsole::UpdateScreenSize(int w, int h) { float height = h * 0.6f; - SetSize(0, h-height, (float)w, height); + SetSize(0, 0, (float)w, height); } @@ -87,14 +89,14 @@ void CConsole::ToggleVisible() m_bVisible = !m_bVisible; } -void CConsole::SetVisible( bool visible ) +void CConsole::SetVisible(bool visible) { - if( visible != m_bVisible ) + if (visible != m_bVisible) m_bToggle = true; m_bVisible = visible; } -void CConsole::FlushBuffer(void) +void CConsole::FlushBuffer() { // Clear the buffer and set the cursor and length to 0 memset(m_szBuffer, '\0', sizeof(wchar_t) * CONSOLE_BUFFER_SIZE); @@ -180,65 +182,78 @@ void CConsole::Render() CFont font(CONSOLE_FONT); font.Bind(); - // animation: slide in from top of screen - const float MaxY = m_fHeight; - const float DeltaY = (1.0f - m_fVisibleFrac) * MaxY; - - glPushMatrix(); - - glTranslatef(m_fX, m_fY + DeltaY, 0.0f); //Move to window position - glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - DrawWindow(); - DrawHistory(); - DrawBuffer(); + CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect("solid"); + solidTech->BeginPass(); + CShaderProgramPtr solidShader = solidTech->GetShader(); + + CMatrix3D transform = GetDefaultGuiMatrix(); + + // animation: slide in from top of screen + const float DeltaY = (1.0f - m_fVisibleFrac) * m_fHeight; + transform.PostTranslate(m_fX, m_fY - DeltaY, 0.0f); // move to window position + solidShader->Uniform("transform", transform); + + DrawWindow(solidShader); + + solidTech->EndPass(); + + CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); + textTech->BeginPass(); + CTextRenderer textRenderer(textTech->GetShader()); + textRenderer.Font(CONSOLE_FONT); + textRenderer.SetTransform(transform); + + DrawHistory(textRenderer); + DrawBuffer(textRenderer); + + textRenderer.Render(); + + textTech->EndPass(); glDisable(GL_BLEND); - - glPopMatrix(); } -void CConsole::DrawWindow() +void CConsole::DrawWindow(CShaderProgramPtr& shader) { - // TODO: Add texturing - glDisable(GL_TEXTURE_2D); + float boxVerts[] = { + m_fWidth, 0.0f, + 1.0f, 0.0f, + 1.0f, m_fHeight-1.0f, + m_fWidth, m_fHeight-1.0f + }; + + shader->VertexPointer(2, GL_FLOAT, 0, boxVerts); // Draw Background // Set the color to a translucent blue - glColor4f(0.0f, 0.0f, 0.5f, 0.6f); - glBegin(GL_QUADS); - glVertex2f(0.0f, 0.0f); - glVertex2f(m_fWidth-1.0f, 0.0f); - glVertex2f(m_fWidth-1.0f, m_fHeight-1.0f); - glVertex2f(0.0f, m_fHeight-1.0f); - glEnd(); + shader->Uniform("color", 0.0f, 0.0f, 0.5f, 0.6f); + shader->AssertPointersBound(); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); // Draw Border // Set the color to a translucent yellow - glColor4f(0.5f, 0.5f, 0.0f, 0.6f); - glBegin(GL_LINE_LOOP); - glVertex2f(0.0f, 0.0f); - glVertex2f(m_fWidth-1.0f, 0.0f); - glVertex2f(m_fWidth-1.0f, m_fHeight-1.0f); - glVertex2f(0.0f, m_fHeight-1.0f); - glEnd(); + shader->Uniform("color", 0.5f, 0.5f, 0.0f, 0.6f); + shader->AssertPointersBound(); + glDrawArrays(GL_LINE_LOOP, 0, 4); if (m_fHeight > m_iFontHeight + 4) { - glBegin(GL_LINES); - glVertex2f(0.0f, (GLfloat)(m_iFontHeight + 4)); - glVertex2f(m_fWidth, (GLfloat)(m_iFontHeight + 4)); - glEnd(); + float lineVerts[] = { + 0.0f, m_fHeight - (float)m_iFontHeight - 4.0f, + m_fWidth, m_fHeight - (float)m_iFontHeight - 4.0f + }; + shader->VertexPointer(2, GL_FLOAT, 0, lineVerts); + shader->AssertPointersBound(); + glDrawArrays(GL_LINES, 0, 2); } - - glEnable(GL_TEXTURE_2D); } -void CConsole::DrawHistory() +void CConsole::DrawHistory(CTextRenderer& textRenderer) { int i = 1; @@ -246,73 +261,63 @@ void CConsole::DrawHistory() CScopeLock lock(m_Mutex); // needed for safe access to m_deqMsgHistory - glPushMatrix(); - glColor3f(1.0f, 1.0f, 1.0f); //Set color of text - glTranslatef(9.0f, (float)m_iFontOffset, 0.0f); //move away from the border + textRenderer.Color(1.0f, 1.0f, 1.0f); - // Draw the text upside-down, because it's aligned with - // the GUI (which uses the top-left as (0,0)) - glScalef(1.0f, -1.0f, 1.0f); + for (Iter = m_deqMsgHistory.begin(); + Iter != m_deqMsgHistory.end() + && (((i - m_iMsgHistPos + 1) * m_iFontHeight) < m_fHeight); + ++Iter) + { + if (i >= m_iMsgHistPos) + textRenderer.PrintfAt(9.0f, m_fHeight - (float)m_iFontOffset - (float)m_iFontHeight * i, L"%ls", Iter->c_str()); - for (Iter = m_deqMsgHistory.begin(); - Iter != m_deqMsgHistory.end() - && (((i - m_iMsgHistPos + 1) * m_iFontHeight) < m_fHeight); - ++Iter) - { - if (i >= m_iMsgHistPos){ - glTranslatef(0.0f, -(float)m_iFontHeight, 0.0f); - - glPushMatrix(); - glwprintf(L"%ls", Iter->c_str()); - glPopMatrix(); - } - - i++; - } - glPopMatrix(); + i++; + } } -//Renders the buffer to the screen. -void CConsole::DrawBuffer(void) +// Renders the buffer to the screen. +void CConsole::DrawBuffer(CTextRenderer& textRenderer) { - if (m_fHeight < m_iFontHeight) return; + if (m_fHeight < m_iFontHeight) + return; - glPushMatrix(); - glColor3f(1.0f, 1.0f, 0.0f); - glTranslatef(2.0f, (float)m_iFontOffset, 0); - glScalef(1.0f, -1.0f, 1.0f); + CMatrix3D savedTransform = textRenderer.GetTransform(); - glwprintf(L"]"); + textRenderer.Translate(2.0f, m_fHeight - (float)m_iFontOffset + 1.0f, 0.0f); - glColor3f(1.0f, 1.0f, 1.0f); - if (m_iBufferPos==0) DrawCursor(); + textRenderer.Color(1.0f, 1.0f, 0.0f); + textRenderer.Printf(L"]"); - for (int i = 0; i < m_iBufferLength; i++){ - glwprintf(L"%lc", m_szBuffer[i]); - if (m_iBufferPos-1==i) DrawCursor(); - } - glPopMatrix(); + textRenderer.Color(1.0f, 1.0f, 1.0f); + + if (m_iBufferPos == 0) + DrawCursor(textRenderer); + + for (int i = 0; i < m_iBufferLength; i++) + { + textRenderer.Printf(L"%lc", m_szBuffer[i]); + if (m_iBufferPos-1 == i) + DrawCursor(textRenderer); + } + + textRenderer.SetTransform(savedTransform); } - -void CConsole::DrawCursor(void) +void CConsole::DrawCursor(CTextRenderer& textRenderer) { - // (glPushMatrix is necessary because glwprintf does glTranslatef) - glPushMatrix(); - // Slightly translucent yellow - glColor4f(1.0f, 1.0f, 0.0f, 0.8f); + // Slightly translucent yellow + textRenderer.Color(1.0f, 1.0f, 0.0f, 0.8f); - // Cursor character is chosen to be an underscore - glwprintf(L"_"); + // Cursor character is chosen to be an underscore + textRenderer.PrintfAt(0.0f, 0.0f, L"_"); - // Revert to the standard text colour - glColor3f(1.0f, 1.0f, 1.0f); - glPopMatrix(); + // Revert to the standard text colour + textRenderer.Color(1.0f, 1.0f, 1.0f); } //Inserts a character into the buffer. -void CConsole::InsertChar(const int szChar, const wchar_t cooked ) +void CConsole::InsertChar(const int szChar, const wchar_t cooked) { static int iHistoryPos = -1; @@ -335,8 +340,9 @@ void CConsole::InsertChar(const int szChar, const wchar_t cooked ) if (m_iBufferPos == m_iBufferLength) m_szBuffer[m_iBufferPos - 1] = '\0'; - else{ - for(int j=m_iBufferPos-1; j #include #include @@ -29,8 +32,10 @@ #include "ps/CStr.h" #include "ps/ThreadUtil.h" -#ifndef INCLUDED_CCONSOLE -#define INCLUDED_CCONSOLE +class CShaderProgram; +typedef shared_ptr CShaderProgramPtr; + +class CTextRenderer; #define CONSOLE_BUFFER_SIZE 1024 // for text being typed into the console #define CONSOLE_MESSAGE_SIZE 1024 // for messages being printed into the console @@ -54,7 +59,7 @@ public: void UpdateScreenSize(int w, int h); void ToggleVisible(); - void SetVisible( bool visible ); + void SetVisible(bool visible); void Update(float DeltaTime); @@ -67,7 +72,7 @@ public: void SetBuffer(const wchar_t* szMessage); - void UseHistoryFile( const VfsPath& filename, int historysize ); + void UseHistoryFile(const VfsPath& filename, int historysize); // Only returns a pointer to the buffer; copy out of here if you want to keep it. const wchar_t* GetBuffer(); @@ -113,10 +118,10 @@ private: void ToLower(wchar_t* szMessage, size_t iSize = 0); void Trim(wchar_t* szMessage, const wchar_t cChar = 32, size_t iSize = 0); - void DrawHistory(); - void DrawWindow(); - void DrawBuffer(); - void DrawCursor(); + void DrawWindow(CShaderProgramPtr& shader); + void DrawHistory(CTextRenderer& textRenderer); + void DrawBuffer(CTextRenderer& textRenderer); + void DrawCursor(CTextRenderer& textRenderer); bool IsEOB() { return (m_iBufferPos == m_iBufferLength); } // Is end of Buffer? bool IsBOB() { return (m_iBufferPos == 0); } // Is beginning of Buffer? diff --git a/source/ps/CLogger.cpp b/source/ps/CLogger.cpp index 43c6319ada..deb2e7f5db 100644 --- a/source/ps/CLogger.cpp +++ b/source/ps/CLogger.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2012 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -20,6 +20,8 @@ #include "CLogger.h" #include "CConsole.h" #include "ConfigDB.h" +#include "graphics/ShaderManager.h" +#include "graphics/TextRenderer.h" #include "lib/ogl.h" #include "lib/timer.h" #include "lib/utf8.h" @@ -27,6 +29,7 @@ #include "lib/sysdep/sysdep.h" #include "ps/Font.h" #include "ps/Profile.h" +#include "renderer/Renderer.h" #include #include @@ -281,18 +284,19 @@ void CLogger::Render() CleanupRenderQueue(); - CFont font(L"mono-stroke-10"); + CStrW font_name(L"mono-stroke-10"); + CFont font(font_name); int lineSpacing = font.GetLineSpacing(); - font.Bind(); - glPushMatrix(); + CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); + textTech->BeginPass(); - glScalef(1.0f, -1.0f, 1.0f); - //Offset by 35 vertically to avoid the top bar. - glTranslatef(4.0f, 35.0f + (float)lineSpacing - g_yres, 0.0f); + CTextRenderer textRenderer(textTech->GetShader()); + textRenderer.Font(font_name); + textRenderer.Color(1.0f, 1.0f, 1.0f); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // Offset by an extra 35px vertically to avoid the top bar. + textRenderer.Translate(4.0f, 35.0f + lineSpacing, 0.0f); // (Lock must come after loading the CFont, since that might log error messages // and attempt to lock the mutex recursively which is forbidden) @@ -304,32 +308,34 @@ void CLogger::Render() if (it->method == Normal) { type = L"info"; - glColor3f(0.0f, 0.8f, 0.0f); + textRenderer.Color(0.0f, 0.8f, 0.0f); } else if (it->method == Warning) { type = L"warning"; - glColor3f(1.0f, 1.0f, 0.0f); + textRenderer.Color(1.0f, 1.0f, 0.0f); } else { type = L"error"; - glColor3f(1.0f, 0.0f, 0.0f); + textRenderer.Color(1.0f, 0.0f, 0.0f); } - glPushMatrix(); - glwprintf(L"[%8.3f] %ls: ", it->time, type); + CMatrix3D savedTransform = textRenderer.GetTransform(); + + textRenderer.Printf(L"[%8.3f] %ls: ", it->time, type); // Display the actual message in white so it's more readable - glColor3f(1.0f, 1.0f, 1.0f); - glwprintf(L"%ls", it->message.c_str()); + textRenderer.Color(1.0f, 1.0f, 1.0f); + textRenderer.Printf(L"%ls", it->message.c_str()); - glPopMatrix(); - glTranslatef(0.f, (float)lineSpacing, 0.f); + textRenderer.SetTransform(savedTransform); + + textRenderer.Translate(0.0f, (float)lineSpacing, 0.0f); } - glDisable(GL_BLEND); + textRenderer.Render(); - glPopMatrix(); + textTech->EndPass(); } void CLogger::PushRenderMessage(ELogMethod method, const wchar_t* message) diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 4f48485e99..dee3bf1996 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -223,23 +223,6 @@ void Render() ogl_WarnIfError(); - // set up overlay mode - glPushAttrib(GL_ENABLE_BIT); - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.f, (float)g_xres, 0.f, (float)g_yres, -1.f, 1000.f); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - ogl_WarnIfError(); - g_Renderer.RenderTextOverlays(); if (g_DoRenderGui) @@ -249,14 +232,7 @@ void Render() // Text: - // Use the GL_ALPHA texture as the alpha channel with a flat colouring - glDisable(GL_ALPHA_TEST); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - // Added -- - glEnable(GL_TEXTURE_2D); - // -- GL - - glLoadIdentity(); + glDisable(GL_DEPTH_TEST); g_Console->Render(); @@ -280,21 +256,44 @@ void Render() CStrW cursorName = g_CursorName; if (cursorName.empty()) { - cursor_draw(g_VFS, NULL, g_mouse_x, g_yres-g_mouse_y); + cursor_draw(g_VFS, NULL, g_mouse_x, g_yres-g_mouse_y, false); } else { - if (cursor_draw(g_VFS, cursorName.c_str(), g_mouse_x, g_yres-g_mouse_y) < 0) + bool forceGL = false; + CFG_GET_USER_VAL("nohwcursor", Bool, forceGL); + +#if CONFIG2_GLES +#warning TODO: implement cursors for GLES +#else + // set up transform for GL cursor + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + CMatrix3D transform; + transform.SetOrtho(0.f, (float)g_xres, 0.f, (float)g_yres, -1.f, 1000.f); + glLoadMatrixf(&transform._11); +#endif + + if (cursor_draw(g_VFS, cursorName.c_str(), g_mouse_x, g_yres-g_mouse_y, forceGL) < 0) LOGWARNING(L"Failed to draw cursor '%ls'", cursorName.c_str()); + +#if CONFIG2_GLES +#warning TODO: implement cursors for GLES +#else + // restore transform + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +#endif } } - // restore - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glPopAttrib(); + glEnable(GL_DEPTH_TEST); g_Renderer.EndFrame(); @@ -546,7 +545,7 @@ static void ShutdownPs() SAFE_DELETE(g_Console); // disable the special Windows cursor, or free textures for OGL cursors - cursor_draw(g_VFS, 0, g_mouse_x, g_yres-g_mouse_y); + cursor_draw(g_VFS, 0, g_mouse_x, g_yres-g_mouse_y, false); } diff --git a/source/ps/ProfileViewer.cpp b/source/ps/ProfileViewer.cpp index 1f37f4d0e3..69c6e93f1c 100644 --- a/source/ps/ProfileViewer.cpp +++ b/source/ps/ProfileViewer.cpp @@ -164,8 +164,6 @@ void CProfileViewer::RenderProfile() PROFILE3_GPU("profile viewer"); - glDisable(GL_DEPTH_TEST); - glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -192,8 +190,8 @@ void CProfileViewer::RenderProfile() estimate_height = lineSpacing*estimate_height; CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect("solid"); - solidTech->BeginPass(0); - CShaderProgramPtr solidShader = solidTech->GetShader(0); + solidTech->BeginPass(); + CShaderProgramPtr solidShader = solidTech->GetShader(); solidShader->Uniform("color", 0.0f, 0.0f, 0.0f, 0.5f); @@ -240,16 +238,16 @@ void CProfileViewer::RenderProfile() solidShader->Uniform("transform", transform); } - solidTech->EndPass(0); + solidTech->EndPass(); // Print table and column titles CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); - textTech->BeginPass(0); + textTech->BeginPass(); - CTextRenderer textRenderer(textTech->GetShader(0)); + CTextRenderer textRenderer(textTech->GetShader()); textRenderer.Font(font_name); - textRenderer.Color(CColor(1.0f, 1.0f, 1.0f, 1.0f)); + textRenderer.Color(1.0f, 1.0f, 1.0f); textRenderer.PrintfAt(2.0f, lineSpacing, L"%hs", table->GetTitle().c_str()); @@ -278,9 +276,9 @@ void CProfileViewer::RenderProfile() for (size_t row = 0; row < numrows; ++row) { if (table->IsHighlightRow(row)) - textRenderer.Color(CColor(1.0f, 0.5f, 0.5f, 1.0f)); + textRenderer.Color(1.0f, 0.5f, 0.5f); else - textRenderer.Color(CColor(1.0f, 1.0f, 1.0f, 1.0f)); + textRenderer.Color(1.0f, 1.0f, 1.0f); if (table->GetChild(row)) { @@ -306,7 +304,7 @@ void CProfileViewer::RenderProfile() textRenderer.Translate(0.0f, lineSpacing, 0.0f); } - textRenderer.Color(CColor(1.0f, 1.0f, 1.0f, 1.0f)); + textRenderer.Color(1.0f, 1.0f, 1.0f); if (m->path.size() > 1) { @@ -316,7 +314,7 @@ void CProfileViewer::RenderProfile() } textRenderer.Render(); - textTech->EndPass(0); + textTech->EndPass(); glDisable(GL_BLEND); diff --git a/source/renderer/PatchRData.cpp b/source/renderer/PatchRData.cpp index b7270b64a5..c03dd779ad 100644 --- a/source/renderer/PatchRData.cpp +++ b/source/renderer/PatchRData.cpp @@ -25,6 +25,7 @@ #include "graphics/LightEnv.h" #include "graphics/Patch.h" #include "graphics/Terrain.h" +#include "graphics/TextRenderer.h" #include "lib/alignment.h" #include "lib/allocators/arena.h" #include "lib/res/graphics/unifont.h" @@ -1141,7 +1142,7 @@ void CPatchRData::RenderSides() CVertexBuffer::Unbind(); } -void CPatchRData::RenderPriorities() +void CPatchRData::RenderPriorities(CTextRenderer& textRenderer) { CTerrain* terrain = m_Patch->m_Parent; CCamera* camera = g_Game->GetView()->GetCamera(); @@ -1163,15 +1164,7 @@ void CPatchRData::RenderPriorities() float x, y; camera->GetScreenCoordinates(pos, x, y); - glPushMatrix(); - glTranslatef(x, g_yres - y, 0.f); - - // Draw the text upside-down, because it's aligned with - // the GUI (which uses the top-left as (0,0)) - glScalef(1.0f, -1.0f, 1.0f); - - glwprintf(L"%d", m_Patch->m_MiniPatches[j][i].Priority); - glPopMatrix(); + textRenderer.PrintfAt(x, y, L"%d", m_Patch->m_MiniPatches[j][i].Priority); } } } diff --git a/source/renderer/PatchRData.h b/source/renderer/PatchRData.h index 288fba4738..19b477fad4 100644 --- a/source/renderer/PatchRData.h +++ b/source/renderer/PatchRData.h @@ -27,6 +27,7 @@ class CPatch; class CTerrainTextureEntry; +class CTextRenderer; ////////////////////////////////////////////////////////////////////////////////////////////////// // CPatchRData: class encapsulating logic for rendering terrain patches; holds per @@ -40,7 +41,7 @@ public: void Update(); void RenderOutline(); void RenderSides(); - void RenderPriorities(); + void RenderPriorities(CTextRenderer& textRenderer); void RenderWater(); diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 01ebe7772c..46d9a33e55 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -1488,14 +1488,14 @@ void CRenderer::RenderParticles() m->particleRenderer.RenderParticles(true); CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect("solid"); - shaderTech->BeginPass(0); - CShaderProgramPtr shader = shaderTech->GetShader(0); + shaderTech->BeginPass(); + CShaderProgramPtr shader = shaderTech->GetShader(); shader->Uniform("color", 0.0f, 1.0f, 0.0f, 1.0f); shader->Uniform("transform", m_ViewCamera.GetViewProjection()); m->particleRenderer.RenderBounds(shader); - shaderTech->EndPass(0); + shaderTech->EndPass(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } diff --git a/source/renderer/ShadowMap.cpp b/source/renderer/ShadowMap.cpp index eab0447dae..4379d58233 100644 --- a/source/renderer/ShadowMap.cpp +++ b/source/renderer/ShadowMap.cpp @@ -529,8 +529,8 @@ const float* ShadowMap::GetFilterOffsets() const void ShadowMap::RenderDebugDisplay() { CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect("solid"); - shaderTech->BeginPass(0); - CShaderProgramPtr shader = shaderTech->GetShader(0); + shaderTech->BeginPass(); + CShaderProgramPtr shader = shaderTech->GetShader(); glDepthMask(0); glDisable(GL_CULL_FACE); @@ -565,7 +565,7 @@ void ShadowMap::RenderDebugDisplay() shader->AssertPointersBound(); glDrawArrays(GL_LINES, 0, 8); - shaderTech->EndPass(0); + shaderTech->EndPass(); #if 0 CMatrix3D InvTexTransform; diff --git a/source/renderer/TerrainRenderer.cpp b/source/renderer/TerrainRenderer.cpp index 18703cd79a..edf0792373 100644 --- a/source/renderer/TerrainRenderer.cpp +++ b/source/renderer/TerrainRenderer.cpp @@ -32,6 +32,7 @@ #include "graphics/Model.h" #include "graphics/ShaderManager.h" #include "graphics/TerritoryTexture.h" +#include "graphics/TextRenderer.h" #include "maths/MathUtil.h" @@ -803,11 +804,16 @@ void TerrainRenderer::RenderPriorities() ENSURE(m->phase == Phase_Render); - CFont font(L"mono-stroke-10"); - font.Bind(); + CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect("gui_text"); + tech->BeginPass(); + CTextRenderer textRenderer(tech->GetShader()); - glColor3f(1, 1, 0); + textRenderer.Font(L"mono-stroke-10"); + textRenderer.Color(1.0f, 1.0f, 0.0f); for (size_t i = 0; i < m->visiblePatches.size(); ++i) - m->visiblePatches[i]->RenderPriorities(); + m->visiblePatches[i]->RenderPriorities(textRenderer); + + textRenderer.Render(); + tech->EndPass(); } diff --git a/source/tools/atlas/GameInterface/ActorViewer.cpp b/source/tools/atlas/GameInterface/ActorViewer.cpp index 78b8acadb6..6c1e9f1bf9 100644 --- a/source/tools/atlas/GameInterface/ActorViewer.cpp +++ b/source/tools/atlas/GameInterface/ActorViewer.cpp @@ -488,33 +488,9 @@ void ActorViewer::Render() g_Renderer.RenderScene(m); - // .... - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.f, (float)g_xres, 0.f, (float)g_yres, -1.f, 1000.f); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glPushAttrib(GL_ENABLE_BIT); - glEnable(GL_TEXTURE_2D); - glDisable(GL_CULL_FACE); - 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); - glEnable(GL_TEXTURE_2D); - + glDisable(GL_DEPTH_TEST); g_ProfileViewer.RenderProfile(); - - glPopAttrib(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + glEnable(GL_DEPTH_TEST); g_Renderer.EndFrame(); diff --git a/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp index 7203dcf0c8..e5582b0d2d 100644 --- a/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp @@ -68,6 +68,7 @@ QUERYHANDLER(GetTerrainGroupPreviews) std::vector buf (msg->imageWidth*msg->imageHeight*3); +#if !CONFIG2_GLES // It's not good to shrink the entire texture to fit the small preview // window, since it's the fine details in the texture that are // interesting; so just go down one mipmap level, then crop a chunk @@ -75,24 +76,12 @@ QUERYHANDLER(GetTerrainGroupPreviews) // Read the size of the texture. (Usually loads the texture from // disk, which is slow.) - GLint w, h; - ssize_t level = 1; // level 0 is the original size (*it)->GetTexture()->Bind(); - glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &w); - glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_HEIGHT, &h); + int level = 1; // level 0 is the original size + int w = std::max(1, (int)(*it)->GetTexture()->GetWidth() >> level); + int h = std::max(1, (int)(*it)->GetTexture()->GetHeight() >> level); - if (w < msg->imageWidth || h < msg->imageHeight) - { - // Oops, too small to preview - just use a flat colour - u32 c = (*it)->GetBaseColor(); - for (ssize_t i = 0; i < msg->imageWidth*msg->imageHeight; ++i) - { - buf[i*3+0] = (c>>16) & 0xff; - buf[i*3+1] = (c>>8) & 0xff; - buf[i*3+2] = (c>>0) & 0xff; - } - } - else + if (w >= msg->imageWidth && h >= msg->imageHeight) { // Read the whole texture into a new buffer unsigned char* texdata = new unsigned char[w*h*3]; @@ -111,6 +100,19 @@ QUERYHANDLER(GetTerrainGroupPreviews) delete[] texdata; } + else +#endif + { + // Too small to preview, or glGetTexImage not supported (on GLES) + // Just use a flat color instead + u32 c = (*it)->GetBaseColor(); + for (ssize_t i = 0; i < msg->imageWidth*msg->imageHeight; ++i) + { + buf[i*3+0] = (c>>16) & 0xff; + buf[i*3+1] = (c>>8) & 0xff; + buf[i*3+2] = (c>>0) & 0xff; + } + } previews.back().loaded = (*it)->GetTexture()->IsLoaded(); previews.back().imageWidth = msg->imageWidth;