|
From: Tapio V. <aa...@us...> - 2010-11-02 13:24:49
|
Module: performous
Branch: opengl2
Commit: bb751601732b8095703883067b7ddbc7662c7dd5
Author: Tapio Vierros <tap...@gm...>
Date: Tue Nov 2 15:21:25 2010 +0200
Separate shaders for 3d objects.
* This is preparation for lighting and other specialized shader uses.
* The actual shaders are the same as core ones for now.
* New UseShader class analogous to UseTexture.
* UseTexture now takes optional shader program argument.
---
game/3dobject.cc | 2 ++
game/3dobject.hh | 5 +++--
game/glshader.cc | 18 +++++++++++++++++-
game/glshader.hh | 25 ++++++++++++++++++++-----
game/guitargraph.cc | 7 +++++--
game/surface.hh | 14 +++++++++-----
game/video_driver.cc | 8 +++-----
game/video_driver.hh | 3 ++-
themes/default/shaders/3dobject.frag | 19 +++++++++++++++++++
themes/default/shaders/3dobject.vert | 7 +++++++
10 files changed, 87 insertions(+), 21 deletions(-)
diff --git a/game/3dobject.cc b/game/3dobject.cc
index 5bf4338..bde08e3 100644
--- a/game/3dobject.cc
+++ b/game/3dobject.cc
@@ -21,6 +21,8 @@ namespace {
}
}
+boost::scoped_ptr<Shader> Object3d::shader;
+
/// Load a Wavefront .obj file and possibly scale it also
void Object3d::loadWavefrontObj(std::string filepath, float scale) {
std::string row;
diff --git a/game/3dobject.hh b/game/3dobject.hh
index 144f9db..cef6e40 100644
--- a/game/3dobject.hh
+++ b/game/3dobject.hh
@@ -12,7 +12,6 @@
// TODO: Exception handling
// TODO: Texture loading
-// TODO: Switch to vertex arrays
/// Point in 3d space
struct Vertex {
@@ -75,10 +74,12 @@ class Object3d: boost::noncopyable {
glTranslatef(x, y, z); // Move to position
if (s != 1.0) glScalef(s,s,s); // Scale if needed
if (m_texture) {
- UseTexture tex(*m_texture);
+ UseTexture tex(*m_texture, shader->program);
drawVBO();
} else {
drawVBO();
}
}
+
+ static boost::scoped_ptr<Shader> shader; ///< shader used for 3d objects
};
diff --git a/game/glshader.cc b/game/glshader.cc
index 693e253..bb0f967 100644
--- a/game/glshader.cc
+++ b/game/glshader.cc
@@ -1,5 +1,8 @@
#include "glshader.hh"
#include "glutil.hh"
+#include "video_driver.hh"
+#include "3dobject.hh"
+#include "fs.hh"
#include <fstream>
#include <stdexcept>
@@ -51,6 +54,7 @@ Shader::~Shader() {
glDeleteProgram(program);
glDeleteShader(vert_shader);
glDeleteShader(frag_shader);
+ //std::clog << "shader/info: Shader program " << (unsigned)program << " deleted." << std::endl;
}
@@ -104,5 +108,17 @@ void Shader::loadFromMemory(const char* vert_source, const char* frag_source, bo
glutil::GLErrorChecker linkerror("Shader::loadFromMemory - glLinkProgram");
if (use) bind();
- glutil::GLErrorChecker glerror("Shader::loadFromMemory - bind");
+}
+
+
+void Shader::bind() {
+ glUseProgram(program);
+ glutil::GLErrorChecker glerror("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")));
}
diff --git a/game/glshader.hh b/game/glshader.hh
index 016c601..ed394eb 100644
--- a/game/glshader.hh
+++ b/game/glshader.hh
@@ -2,21 +2,36 @@
#include <string>
#include <GL/glew.h>
+#include <boost/noncopyable.hpp>
-struct Shader {
+struct Shader: public boost::noncopyable {
Shader();
- Shader(const std::string& vert_path, const std::string& frag_path, bool use = true);
+ Shader(const std::string& vert_path, const std::string& frag_path, bool use = false);
~Shader();
/** Loads the shader from files. */
- void loadFromFile(const std::string& vert_path, const std::string& frag_path, bool use = true);
+ void loadFromFile(const std::string& vert_path, const std::string& frag_path, bool use = false);
/** Loads the shader from memory. */
- void loadFromMemory(const char* vert_source, const char* frag_source, bool use = true);
+ void loadFromMemory(const char* vert_source, const char* frag_source, bool use = false);
/** Binds the shader into use. */
- void bind() { glUseProgram(program); }
+ void bind();
GLuint program, vert_shader, frag_shader;
int gl_response;
};
+
+/** Temporarily switch shader in a RAII manner. */
+struct UseShader {
+ UseShader(Shader& new_shader, Shader& old_shader): m_old(old_shader) {
+ new_shader.bind();
+ }
+ ~UseShader() { m_old.bind(); }
+ private:
+ Shader& m_old;
+};
+
+
+/** Load shaders. */
+void loadShaders();
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index 7587dcf..e871412 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -855,7 +855,8 @@ void GuitarGraph::draw(double time) {
}
// Draw the notes
- { glutil::UseLighting lighting(m_use3d);
+ { UseShader objectShader(*Object3d::shader, *Window::shader);
+ //glutil::UseLighting lighting(m_use3d);
// Draw drum fills / Big Rock Endings
bool drumfill = m_dfIt != m_drumfills.end() && m_dfIt->begin - time <= future;
if (drumfill) {
@@ -919,7 +920,9 @@ void GuitarGraph::draw(double time) {
}
}
}
- } //< disable lighting
+ glutil::GLErrorChecker::reset(); // FIXME: There are errors here.
+ //glutil::GLErrorChecker glerror("GuitarGraph::draw - objects");
+ } //< restore core shader
// Draw flames
for (int fret = 0; fret < m_pads; ++fret) { // Loop through the frets
if (m_drums && fret == 0) { // Skip bass drum
diff --git a/game/surface.hh b/game/surface.hh
index 44f187c..dbb8e9b 100644
--- a/game/surface.hh
+++ b/game/surface.hh
@@ -120,10 +120,13 @@ template <GLenum Type> class OpenGLTexture: boost::noncopyable {
class UseTexture: boost::noncopyable {
public:
/// constructor
- template <GLenum Type> UseTexture(OpenGLTexture<Type> const& s): m_type(s.type()) {
- GLint texmodeloc = glGetUniformLocation(Window::shader.program, "texMode");
- GLint texloc = glGetUniformLocation(Window::shader.program, "tex");
- GLint texrectloc = glGetUniformLocation(Window::shader.program, "texrect");
+ template <GLenum Type> UseTexture(OpenGLTexture<Type> const& s, GLuint prog = 0):
+ m_type(s.type()), m_program(prog) {
+ if (m_program == 0) m_program = Window::shader->program; // Default shader
+
+ GLint texmodeloc = glGetUniformLocation(m_program, "texMode");
+ GLint texloc = glGetUniformLocation(m_program, "tex");
+ GLint texrectloc = glGetUniformLocation(m_program, "texrect");
glUniform1i(texloc, 0);
glUniform1i(texrectloc, 1);
@@ -139,13 +142,14 @@ class UseTexture: boost::noncopyable {
glBindTexture(m_type, s.id());
}
~UseTexture() {
- GLint texmodeloc = glGetUniformLocation(Window::shader.program, "texMode");
+ GLint texmodeloc = glGetUniformLocation(m_program, "texMode");
glDisable(m_type);
glUniform1i(texmodeloc, 0);
}
private:
GLenum m_type;
+ GLuint m_program;
};
template <GLenum Type> void OpenGLTexture<Type>::draw(Dimensions const& dim, TexCoords const& tex) const {
diff --git a/game/video_driver.cc b/game/video_driver.cc
index 68621a0..91bdb1e 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -36,7 +36,7 @@ namespace {
unsigned int screenW() { return s_width; }
unsigned int screenH() { return s_height; }
-Shader Window::shader;
+boost::scoped_ptr<Shader> Window::shader;
Window::Window(unsigned int width, unsigned int height, bool fs): m_windowW(width), m_windowH(height), m_fullscreen(fs) {
std::atexit(SDL_Quit);
@@ -62,10 +62,8 @@ Window::Window(unsigned int width, unsigned int height, bool fs): m_windowW(widt
// Extensions would need more complex outputting, otherwise they will break clog.
//std::clog << "video/info: GL_EXTENSIONS: " << glGetString(GL_EXTENSIONS) << std::endl;
- // Joystick etc. initialization
- input::SDL::init();
- // Shaders
- shader = Shader(getThemePath("shaders/core.vert"), getThemePath("shaders/core.frag"));
+ input::SDL::init(); // Joysticks etc.
+ loadShaders(); // Shaders
}
Window::~Window() { }
diff --git a/game/video_driver.hh b/game/video_driver.hh
index 2580e4c..3dc3033 100644
--- a/game/video_driver.hh
+++ b/game/video_driver.hh
@@ -1,6 +1,7 @@
#pragma once
#include "glshader.hh"
+#include <boost/scoped_ptr.hpp>
unsigned int screenW();
unsigned int screenH();
@@ -38,7 +39,7 @@ class Window {
/// take a screenshot
void screenshot();
- static Shader shader; // Core shader program for general drawing
+ static boost::scoped_ptr<Shader> shader; ///< core shader used for general drawing
private:
SDL_Surface* screen;
diff --git a/themes/default/shaders/3dobject.frag b/themes/default/shaders/3dobject.frag
new file mode 100644
index 0000000..ae5a802
--- /dev/null
+++ b/themes/default/shaders/3dobject.frag
@@ -0,0 +1,19 @@
+uniform int texMode;
+uniform sampler2D tex;
+uniform sampler2DRect texrect;
+
+void main()
+{
+ vec4 texel;
+ vec4 color;
+ if (texMode == 1) {
+ texel = texture2D(tex, gl_TexCoord[0].st).rgba;
+ } else if (texMode == 2) {
+ texel = texture(texrect, gl_TexCoord[0].st).rgba;
+ } else if (texMode == 0) {
+ texel = gl_Color;
+ } else {
+ texel = vec4(1.0,0.0,0.0,1.0);
+ }
+ gl_FragColor = vec4(texel.rgb*gl_Color.rgb, texel.a*gl_Color.a);
+}
diff --git a/themes/default/shaders/3dobject.vert b/themes/default/shaders/3dobject.vert
new file mode 100644
index 0000000..570a61a
--- /dev/null
+++ b/themes/default/shaders/3dobject.vert
@@ -0,0 +1,7 @@
+void main()
+{
+ gl_FrontColor = gl_Color;
+ gl_BackColor = gl_Color;
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_Position = ftransform();
+}
|