diff --git a/binaries/data/mods/public/shaders/effects/solid.xml b/binaries/data/mods/public/shaders/effects/solid.xml
new file mode 100644
index 0000000000..2296b23fcd
--- /dev/null
+++ b/binaries/data/mods/public/shaders/effects/solid.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/source/graphics/Camera.h b/source/graphics/Camera.h
index 029bf14e41..bfb01d2f37 100644
--- a/source/graphics/Camera.h
+++ b/source/graphics/Camera.h
@@ -51,7 +51,7 @@ class CCamera
CMatrix3D& GetOrientation() { return m_Orientation; }
const CMatrix3D& GetOrientation() const { return m_Orientation; }
- CMatrix3D GetViewProjection() { return m_ProjMat * m_Orientation.GetInverse(); }
+ CMatrix3D GetViewProjection() const { return m_ProjMat * m_Orientation.GetInverse(); }
// Updates the frustum planes. Should be called
// everytime the view or projection matrices are
diff --git a/source/graphics/ShaderProgram.cpp b/source/graphics/ShaderProgram.cpp
index 22f1ee34e0..f88093e795 100644
--- a/source/graphics/ShaderProgram.cpp
+++ b/source/graphics/ShaderProgram.cpp
@@ -28,6 +28,8 @@
#include "ps/Overlay.h"
#include "ps/Preprocessor.h"
+#if !CONFIG2_GLES
+
class CShaderProgramARB : public CShaderProgram
{
public:
@@ -227,6 +229,7 @@ private:
std::map m_FragmentIndexes;
};
+#endif // #if !CONFIG2_GLES
class CShaderProgramGLSL : public CShaderProgram
{
@@ -346,7 +349,12 @@ public:
m_UniformTypes[name] = type;
// Assign sampler uniforms to sequential texture units
- if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_SHADOW || type == GL_SAMPLER_CUBE)
+ if (type == GL_SAMPLER_2D
+ || type == GL_SAMPLER_CUBE
+#if !CONFIG2_GLES
+ || type == GL_SAMPLER_2D_SHADOW
+#endif
+ )
{
int unit = (int)m_Samplers.size();
m_Samplers[name].first = (type == GL_SAMPLER_CUBE ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D);
@@ -550,6 +558,17 @@ CShaderProgram::CShaderProgram(int streamflags)
{
}
+#if CONFIG2_GLES
+/*static*/ CShaderProgram* CShaderProgram::ConstructARB(const VfsPath& vertexFile, const VfsPath& fragmentFile,
+ const std::map& UNUSED(defines),
+ const std::map& UNUSED(vertexIndexes), const std::map& UNUSED(fragmentIndexes),
+ int UNUSED(streamflags))
+{
+ LOGERROR(L"CShaderProgram::ConstructARB: '%ls'+'%ls': ARB shaders not supported on this device",
+ vertexFile.string().c_str(), fragmentFile.string().c_str());
+ return NULL;
+}
+#else
/*static*/ CShaderProgram* CShaderProgram::ConstructARB(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const std::map& defines,
const std::map& vertexIndexes, const std::map& fragmentIndexes,
@@ -557,6 +576,7 @@ CShaderProgram::CShaderProgram(int streamflags)
{
return new CShaderProgramARB(vertexFile, fragmentFile, defines, vertexIndexes, fragmentIndexes, streamflags);
}
+#endif
/*static*/ CShaderProgram* CShaderProgram::ConstructGLSL(const VfsPath& vertexFile, const VfsPath& fragmentFile,
const std::map& defines,
@@ -641,25 +661,6 @@ void CShaderProgram::Uniform(uniform_id_t id, const CMatrix3D& v)
Uniform(GetUniformBinding(id), v);
}
-void CShaderProgram::VertexPointer(GLint size, GLenum type, GLsizei stride, void* pointer)
-{
- glVertexPointer(size, type, stride, pointer);
- m_ValidStreams |= STREAM_POS;
-}
-
-void CShaderProgram::NormalPointer(GLenum type, GLsizei stride, void* pointer)
-{
- glNormalPointer(type, stride, pointer);
- m_ValidStreams |= STREAM_NORMAL;
-}
-
-void CShaderProgram::TexCoordPointer(GLenum texture, GLint size, GLenum type, GLsizei stride, void* pointer)
-{
- pglActiveTextureARB(texture);
- glTexCoordPointer(size, type, stride, pointer);
- m_ValidStreams |= STREAM_UV0 << (texture - GL_TEXTURE0);
-}
-
CStr CShaderProgram::Preprocess(CPreprocessor& preprocessor, const CStr& input)
{
size_t len = 0;
@@ -680,6 +681,27 @@ CStr CShaderProgram::Preprocess(CPreprocessor& preprocessor, const CStr& input)
return ret;
}
+#if !CONFIG2_GLES
+
+void CShaderProgram::VertexPointer(GLint size, GLenum type, GLsizei stride, void* pointer)
+{
+ glVertexPointer(size, type, stride, pointer);
+ m_ValidStreams |= STREAM_POS;
+}
+
+void CShaderProgram::NormalPointer(GLenum type, GLsizei stride, void* pointer)
+{
+ glNormalPointer(type, stride, pointer);
+ m_ValidStreams |= STREAM_NORMAL;
+}
+
+void CShaderProgram::TexCoordPointer(GLenum texture, GLint size, GLenum type, GLsizei stride, void* pointer)
+{
+ pglActiveTextureARB(texture);
+ glTexCoordPointer(size, type, stride, pointer);
+ m_ValidStreams |= STREAM_UV0 << (texture - GL_TEXTURE0);
+}
+
void CShaderProgram::BindClientStates()
{
ENSURE(m_StreamFlags == (m_StreamFlags & (STREAM_POS|STREAM_NORMAL|STREAM_COLOR|STREAM_UV0|STREAM_UV1)));
@@ -729,7 +751,9 @@ void CShaderProgram::UnbindClientStates()
}
}
+#endif // !CONFIG2_GLES
+
void CShaderProgram::AssertPointersBound()
{
- ENSURE(m_ValidStreams == m_StreamFlags);
+ ENSURE((m_StreamFlags & ~m_ValidStreams) == 0);
}
\ No newline at end of file
diff --git a/source/graphics/ShaderProgramFFP.cpp b/source/graphics/ShaderProgramFFP.cpp
index 7db732ebd0..54b8d2b547 100644
--- a/source/graphics/ShaderProgramFFP.cpp
+++ b/source/graphics/ShaderProgramFFP.cpp
@@ -27,6 +27,8 @@
#include "ps/Overlay.h"
#include "renderer/Renderer.h"
+#if !CONFIG2_GLES
+
/**
* CShaderProgramFFP allows rendering code to use the shader-based API
* even if the 'shader' is actually implemented with the fixed-function
@@ -619,7 +621,19 @@ public:
return new CShaderProgramFFP_GuiGrayscale();
if (id == "gui_solid")
return new CShaderProgramFFP_GuiSolid();
+ if (id == "solid")
+ return new CShaderProgramFFP_GuiSolid(); // works for non-GUI objects too
- LOGERROR(L"CShaderProgram::ConstructFFP: Invalid id '%hs'", id.c_str());
+ debug_warn(L"CShaderProgram::ConstructFFP: Invalid id '%hs'", id.c_str());
return NULL;
}
+
+#else // CONFIG2_GLES
+
+/*static*/ CShaderProgram* CShaderProgram::ConstructFFP(const std::string& id, const std::map& defines)
+{
+ debug_warn(L"CShaderProgram::ConstructFFP: '%hs': FFP not supported on this device", id.c_str());
+ return NULL;
+}
+
+#endif // CONFIG2_GLES
diff --git a/source/graphics/TextRenderer.cpp b/source/graphics/TextRenderer.cpp
index 1b8588c710..bebb240acb 100644
--- a/source/graphics/TextRenderer.cpp
+++ b/source/graphics/TextRenderer.cpp
@@ -84,9 +84,7 @@ void CTextRenderer::Printf(const wchar_t* fmt, ...)
va_end(args);
if (ret < 0)
- {
- debug_printf(L"glwprintf failed (buffer size exceeded?) - return value %d, errno %d\n", ret, errno);
- }
+ debug_printf(L"CTextRenderer::Printf vswprintf failed (buffer size exceeded?) - return value %d, errno %d\n", ret, errno);
SBatch batch;
batch.transform = m_Transform;
@@ -100,6 +98,29 @@ void CTextRenderer::Printf(const wchar_t* fmt, ...)
Translate((float)w, 0.0f, 0.0f);
}
+void CTextRenderer::PrintfAt(float x, float y, const wchar_t* fmt, ...)
+{
+ wchar_t buf[1024] = {0};
+
+ va_list args;
+ va_start(args, fmt);
+ int ret = vswprintf(buf, ARRAY_SIZE(buf)-1, fmt, args);
+ va_end(args);
+
+ if (ret < 0)
+ debug_printf(L"CTextRenderer::PrintfAt vswprintf failed (buffer size exceeded?) - return value %d, errno %d\n", ret, errno);
+
+ CMatrix3D translate;
+ translate.SetTranslation(x, y, 0.0f);
+
+ SBatch batch;
+ batch.transform = m_Transform * translate;
+ batch.color = m_Color;
+ batch.font = m_Font;
+ batch.text = buf;
+ m_Batches.push_back(batch);
+}
+
void CTextRenderer::Render()
{
for (size_t i = 0; i < m_Batches.size(); ++i)
diff --git a/source/graphics/TextRenderer.h b/source/graphics/TextRenderer.h
index fce45b6c25..d4cc60e6ae 100644
--- a/source/graphics/TextRenderer.h
+++ b/source/graphics/TextRenderer.h
@@ -30,17 +30,42 @@ class CTextRenderer
public:
CTextRenderer(const CShaderProgramPtr& shader);
+ /**
+ * Reset the text transform to the default, with (0,0) in the top-left of the screen.
+ */
void ResetTransform();
+
CMatrix3D GetTransform();
+
void SetTransform(const CMatrix3D& transform);
void Translate(float x, float y, float z);
+ /**
+ * Set the color for subsequent print calls.
+ */
void Color(const CColor& color);
+
+ /**
+ * Set the font for subsequent print calls.
+ */
void Font(const CStrW& font);
+ /**
+ * Print formatted text at (0,0) under the current transform,
+ * and advance the transform by the width of the text.
+ */
void Printf(const wchar_t* fmt, ...);
+ /**
+ * Print formatted text at (x,y) under the current transform.
+ * Does not alter the current transform.
+ */
+ void PrintfAt(float x, float y, const wchar_t* fmt, ...);
+
+ /**
+ * Render all of the previously printed text calls.
+ */
void Render();
private:
diff --git a/source/lib/external_libraries/glext_funcs.h b/source/lib/external_libraries/glext_funcs.h
index 0398969b5b..affdd5db4d 100644
--- a/source/lib/external_libraries/glext_funcs.h
+++ b/source/lib/external_libraries/glext_funcs.h
@@ -72,6 +72,33 @@ actually supported).
#define pglCompressedTexImage2DARB glCompressedTexImage2D
#define pglActiveTextureARB glActiveTexture
+#define pglAttachObjectARB glAttachShader
+#define pglBindAttribLocationARB glBindAttribLocation
+#define pglCompileShaderARB glCompileShader
+#define pglCreateProgramObjectARB glCreateProgram
+#define pglCreateShaderObjectARB glCreateShader
+#define pglDeleteProgram glDeleteProgram
+#define pglDeleteShader glDeleteShader
+#define pglDisableVertexAttribArrayARB glDisableVertexAttribArray
+#define pglEnableVertexAttribArrayARB glEnableVertexAttribArray
+#define pglGetActiveUniformARB glGetActiveUniform
+#define pglGetProgramiv glGetProgramiv
+#define pglGetProgramInfoLog glGetProgramInfoLog
+#define pglGetShaderiv glGetShaderiv
+#define pglGetShaderInfoLog glGetShaderInfoLog
+#define pglLinkProgramARB glLinkProgram
+#define pglShaderSourceARB glShaderSource
+#define pglUniform1fARB glUniform1i
+#define pglUniform2fARB glUniform2f
+#define pglUniform3fARB glUniform3f
+#define pglUniform4fARB glUniform4f
+#define pglUniform1iARB glUniform1i
+#define pglUniformMatrix4fvARB glUniformMatrix4fv
+#define pglUseProgramObjectARB glUseProgram
+#define pglVertexAttribPointerARB glVertexAttribPointer
+
+typedef GLuint GLhandleARB;
+
#else
// were these defined as real functions in gl.h already?
diff --git a/source/maths/BoundingBoxAligned.cpp b/source/maths/BoundingBoxAligned.cpp
index 106e5c5262..2e0e706650 100644
--- a/source/maths/BoundingBoxAligned.cpp
+++ b/source/maths/BoundingBoxAligned.cpp
@@ -235,7 +235,7 @@ void CBoundingBoxAligned::Expand(float amount)
///////////////////////////////////////////////////////////////////////////////
// Render the bounding box
-void CBoundingBoxAligned::Render() const
+void CBoundingBoxAligned::Render(CShaderProgramPtr& shader) const
{
std::vector data;
@@ -258,14 +258,45 @@ void CBoundingBoxAligned::Render() const
ADD_FACE(1, u, 1-v);
ADD_FACE(u, 1, v);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glTexCoordPointer(2, GL_FLOAT, 5*sizeof(float), &data[0]);
- glVertexPointer(3, GL_FLOAT, 5*sizeof(float), &data[2]);
+#undef ADD_FACE
+ shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 5*sizeof(float), &data[0]);
+ shader->VertexPointer(3, GL_FLOAT, 5*sizeof(float), &data[2]);
+
+ shader->AssertPointersBound();
glDrawArrays(GL_TRIANGLES, 0, 6*6);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+void CBoundingBoxAligned::RenderOutline(CShaderProgramPtr& shader) const
+{
+ std::vector data;
+
+#define ADD_FACE(x, y, z) \
+ ADD_PT(0, 0, x, y, z); ADD_PT(1, 0, x, y, z); \
+ ADD_PT(1, 0, x, y, z); ADD_PT(1, 1, x, y, z); \
+ ADD_PT(1, 1, x, y, z); ADD_PT(0, 1, x, y, z); \
+ ADD_PT(0, 1, x, y, z); ADD_PT(0, 0, x, y, z);
+#define ADD_PT(u_, v_, x, y, z) \
+ STMT(int u = u_; int v = v_; \
+ data.push_back(u); \
+ data.push_back(v); \
+ data.push_back(m_Data[x].X); \
+ data.push_back(m_Data[y].Y); \
+ data.push_back(m_Data[z].Z); \
+ )
+
+ ADD_FACE(u, v, 0);
+ ADD_FACE(0, u, v);
+ ADD_FACE(u, 0, 1-v);
+ ADD_FACE(u, 1-v, 1);
+ ADD_FACE(1, u, 1-v);
+ ADD_FACE(u, 1, v);
+
+#undef ADD_FACE
+
+ shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 5*sizeof(float), &data[0]);
+ shader->VertexPointer(3, GL_FLOAT, 5*sizeof(float), &data[2]);
+
+ shader->AssertPointersBound();
+ glDrawArrays(GL_LINES, 0, 6*8);
}
diff --git a/source/maths/BoundingBoxAligned.h b/source/maths/BoundingBoxAligned.h
index 96254a0e48..d79805c949 100644
--- a/source/maths/BoundingBoxAligned.h
+++ b/source/maths/BoundingBoxAligned.h
@@ -24,6 +24,7 @@
// necessary includes
#include "Vector3D.h"
+#include "graphics/ShaderProgram.h"
class CFrustum;
class CMatrix3D;
@@ -131,9 +132,14 @@ public:
void IntersectFrustumConservative(const CFrustum& frustum);
/**
- * Render: Render the surfaces of the bound object as polygons.
+ * Render: Render the surfaces of the bound object as triangles.
*/
- void Render() const;
+ void Render(CShaderProgramPtr& shader) const;
+
+ /**
+ * Render: Render the outline of the bound object as lines.
+ */
+ void RenderOutline(CShaderProgramPtr& shader) const;
private:
// Holds the minimal and maximal coordinate points in m_Data[0] and m_Data[1], respectively.
diff --git a/source/maths/Matrix3D.cpp b/source/maths/Matrix3D.cpp
index f6ebbfcd7d..54576a2108 100644
--- a/source/maths/Matrix3D.cpp
+++ b/source/maths/Matrix3D.cpp
@@ -183,6 +183,15 @@ void CMatrix3D::Translate(const CVector3D &vector)
_34 += vector.Z;
}
+void CMatrix3D::PostTranslate(float x, float y, float z)
+{
+ // Equivalent to "m.SetTranslation(x, y, z); *this = *this * m;"
+ _14 += _11*x + _12*y + _13*z;
+ _24 += _21*x + _22*y + _23*z;
+ _34 += _31*x + _32*y + _33*z;
+ _44 += _41*x + _42*y + _43*z;
+}
+
CVector3D CMatrix3D::GetTranslation() const
{
return CVector3D(_14, _24, _34);
diff --git a/source/maths/Matrix3D.h b/source/maths/Matrix3D.h
index ed9a2840ec..e6999a0ec7 100644
--- a/source/maths/Matrix3D.h
+++ b/source/maths/Matrix3D.h
@@ -232,6 +232,9 @@ public:
void Translate(float x, float y, float z);
void Translate(const CVector3D& vector);
+ // apply translation after this matrix (M = M * T)
+ void PostTranslate(float x, float y, float z);
+
// set this matrix to the given scaling matrix
void SetScaling(float x_scale, float y_scale, float z_scale);
diff --git a/source/ps/GameSetup/HWDetect.cpp b/source/ps/GameSetup/HWDetect.cpp
index 33638aa6dd..5a9e67f576 100644
--- a/source/ps/GameSetup/HWDetect.cpp
+++ b/source/ps/GameSetup/HWDetect.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011 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
@@ -181,8 +181,11 @@ void RunHardwareDetection()
#else
scriptInterface.SetProperty(settings.get(), "build_debug", 1);
#endif
+ scriptInterface.SetProperty(settings.get(), "build_opengles", CONFIG2_GLES);
+
scriptInterface.SetProperty(settings.get(), "build_datetime", std::string(__DATE__ " " __TIME__));
scriptInterface.SetProperty(settings.get(), "build_revision", std::wstring(svn_revision));
+
scriptInterface.SetProperty(settings.get(), "build_msc", (int)MSC_VERSION);
scriptInterface.SetProperty(settings.get(), "build_icc", (int)ICC_VERSION);
scriptInterface.SetProperty(settings.get(), "build_gcc", (int)GCC_VERSION);
@@ -265,7 +268,7 @@ void RunHardwareDetection()
scriptInterface.SetProperty(settings.get(), "timer_resolution", timer_Resolution());
// Send the same data to the reporting system
- g_UserReporter.SubmitReport("hwdetect", 10, scriptInterface.StringifyJSON(settings.get(), false));
+ g_UserReporter.SubmitReport("hwdetect", 11, scriptInterface.StringifyJSON(settings.get(), false));
// Run the detection script:
@@ -363,21 +366,28 @@ static void ReportGLLimits(ScriptInterface& scriptInterface, CScriptValRooted se
STRING(VENDOR);
STRING(RENDERER);
STRING(EXTENSIONS);
+#if !CONFIG2_GLES
INTEGER(MAX_LIGHTS);
INTEGER(MAX_CLIP_PLANES);
// Skip MAX_COLOR_MATRIX_STACK_DEPTH (only in imaging subset)
INTEGER(MAX_MODELVIEW_STACK_DEPTH);
INTEGER(MAX_PROJECTION_STACK_DEPTH);
INTEGER(MAX_TEXTURE_STACK_DEPTH);
+#endif
INTEGER(SUBPIXEL_BITS);
+#if !CONFIG2_GLES
INTEGER(MAX_3D_TEXTURE_SIZE);
+#endif
INTEGER(MAX_TEXTURE_SIZE);
INTEGER(MAX_CUBE_MAP_TEXTURE_SIZE);
+#if !CONFIG2_GLES
INTEGER(MAX_PIXEL_MAP_TABLE);
INTEGER(MAX_NAME_STACK_DEPTH);
INTEGER(MAX_LIST_NESTING);
INTEGER(MAX_EVAL_ORDER);
+#endif
INTEGER2(MAX_VIEWPORT_DIMS);
+#if !CONFIG2_GLES
INTEGER(MAX_ATTRIB_STACK_DEPTH);
INTEGER(MAX_CLIENT_ATTRIB_STACK_DEPTH);
INTEGER(AUX_BUFFERS);
@@ -385,16 +395,21 @@ static void ReportGLLimits(ScriptInterface& scriptInterface, CScriptValRooted se
BOOL(INDEX_MODE);
BOOL(DOUBLEBUFFER);
BOOL(STEREO);
+#endif
FLOAT2(ALIASED_POINT_SIZE_RANGE);
+#if !CONFIG2_GLES
FLOAT2(SMOOTH_POINT_SIZE_RANGE);
FLOAT(SMOOTH_POINT_SIZE_GRANULARITY);
+#endif
FLOAT2(ALIASED_LINE_WIDTH_RANGE);
+#if !CONFIG2_GLES
FLOAT2(SMOOTH_LINE_WIDTH_RANGE);
FLOAT(SMOOTH_LINE_WIDTH_GRANULARITY);
// Skip MAX_CONVOLUTION_WIDTH, MAX_CONVOLUTION_HEIGHT (only in imaging subset)
INTEGER(MAX_ELEMENTS_INDICES);
INTEGER(MAX_ELEMENTS_VERTICES);
INTEGER(MAX_TEXTURE_UNITS);
+#endif
INTEGER(SAMPLE_BUFFERS);
INTEGER(SAMPLES);
// TODO: compressed texture formats
@@ -402,13 +417,19 @@ static void ReportGLLimits(ScriptInterface& scriptInterface, CScriptValRooted se
INTEGER(GREEN_BITS);
INTEGER(BLUE_BITS);
INTEGER(ALPHA_BITS);
+#if !CONFIG2_GLES
INTEGER(INDEX_BITS);
+#endif
INTEGER(DEPTH_BITS);
INTEGER(STENCIL_BITS);
+#if !CONFIG2_GLES
INTEGER(ACCUM_RED_BITS);
INTEGER(ACCUM_GREEN_BITS);
INTEGER(ACCUM_BLUE_BITS);
INTEGER(ACCUM_ALPHA_BITS);
+#endif
+
+#if !CONFIG2_GLES
// Core OpenGL 2.0 (treated as extensions):
@@ -437,7 +458,9 @@ static void ReportGLLimits(ScriptInterface& scriptInterface, CScriptValRooted se
}
if (ogl_HaveExtension("GL_ARB_fragment_shader"))
+ {
INTEGER(MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB);
+ }
if (ogl_HaveExtension("GL_ARB_vertex_shader") || ogl_HaveExtension("GL_ARB_fragment_shader") ||
ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
@@ -580,4 +603,20 @@ static void ReportGLLimits(ScriptInterface& scriptInterface, CScriptValRooted se
INTEGER(MAX_GEOMETRY_VARYING_COMPONENTS_ARB);
INTEGER(MAX_VERTEX_VARYING_COMPONENTS_ARB);
}
+
+#else // CONFIG2_GLES
+
+ // Core OpenGL ES 2.0:
+
+ STRING(SHADING_LANGUAGE_VERSION);
+ INTEGER(MAX_VERTEX_ATTRIBS);
+ INTEGER(MAX_VERTEX_UNIFORM_VECTORS);
+ INTEGER(MAX_VARYING_VECTORS);
+ INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ INTEGER(MAX_FRAGMENT_UNIFORM_VECTORS);
+ INTEGER(MAX_TEXTURE_IMAGE_UNITS);
+ INTEGER(MAX_RENDERBUFFER_SIZE);
+
+#endif // CONFIG2_GLES
}
diff --git a/source/ps/ProfileViewer.cpp b/source/ps/ProfileViewer.cpp
index 24e7224063..1f37f4d0e3 100644
--- a/source/ps/ProfileViewer.cpp
+++ b/source/ps/ProfileViewer.cpp
@@ -27,6 +27,9 @@
#include "ProfileViewer.h"
+#include "gui/GUIutil.h"
+#include "graphics/ShaderManager.h"
+#include "graphics/TextRenderer.h"
#include "ps/CLogger.h"
#include "ps/Filesystem.h"
#include "ps/Font.h"
@@ -161,6 +164,8 @@ void CProfileViewer::RenderProfile()
PROFILE3_GPU("profile viewer");
+ glDisable(GL_DEPTH_TEST);
+
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -168,7 +173,8 @@ void CProfileViewer::RenderProfile()
const std::vector& columns = table->GetColumns();
size_t numrows = table->GetNumberRows();
- CFont font(L"mono-stroke-10");
+ CStrW font_name = L"mono-stroke-10";
+ CFont font(font_name);
font.Bind();
int lineSpacing = font.GetLineSpacing();
@@ -185,110 +191,136 @@ void CProfileViewer::RenderProfile()
estimate_height += 2;
estimate_height = lineSpacing*estimate_height;
- glDisable(GL_TEXTURE_2D);
- glColor4ub(0,0,0,128);
- glBegin(GL_QUADS);
- glVertex2i(estimate_width, g_yres);
- glVertex2i(0, g_yres);
- glVertex2i(0, g_yres-estimate_height);
- glVertex2i(estimate_width, g_yres-estimate_height);
- glEnd();
- glEnable(GL_TEXTURE_2D);
+ CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect("solid");
+ solidTech->BeginPass(0);
+ CShaderProgramPtr solidShader = solidTech->GetShader(0);
+
+ solidShader->Uniform("color", 0.0f, 0.0f, 0.0f, 0.5f);
+
+ CMatrix3D transform = GetDefaultGuiMatrix();
+ solidShader->Uniform("transform", transform);
+
+ float backgroundVerts[] = {
+ (float)estimate_width, 0.0f,
+ 0.0f, 0.0f,
+ 0.0f, (float)estimate_height,
+ 0.0f, (float)estimate_height,
+ (float)estimate_width, (float)estimate_height,
+ (float)estimate_width, 0.0f
+ };
+ solidShader->VertexPointer(2, GL_FLOAT, 0, backgroundVerts);
+ solidShader->AssertPointersBound();
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ transform.PostTranslate(22.0f, lineSpacing*3.0f, 0.0f);
+ solidShader->Uniform("transform", transform);
+
+ // Draw row backgrounds
+ for (size_t row = 0; row < numrows; ++row)
+ {
+ if (row % 2)
+ solidShader->Uniform("color", 1.0f, 1.0f, 1.0f, 0.1f);
+ else
+ solidShader->Uniform("color", 0.0f, 0.0f, 0.0f, 0.1f);
+
+ float rowVerts[] = {
+ -22.f, 2.f,
+ estimate_width-22.f, 2.f,
+ estimate_width-22.f, 2.f-lineSpacing,
+
+ estimate_width-22.f, 2.f-lineSpacing,
+ -22.f, 2.f-lineSpacing,
+ -22.f, 2.f
+ };
+ solidShader->VertexPointer(2, GL_FLOAT, 0, rowVerts);
+ solidShader->AssertPointersBound();
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ transform.PostTranslate(0.0f, lineSpacing, 0.0f);
+ solidShader->Uniform("transform", transform);
+ }
+
+ solidTech->EndPass(0);
// Print table and column titles
- glPushMatrix();
- glTranslatef(2.0f, g_yres - lineSpacing, 0.0f );
- glScalef(1.0f, -1.0f, 1.0f);
- glColor3ub(255, 255, 255);
- glPushMatrix();
- glwprintf(L"%hs", table->GetTitle().c_str());
- glPopMatrix();
- glTranslatef( 20.0f, lineSpacing, 0.0f );
+ CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect("gui_text");
+ textTech->BeginPass(0);
- glPushMatrix();
- for(size_t col = 0; col < columns.size(); ++col)
+ CTextRenderer textRenderer(textTech->GetShader(0));
+ textRenderer.Font(font_name);
+ textRenderer.Color(CColor(1.0f, 1.0f, 1.0f, 1.0f));
+
+ textRenderer.PrintfAt(2.0f, lineSpacing, L"%hs", table->GetTitle().c_str());
+
+ textRenderer.Translate(22.0f, lineSpacing*2.0f, 0.0f);
+
+ float colX = 0.0f;
+ for (size_t col = 0; col < columns.size(); ++col)
{
CStr text = columns[col].title;
int w, h;
font.CalculateStringSize(text.FromUTF8(), w, h);
- glPushMatrix();
+
+ float x = colX;
if (col > 0) // right-align all but the first column
- glTranslatef(columns[col].width - w, 0, 0);
- glwprintf(L"%hs", text.c_str());
- glPopMatrix();
- glTranslatef(columns[col].width, 0, 0);
+ x += columns[col].width - w;
+ textRenderer.PrintfAt(x, 0.0f, L"%hs", text.c_str());
+
+ colX += columns[col].width;
}
- glPopMatrix();
- glTranslatef( 0.0f, lineSpacing, 0.0f );
+
+ textRenderer.Translate(0.0f, lineSpacing, 0.0f);
// Print rows
int currentExpandId = 1;
- for(size_t row = 0; row < numrows; ++row)
+ for (size_t row = 0; row < numrows; ++row)
{
- glPushMatrix();
-
- glDisable(GL_TEXTURE_2D);
- if (row % 2)
- glColor4ub(255, 255, 255, 16);
- else
- glColor4ub(0, 0, 0, 16);
- glBegin(GL_QUADS);
- glVertex2i(-22.f, 2.f);
- glVertex2i(estimate_width-22.f, 2.f);
- glVertex2i(estimate_width-22.f, 2.f-lineSpacing);
- glVertex2i(-22.f, 2.f-lineSpacing);
- glEnd();
- glEnable(GL_TEXTURE_2D);
-
if (table->IsHighlightRow(row))
- glColor3ub(255, 128, 128);
+ textRenderer.Color(CColor(1.0f, 0.5f, 0.5f, 1.0f));
else
- glColor3ub(255, 255, 255);
+ textRenderer.Color(CColor(1.0f, 1.0f, 1.0f, 1.0f));
if (table->GetChild(row))
{
- glPushMatrix();
- glTranslatef( -15.0f, 0.0f, 0.0f );
- glwprintf(L"%d", currentExpandId);
- glPopMatrix();
+ textRenderer.PrintfAt(-15.0f, 0.0f, L"%d", currentExpandId);
currentExpandId++;
}
- for(size_t col = 0; col < columns.size(); ++col)
+ float colX = 0.0f;
+ for (size_t col = 0; col < columns.size(); ++col)
{
CStr text = table->GetCellText(row, col);
int w, h;
font.CalculateStringSize(text.FromUTF8(), w, h);
- glPushMatrix();
+
+ float x = colX;
if (col > 0) // right-align all but the first column
- glTranslatef(columns[col].width - w, 0, 0);
- glwprintf(L"%hs", text.c_str());
- glPopMatrix();
- glTranslatef(columns[col].width, 0, 0);
+ x += columns[col].width - w;
+ textRenderer.PrintfAt(x, 0.0f, L"%hs", text.c_str());
+
+ colX += columns[col].width;
}
- glPopMatrix();
- glTranslatef( 0.0f, lineSpacing, 0.0f );
+ textRenderer.Translate(0.0f, lineSpacing, 0.0f);
}
- glColor3ub(255, 255, 255);
+
+ textRenderer.Color(CColor(1.0f, 1.0f, 1.0f, 1.0f));
if (m->path.size() > 1)
{
- glTranslatef( 0.0f, lineSpacing, 0.0f );
- glPushMatrix();
- glPushMatrix();
- glTranslatef( -15.0f, 0.0f, 0.0f );
- glwprintf( L"0" );
- glPopMatrix();
- glwprintf( L"back to parent" );
- glPopMatrix();
+ textRenderer.Translate(0.0f, lineSpacing, 0.0f);
+ textRenderer.PrintfAt(-15.0f, 0.0f, L"0");
+ textRenderer.PrintfAt(0.0f, 0.0f, L"back to parent");
}
- glPopMatrix();
+ textRenderer.Render();
+ textTech->EndPass(0);
glDisable(GL_BLEND);
+
+ glEnable(GL_DEPTH_TEST);
}
diff --git a/source/ps/Profiler2GPU.cpp b/source/ps/Profiler2GPU.cpp
index 7afd444e9f..e4cbffb1b0 100644
--- a/source/ps/Profiler2GPU.cpp
+++ b/source/ps/Profiler2GPU.cpp
@@ -29,6 +29,8 @@
#include "ps/ConfigDB.h"
#include "ps/Profiler2.h"
+#if !CONFIG2_GLES
+
class CProfiler2GPU_base
{
NONCOPYABLE(CProfiler2GPU_base);
@@ -854,3 +856,19 @@ void CProfiler2GPU::RegionLeave(const char* id)
if (m_ProfilerINTEL)
m_ProfilerINTEL->RegionLeave(id);
}
+
+#else // CONFIG2_GLES
+
+CProfiler2GPU::CProfiler2GPU(CProfiler2& profiler) :
+ m_Profiler(profiler), m_ProfilerARB(NULL), m_ProfilerEXT(NULL), m_ProfilerINTEL(NULL)
+{
+}
+
+CProfiler2GPU::~CProfiler2GPU() { }
+
+void CProfiler2GPU::FrameStart() { }
+void CProfiler2GPU::FrameEnd() { }
+void CProfiler2GPU::RegionEnter(const char* UNUSED(id)) { }
+void CProfiler2GPU::RegionLeave(const char* UNUSED(id)) { }
+
+#endif
\ No newline at end of file
diff --git a/source/ps/Util.cpp b/source/ps/Util.cpp
index 516e8170e5..623add3c58 100644
--- a/source/ps/Util.cpp
+++ b/source/ps/Util.cpp
@@ -206,8 +206,10 @@ void WriteScreenshot(const VfsPath& extension)
// so read data from OpenGL in BMP format to obviate conversion.
if(extension == L".bmp")
{
+#if !CONFIG2_GLES // GLES doesn't support BGR
fmt = GL_BGR;
flags |= TEX_BGR;
+#endif
}
// Hide log messages and re-render
@@ -265,8 +267,10 @@ void WriteBigScreenshot(const VfsPath& extension, int tiles)
// so read data from OpenGL in BMP format to obviate conversion.
if(extension == L".bmp")
{
+#if !CONFIG2_GLES // GLES doesn't support BGR
fmt = GL_BGR;
flags |= TEX_BGR;
+#endif
}
const size_t img_size = img_w * img_h * bpp/8;
@@ -299,6 +303,7 @@ void WriteBigScreenshot(const VfsPath& extension, int tiles)
g_Game->GetView()->SetCameraProjection();
}
+#if !CONFIG2_GLES
// Temporarily move everything onto the front buffer, so the user can
// see the exciting progress as it renders (and can tell when it's finished).
// (It doesn't just use SwapBuffers, because it doesn't know whether to
@@ -308,6 +313,7 @@ void WriteBigScreenshot(const VfsPath& extension, int tiles)
glGetIntegerv(GL_DRAW_BUFFER, &oldDrawBuffer);
glDrawBuffer(GL_FRONT);
glReadBuffer(GL_FRONT);
+#endif
// Hide the cursor
CStrW oldCursor = g_CursorName;
@@ -341,9 +347,11 @@ void WriteBigScreenshot(const VfsPath& extension, int tiles)
// Restore the old cursor
g_CursorName = oldCursor;
+#if !CONFIG2_GLES
// Restore the buffer settings
glDrawBuffer(oldDrawBuffer);
glReadBuffer(oldReadBuffer);
+#endif
// Restore the viewport settings
{
diff --git a/source/renderer/ParticleRenderer.cpp b/source/renderer/ParticleRenderer.cpp
index e20ea50fb3..b23e6db842 100644
--- a/source/renderer/ParticleRenderer.cpp
+++ b/source/renderer/ParticleRenderer.cpp
@@ -157,13 +157,13 @@ void ParticleRenderer::RenderParticles(bool solidColor)
shader->Unbind();
}
-void ParticleRenderer::RenderBounds()
+void ParticleRenderer::RenderBounds(CShaderProgramPtr& shader)
{
for (size_t i = 0; i < m->emitters.size(); ++i)
{
CParticleEmitter* emitter = m->emitters[i];
CBoundingBoxAligned bounds = emitter->m_Type->CalculateBounds(emitter->GetPosition(), emitter->GetParticleBounds());
- bounds.Render();
+ bounds.Render(shader);
}
}
diff --git a/source/renderer/ParticleRenderer.h b/source/renderer/ParticleRenderer.h
index 9e96810a8e..7beeeddb65 100644
--- a/source/renderer/ParticleRenderer.h
+++ b/source/renderer/ParticleRenderer.h
@@ -22,6 +22,8 @@ class CParticleEmitter;
struct ParticleRendererInternals;
+#include "graphics/ShaderProgram.h"
+
/**
* Render particles.
*/
@@ -56,7 +58,7 @@ public:
/**
* Render bounding boxes for all the submitted emitters.
*/
- void RenderBounds();
+ void RenderBounds(CShaderProgramPtr& shader);
private:
ParticleRendererInternals* m;
diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp
index 2e2dcdfac0..01ebe7772c 100644
--- a/source/renderer/Renderer.cpp
+++ b/source/renderer/Renderer.cpp
@@ -1487,10 +1487,15 @@ void CRenderer::RenderParticles()
m->particleRenderer.RenderParticles(true);
- glDisable(GL_TEXTURE_2D);
- glColor3f(0.0f, 1.0f, 0.0f);
+ CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect("solid");
+ shaderTech->BeginPass(0);
+ CShaderProgramPtr shader = shaderTech->GetShader(0);
+ shader->Uniform("color", 0.0f, 1.0f, 0.0f, 1.0f);
+ shader->Uniform("transform", m_ViewCamera.GetViewProjection());
- m->particleRenderer.RenderBounds();
+ m->particleRenderer.RenderBounds(shader);
+
+ shaderTech->EndPass(0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
@@ -1673,6 +1678,7 @@ void CRenderer::DisplayFrustum()
{
glDepthMask(0);
glDisable(GL_CULL_FACE);
+ glDisable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
diff --git a/source/renderer/ShadowMap.cpp b/source/renderer/ShadowMap.cpp
index 2631ba70bb..eab0447dae 100644
--- a/source/renderer/ShadowMap.cpp
+++ b/source/renderer/ShadowMap.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009 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
@@ -27,6 +27,7 @@
#include "ps/Profile.h"
#include "graphics/LightEnv.h"
+#include "graphics/ShaderManager.h"
#include "maths/BoundingBoxAligned.h"
#include "maths/MathUtil.h"
@@ -527,35 +528,44 @@ const float* ShadowMap::GetFilterOffsets() const
// - blue: objects in shadow
void ShadowMap::RenderDebugDisplay()
{
+ CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect("solid");
+ shaderTech->BeginPass(0);
+ CShaderProgramPtr shader = shaderTech->GetShader(0);
+
glDepthMask(0);
glDisable(GL_CULL_FACE);
// Render shadow bound
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glMultMatrixf(&m->InvLightTransform._11);
+ shader->Uniform("transform", g_Renderer.GetViewCamera().GetViewProjection() * m->InvLightTransform);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ub(0,0,255,64);
- m->ShadowBound.Render();
+ shader->Uniform("color", 0.0f, 0.0f, 1.0f, 0.25f);
+ m->ShadowBound.Render(shader);
glDisable(GL_BLEND);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- glColor3ub(0,0,255);
- m->ShadowBound.Render();
+ shader->Uniform("color", 0.0f, 0.0f, 1.0f, 1.0f);
+ m->ShadowBound.RenderOutline(shader);
- glBegin(GL_LINES);
- glVertex3f(0.0, 0.0, 0.0);
- glVertex3f(0.0, 0.0, 50.0);
- glEnd();
- glBegin(GL_POLYGON);
- glVertex3f(0.0, 0.0, 50.0);
- glVertex3f(50.0, 0.0, 50.0);
- glVertex3f(0.0, 50.0, 50.0);
- glEnd();
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glPopMatrix();
+ // Draw a funny line/triangle direction indicator thing for unknown reasons
+ float shadowLineVerts[] = {
+ 0.0, 0.0, 0.0,
+ 0.0, 0.0, 50.0,
+
+ 0.0, 0.0, 50.0,
+ 50.0, 0.0, 50.0,
+
+ 50.0, 0.0, 50.0,
+ 0.0, 50.0, 50.0,
+
+ 0.0, 50.0, 50.0,
+ 0.0, 0.0, 50.0
+ };
+ shader->VertexPointer(3, GL_FLOAT, 0, shadowLineVerts);
+ shader->AssertPointersBound();
+ glDrawArrays(GL_LINES, 0, 8);
+
+ shaderTech->EndPass(0);
#if 0
CMatrix3D InvTexTransform;