|
From: Lasse Kärkkäi. <tr...@us...> - 2011-02-06 16:23:59
|
Module: performous
Branch: opengl2
Commit: 18626cdf84b8c77df817b17fc95520e3a550e47f
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Feb 6 17:21:09 2011 +0100
Shader refactoring.
* Shaders now owned by Window
* UseTexture sets the proper shader for texture rendering
* GL_TEXTURE_RECTANGLE used instead of ~_ARB
---
game/glshader.cc | 4 ----
game/glshader.hh | 9 ---------
game/screen_intro.cc | 5 +++--
game/surface.cc | 5 +++++
game/surface.hh | 33 ++++++++++++++++-----------------
game/video_driver.cc | 19 +++++++++++++++----
game/video_driver.hh | 7 +++++--
themes/default/shaders/core.frag | 25 +++++++++++++++----------
8 files changed, 59 insertions(+), 48 deletions(-)
diff --git a/game/glshader.cc b/game/glshader.cc
index ffad283..9c30e5b 100644
--- a/game/glshader.cc
+++ b/game/glshader.cc
@@ -40,12 +40,9 @@ namespace {
}
}
-Shader::ShaderMap Shader::shader_progs;
-
Shader::Shader(): program(0) {}
Shader::~Shader() {
- shader_progs[program] = NULL;
glDeleteProgram(program);
std::for_each(shader_ids.begin(), shader_ids.end(), glDeleteShader);
//std::clog << "shader/info: Shader program " << (unsigned)program << " deleted." << std::endl;
@@ -109,7 +106,6 @@ Shader& Shader::link() {
}
ec.check("glLinkProgram");
- shader_progs[program] = this;
return *this;
}
diff --git a/game/glshader.hh b/game/glshader.hh
index 0bf934b..61039ca 100644
--- a/game/glshader.hh
+++ b/game/glshader.hh
@@ -65,13 +65,6 @@ struct Shader: public boost::noncopyable {
bool operator==(const Shader& rhs) const { return program == rhs.program; }
bool operator!=(const Shader& rhs) const { return program != rhs.program; }
- /** Returns pointer to the currently used shader. */
- static Shader* current() {
- GLint i;
- glGetIntegerv(GL_CURRENT_PROGRAM, &i);
- return shader_progs[i];
- }
-
private:
GLuint program; ///< shader program object id
int gl_response; ///< save last return state
@@ -82,8 +75,6 @@ private:
typedef std::map<std::string, GLint> UniformMap;
UniformMap uniforms; ///< Cached uniform locations, use operator[] to access
- typedef std::map<GLint, Shader*> ShaderMap;
- static ShaderMap shader_progs; ///< Shader objects for reverse look-up by id
};
diff --git a/game/screen_intro.cc b/game/screen_intro.cc
index 2d60ddf..2eff166 100644
--- a/game/screen_intro.cc
+++ b/game/screen_intro.cc
@@ -116,9 +116,10 @@ void ScreenIntro::draw_menu_options() {
void ScreenIntro::draw() {
{
float anim = SDL_GetTicks() % 20000 / 20000.0;
- Shader::current()->setUniformMatrix("colorMatrix", glmath::rotate(2.0 * M_PI * anim, glmath::Vec3(1.0, 1.0, 1.0)));
+ Shader& sh = theme->bg.shader();
+ sh.setUniformMatrix("colorMatrix", glmath::rotate(2.0 * M_PI * anim, glmath::Vec3(1.0, 1.0, 1.0)));
theme->bg.draw();
- Shader::current()->setUniformMatrix("colorMatrix", glmath::Matrix());
+ sh.setUniformMatrix("colorMatrix", glmath::Matrix());
}
if (m_menu.current().image) m_menu.current().image->draw();
// Comment
diff --git a/game/surface.cc b/game/surface.cc
index 54fb533..77da12b 100644
--- a/game/surface.cc
+++ b/game/surface.cc
@@ -5,6 +5,7 @@
#include "configuration.hh"
#include "video_driver.hh"
#include "image.hh"
+#include "screen.hh"
#include <fstream>
#include <stdexcept>
@@ -17,6 +18,10 @@
#include <boost/format.hpp>
using boost::uint32_t;
+Shader& getShader(std::string const& name) {
+ return ScreenManager::getSingletonPtr()->window().shader(name); // FIXME
+}
+
float Dimensions::screenY() const {
switch (m_screenAnchor) {
case CENTER: return 0.0;
diff --git a/game/surface.hh b/game/surface.hh
index 8d856af..adb394e 100644
--- a/game/surface.hh
+++ b/game/surface.hh
@@ -99,11 +99,21 @@ struct TexCoords {
x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
};
+/// This function hides the ugly global vari-- I mean singleton access to ScreenManager...
+Shader& getShader(std::string const& name);
+
/** @short A RAII wrapper for allocating/deallocating OpenGL texture ID **/
template <GLenum Type> class OpenGLTexture: boost::noncopyable {
public:
/// return Type
static GLenum type() { return Type; };
+ static Shader& shader() {
+ switch (Type) {
+ case GL_TEXTURE_2D: return getShader("texture");
+ case GL_TEXTURE_RECTANGLE: return getShader("surface");
+ }
+ throw std::logic_error("Unknown texture type");
+ }
OpenGLTexture(): m_id() { glGenTextures(1, &m_id); }
~OpenGLTexture() { glDeleteTextures(1, &m_id); }
/// returns id
@@ -120,22 +130,11 @@ template <GLenum Type> class OpenGLTexture: boost::noncopyable {
class UseTexture: boost::noncopyable {
public:
/// constructor
- template <GLenum Type> UseTexture(OpenGLTexture<Type> const& s):
- m_shader(*Shader::current()) {
- switch (Type) {
- //case GL_TEXTURE_2D: glActiveTexture(GL_TEXTURE0); /*m_shader.setUniform("texMode", 1); */break;
- case GL_TEXTURE_RECTANGLE_ARB: glActiveTexture(GL_TEXTURE0); /*m_shader.setUniform("texMode", 2);*/ break;
- //default: m_shader.setUniform("texMode", 3); break;
- }
- glEnable(Type);
- glBindTexture(Type, s.id());
- }
- ~UseTexture() {
- //m_shader.setUniform("texMode", 0);
- }
-
+ template <GLenum Type> UseTexture(OpenGLTexture<Type> const& tex):
+ m_shader(/* hack of the year */ (glutil::GLErrorChecker("UseTexture"), glActiveTexture(GL_TEXTURE0), glBindTexture(Type, tex.id()), tex.shader())) {}
+
private:
- Shader& m_shader;
+ UseShader m_shader;
};
template <GLenum Type> void OpenGLTexture<Type>::draw(Dimensions const& dim, TexCoords const& tex) const {
@@ -200,8 +199,8 @@ class Surface {
void draw() const;
/// loads surface into buffer
void load(unsigned int width, unsigned int height, pix::Format format, unsigned char const* buffer, float ar = 0.0f);
-
+ Shader& shader() { return m_texture.shader(); }
private:
unsigned int m_width, m_height;
- OpenGLTexture<GL_TEXTURE_RECTANGLE_ARB> m_texture;
+ OpenGLTexture<GL_TEXTURE_RECTANGLE> m_texture;
};
diff --git a/game/video_driver.cc b/game/video_driver.cc
index 5fec179..9f42452 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -71,8 +71,18 @@ Window::Window(unsigned int width, unsigned int height, bool fs): m_windowW(widt
//std::clog << "video/info: GL_EXTENSIONS: " << glGetString(GL_EXTENSIONS) << std::endl;
input::SDL::init(); // Joysticks etc.
- m_shader.reset(new Shader);
- m_shader->compileFile(getThemePath("shaders/core.vert")).compileFile(getThemePath("shaders/core.frag"), "#define TEXTURE_RECT\n").link().bind();
+ shader("surface")
+ .compileFile(getThemePath("shaders/core.vert"))
+ .compileFile(getThemePath("shaders/core.frag"), "#define SURFACE\n")
+ .link()
+ .bind()
+ .setUniformMatrix("colorMatrix", glmath::Matrix());
+ shader("texture")
+ .compileFile(getThemePath("shaders/core.vert"))
+ .compileFile(getThemePath("shaders/core.frag"), "#define TEXTURE\n")
+ .link()
+ .bind()
+ .setUniformMatrix("colorMatrix", glmath::Matrix());
}
Window::~Window() { }
@@ -91,7 +101,6 @@ void Window::render(boost::function<void (void)> drawFunc) {
double vw = s_width, vh = s_height;
glViewport(vx, vy, vw, vh);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- m_shader->setUniformMatrix("colorMatrix", glmath::Matrix());
if (!stereo) {
view(0);
drawFunc();
@@ -106,6 +115,7 @@ void Window::render(boost::function<void (void)> drawFunc) {
}
// Render to actual framebuffer from FBOs
glDisable(GL_BLEND);
+ Shader& sh = shader("surface");
for (int num = 0; num < 2; ++num) {
if (type == 0) {
using namespace glmath;
@@ -126,7 +136,7 @@ void Window::render(boost::function<void (void)> drawFunc) {
colorMatrix.cols[1] = Vec4(0.0, col, gry); // Green in original becomes
colorMatrix.cols[2] = Vec4(0.0, gry, col); // Blue in original becomes
}
- m_shader->setUniformMatrix("colorMatrix", colorMatrix);
+ sh.setUniformMatrix("colorMatrix", colorMatrix);
} else {
double margin = screen->h - s_height;
glViewport(vx, 0.25 * margin + (num ? 0.0 : 0.5 * screen->h), vw, 0.5 * vh);
@@ -135,6 +145,7 @@ void Window::render(boost::function<void (void)> drawFunc) {
UseTexture use(fbo[num].getTexture());
fbo[num].getTexture().draw(Dimensions().stretch(1.0, virtH()), TexCoords(0.0, screenH(), screenW(), 0.0));
}
+ sh.setUniformMatrix("colorMatrix", glmath::Matrix());
}
}
diff --git a/game/video_driver.hh b/game/video_driver.hh
index 45ecf6b..d9e4209 100644
--- a/game/video_driver.hh
+++ b/game/video_driver.hh
@@ -3,7 +3,7 @@
#include "glshader.hh"
#include "glutil.hh"
#include <boost/function.hpp>
-#include <boost/scoped_ptr.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
unsigned int screenW();
unsigned int screenH();
@@ -54,11 +54,14 @@ public:
/// take a screenshot
void screenshot();
+ /// Construct a new shader or return an existing one by name
+ Shader& shader(std::string const& name) { return m_shaders[name]; }
private:
SDL_Surface* screen;
unsigned int m_windowW, m_windowH;
unsigned int m_fsW, m_fsH;
bool m_fullscreen;
- boost::scoped_ptr<Shader> m_shader; ///< core shader used for general drawing
+ typedef boost::ptr_map<std::string, Shader> ShaderMap;
+ ShaderMap m_shaders; ///< Shader programs by name
};
diff --git a/themes/default/shaders/core.frag b/themes/default/shaders/core.frag
index 337c071..97e8222 100644
--- a/themes/default/shaders/core.frag
+++ b/themes/default/shaders/core.frag
@@ -1,19 +1,24 @@
//DEFINES
-#ifdef TEXTURE_RECT
-#extension GL_ARB_texture_rectangle : enable
-#define SAMPLER sampler2DRect
-#define TEXTURE texture2DRect
-#else
-#define SAMPLER sampler2D
-#define TEXTURE texture2D
+uniform mat4 colorMatrix;
+
+#ifdef SURFACE
+#extension GL_ARB_texture_rectangle : require
+uniform sampler2DRect tex;
+#define TFUNC texture2DRect
#endif
-uniform mat4 colorMatrix;
-uniform SAMPLER tex;
+#ifdef TEXTURE
+uniform sampler2D tex;
+#define TFUNC texture2D
+#endif
void main() {
- gl_FragColor = colorMatrix * (gl_Color * TEXTURE(tex, gl_TexCoord[0].st).rgba);
+ gl_FragColor = colorMatrix * (gl_Color
+#ifdef TFUNC
+ * TFUNC(tex, gl_TexCoord[0].st).rgba
+#endif
+ );
}
|