|
From: Tapio V. <aa...@us...> - 2010-11-04 22:35:16
|
Module: performous
Branch: opengl2
Commit: 439015947a929fc35b47aa9f5433cd863d3ee2c7
Author: Tapio Vierros <tap...@gm...>
Date: Fri Nov 5 00:32:00 2010 +0200
Intro screen background now changes its color dynamically through a shader.
Also, UseTexture can now figure out the shader-in-use itself and
it is possible to access the currently active Shader object globally.
---
game/3dobject.hh | 2 +-
game/glshader.cc | 8 +++++++-
game/glshader.hh | 20 +++++++++++++++++++-
game/screen_intro.cc | 8 +++++++-
game/surface.hh | 4 ++--
game/theme.cc | 2 ++
game/theme.hh | 6 ++++++
themes/default/shaders/intro.frag | 28 ++++++++++++++++++++++++++++
themes/default/shaders/intro.vert | 7 +++++++
9 files changed, 79 insertions(+), 6 deletions(-)
diff --git a/game/3dobject.hh b/game/3dobject.hh
index 6a32cb7..834cb28 100644
--- a/game/3dobject.hh
+++ b/game/3dobject.hh
@@ -72,7 +72,7 @@ class Object3d: boost::noncopyable {
if (s != 1.0) glScalef(s,s,s); // Scale if needed
UseShader objectShader(*shader); // Switch shader
if (m_texture) {
- UseTexture tex(*m_texture, *shader);
+ UseTexture tex(*m_texture);
drawVBO();
} else {
drawVBO();
diff --git a/game/glshader.cc b/game/glshader.cc
index b2c6044..3d0f965 100644
--- a/game/glshader.cc
+++ b/game/glshader.cc
@@ -2,6 +2,7 @@
#include "glutil.hh"
#include "video_driver.hh"
#include "3dobject.hh"
+#include "theme.hh"
#include "fs.hh"
#include <fstream>
@@ -42,8 +43,9 @@ namespace {
}
}
+Shader::ShaderMap Shader::shaders;
-Shader::Shader(): program(), vert_shader(), frag_shader() {}
+Shader::Shader(): program(0), vert_shader(), frag_shader() {}
Shader::Shader(const std::string& vert_path, const std::string& frag_path, bool use) {
loadFromFile(vert_path, frag_path, use);
@@ -111,8 +113,11 @@ void Shader::loadFromMemory(const char* vert_source, const char* frag_source, bo
tex = glGetUniformLocation(program, "tex");
texRect = glGetUniformLocation(program, "texRect");
texMode = glGetUniformLocation(program, "texMode");
+ anim = glGetUniformLocation(program, "anim");
glutil::GLErrorChecker uniformerror("Shader::loadFromMemory - glGetUniformLocation");
+ shaders[program] = this;
+
if (use) bind();
}
@@ -127,4 +132,5 @@ void Shader::bind() {
void loadShaders() {
Window::shader.reset(new Shader(getThemePath("shaders/core.vert"), getThemePath("shaders/core.frag"), true));
Object3d::shader.reset(new Shader(getThemePath("shaders/3dobject.vert"), getThemePath("shaders/3dobject.frag")));
+ ThemeIntro::shader.reset(new Shader(getThemePath("shaders/intro.vert"), getThemePath("shaders/intro.frag")));
}
diff --git a/game/glshader.hh b/game/glshader.hh
index 4705117..71c285d 100644
--- a/game/glshader.hh
+++ b/game/glshader.hh
@@ -1,6 +1,7 @@
#pragma once
#include <string>
+#include <map>
#include <GL/glew.h>
#include <boost/noncopyable.hpp>
@@ -19,8 +20,25 @@ struct Shader: public boost::noncopyable {
void bind();
GLuint program, vert_shader, frag_shader; ///< shader object ids
- GLint tex, texRect, texMode; ///< uniform locations
+ // TODO: Should probably use an std::map for these and cache on-the-fly/on-demand.
+ // Also provide a nice access to setting the uniform.
+ GLint tex, texRect, texMode, anim; ///< uniform locations
int gl_response;
+
+ // Some operators
+ operator bool() const { return program != 0; }
+ 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 shaders[i];
+ }
+
+ typedef std::map<GLint, Shader*> ShaderMap;
+ static ShaderMap shaders;
};
diff --git a/game/screen_intro.cc b/game/screen_intro.cc
index dd7330d..61e9023 100644
--- a/game/screen_intro.cc
+++ b/game/screen_intro.cc
@@ -6,6 +6,7 @@
#include "joystick.hh"
#include "theme.hh"
#include "menu.hh"
+#include "xtime.hh"
ScreenIntro::ScreenIntro(std::string const& name, Audio& audio): Screen(name), m_audio(audio), m_first(true) {
@@ -112,7 +113,12 @@ void ScreenIntro::draw_menu_options() {
}
void ScreenIntro::draw() {
- theme->bg.draw();
+ {
+ UseShader s(*ThemeIntro::shader);
+ float anim = std::abs((((SDL_GetTicks() % 10000) / 10000.f) - 0.5f) * 2.0f);
+ glUniform1f(ThemeIntro::shader->anim, anim);
+ theme->bg.draw();
+ }
if (m_menu.current().image) m_menu.current().image->draw();
// Comment
theme->comment_bg.dimensions.center().screenBottom(-0.01);
diff --git a/game/surface.hh b/game/surface.hh
index 574a6ae..2a9ef6b 100644
--- a/game/surface.hh
+++ b/game/surface.hh
@@ -120,8 +120,8 @@ template <GLenum Type> class OpenGLTexture: boost::noncopyable {
class UseTexture: boost::noncopyable {
public:
/// constructor
- template <GLenum Type> UseTexture(OpenGLTexture<Type> const& s, Shader& shdr = *Window::shader):
- m_shader(shdr) {
+ template <GLenum Type> UseTexture(OpenGLTexture<Type> const& s):
+ m_shader(*Shader::current()) {
glUniform1i(m_shader.tex, 0);
glUniform1i(m_shader.texRect, 1);
diff --git a/game/theme.cc b/game/theme.cc
index dbaab57..b07051d 100644
--- a/game/theme.cc
+++ b/game/theme.cc
@@ -44,6 +44,8 @@ ThemeAudioDevices::ThemeAudioDevices():
comment_bg(getThemePath("mainmenu_comment_bg.svg"))
{}
+boost::scoped_ptr<Shader> ThemeIntro::shader;
+
ThemeIntro::ThemeIntro():
Theme(getThemePath("intro_bg.svg")),
back_h(getThemePath("mainmenu_back_highlight.svg")),
diff --git a/game/theme.hh b/game/theme.hh
index 8b77f32..ac9bd48 100644
--- a/game/theme.hh
+++ b/game/theme.hh
@@ -4,8 +4,12 @@
#include "surface.hh"
#include "cachemap.hh"
#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
#include <string>
+
+class Shader;
+
/// abstract theme class
class Theme: boost::noncopyable {
protected:
@@ -90,6 +94,8 @@ public:
Surface comment_bg;
/// configuration comment background (short tip)
Surface short_comment_bg;
+ /// Custom background shader
+ static boost::scoped_ptr<Shader> shader;
};
/// theme for instrument menu
diff --git a/themes/default/shaders/intro.frag b/themes/default/shaders/intro.frag
new file mode 100644
index 0000000..f4665b3
--- /dev/null
+++ b/themes/default/shaders/intro.frag
@@ -0,0 +1,28 @@
+#extension GL_ARB_texture_rectangle : enable
+
+uniform int texMode;
+uniform sampler2D tex;
+uniform sampler2DRect texRect;
+
+uniform float anim;
+
+void main()
+{
+ vec4 texel;
+
+ if (texMode == 1) {
+ texel = texture2D(tex, gl_TexCoord[0].st).rgba;
+ } else if (texMode == 2) {
+ texel = texture2DRect(texRect, gl_TexCoord[0].st).rgba;
+ } else if (texMode == 0) {
+ texel = gl_Color;
+ } else {
+ texel = vec4(1.0, 0.0, 1.0, 1.0); // Magenta to highlight
+ }
+
+ float r = anim * 0.5;
+ float g = anim * 0.5 + 0.5;
+ float b = anim * 0.3 + 0.7;
+
+ gl_FragColor = vec4(texel.r * r, texel.g * g, texel.b * b, texel.a);
+}
diff --git a/themes/default/shaders/intro.vert b/themes/default/shaders/intro.vert
new file mode 100644
index 0000000..570a61a
--- /dev/null
+++ b/themes/default/shaders/intro.vert
@@ -0,0 +1,7 @@
+void main()
+{
+ gl_FrontColor = gl_Color;
+ gl_BackColor = gl_Color;
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_Position = ftransform();
+}
|