|
From: Tapio V. <aa...@us...> - 2010-10-29 11:08:35
|
Module: performous
Branch: opengl2
Commit: 38af1e04f1d64e0a9b6b4fe1d28f213b10821f70
Author: Tapio Vierros <tap...@gm...>
Date: Fri Oct 29 14:06:15 2010 +0300
Shader refactoring.
* New RAII Shader class to replace previous functions.
* The core shader is a static member of Window-class.
---
game/glshader.cc | 72 ++++++++++++++-----------------------------------
game/glshader.hh | 21 ++++++++------
game/surface.hh | 18 +++++-------
game/video_driver.cc | 39 +++++++++++++++++++++++++--
game/video_driver.hh | 4 +++
5 files changed, 81 insertions(+), 73 deletions(-)
diff --git a/game/glshader.cc b/game/glshader.cc
index 6c9c971..e0e0bd9 100644
--- a/game/glshader.cc
+++ b/game/glshader.cc
@@ -1,62 +1,32 @@
+#include "glshader.hh"
#include "glutil.hh"
-namespace {
- const char *vertex_glsl =
- "void main()"
- "{"
- " gl_FrontColor = gl_Color;"
- " gl_BackColor = gl_Color;"
- " gl_TexCoord[0] = gl_MultiTexCoord0;"
- " gl_Position = ftransform();"
- "}\000";
-
- const char *fragment_glsl =
- "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);"
- "}\000";
-}
-
-void glshader::newShader(struct glshader::Shader *s) {
- s->vert_shader = glCreateShader(GL_VERTEX_SHADER);
- s->frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
+Shader::Shader(const char* vertex_shader, const char* fragment_shader) {
+ vert_shader = glCreateShader(GL_VERTEX_SHADER);
+ frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(s->vert_shader, 1, &vertex_glsl, NULL);
- glShaderSource(s->frag_shader, 1, &fragment_glsl, NULL);
+ glShaderSource(vert_shader, 1, &vertex_shader, NULL);
+ glShaderSource(frag_shader, 1, &fragment_shader, NULL);
- glCompileShader(s->vert_shader);
- glGetShaderiv(s->vert_shader,GL_COMPILE_STATUS,&(s->gl_response));
- if (s->gl_response != GL_TRUE) std::cerr << "Something went wrong compiling the vertex shader." << std::endl;
+ glCompileShader(vert_shader);
+ glGetShaderiv(vert_shader,GL_COMPILE_STATUS, &gl_response);
+ if (gl_response != GL_TRUE) std::cerr << "Something went wrong compiling the vertex shader." << std::endl;
- glCompileShader(s->frag_shader);
- glGetShaderiv(s->frag_shader,GL_COMPILE_STATUS,&(s->gl_response));
- if (s->gl_response != GL_TRUE) std::cerr << "Something went wrong compiling the fragment shader." << std::endl;
+ glCompileShader(frag_shader);
+ glGetShaderiv(frag_shader, GL_COMPILE_STATUS, &gl_response);
+ if (gl_response != GL_TRUE) std::cerr << "Something went wrong compiling the fragment shader." << std::endl;
- s->program = glCreateProgram();
+ program = glCreateProgram();
- glAttachShader(s->program,s->vert_shader);
- glAttachShader(s->program,s->frag_shader);
+ glAttachShader(program, vert_shader);
+ glAttachShader(program, frag_shader);
- glLinkProgram(s->program);
- glUseProgram(s->program);
+ glLinkProgram(program);
+ glUseProgram(program);
}
-void glshader::deleteShader(struct glshader::Shader *s) {
- glDeleteProgram(s->program);
- glDeleteShader(s->vert_shader);
- glDeleteShader(s->frag_shader);
+Shader::~Shader() {
+ glDeleteProgram(program);
+ glDeleteShader(vert_shader);
+ glDeleteShader(frag_shader);
}
diff --git a/game/glshader.hh b/game/glshader.hh
index 073d6d2..24b2668 100644
--- a/game/glshader.hh
+++ b/game/glshader.hh
@@ -1,11 +1,14 @@
#pragma once
-namespace glshader {
- struct Shader {
- GLuint program, vert_shader, frag_shader;
- int gl_response;
- };
-
- void newShader(struct Shader *s);
- void deleteShader(struct Shader *s);
-}
+#include <string>
+#include <GL/glew.h>
+
+struct Shader {
+ Shader(const char* vertex_shader, const char* fragment_shader);
+ Shader() {};
+ ~Shader();
+
+ GLuint program, vert_shader, frag_shader;
+ int gl_response;
+};
+
diff --git a/game/surface.hh b/game/surface.hh
index ad63b2c..44f187c 100644
--- a/game/surface.hh
+++ b/game/surface.hh
@@ -1,14 +1,13 @@
#pragma once
#include "glutil.hh"
+#include "video_driver.hh"
#include <stdexcept>
#include <string>
#include <boost/noncopyable.hpp>
#include <cairo.h>
#include <vector>
-extern struct glshader::Shader shader;
-
/// class for geometry stuff
class Dimensions {
public:
@@ -122,9 +121,9 @@ class UseTexture: boost::noncopyable {
public:
/// constructor
template <GLenum Type> UseTexture(OpenGLTexture<Type> const& s): m_type(s.type()) {
- GLint texmodeloc = glGetUniformLocation(shader.program, "texMode");
- GLint texloc = glGetUniformLocation(shader.program, "tex");
- GLint texrectloc = glGetUniformLocation(shader.program, "texrect");
+ GLint texmodeloc = glGetUniformLocation(Window::shader.program, "texMode");
+ GLint texloc = glGetUniformLocation(Window::shader.program, "tex");
+ GLint texrectloc = glGetUniformLocation(Window::shader.program, "texrect");
glUniform1i(texloc, 0);
glUniform1i(texrectloc, 1);
@@ -132,16 +131,15 @@ class UseTexture: boost::noncopyable {
glEnable(m_type);
switch (Type) {
- case GL_TEXTURE_2D: glActiveTexture(GL_TEXTURE0); glUniform1i(texmodeloc, 1); break;
- case GL_TEXTURE_RECTANGLE_ARB: glActiveTexture(GL_TEXTURE0+1); glUniform1i(texmodeloc, 2); break;
- default: glUniform1i(texmodeloc, 3); break;
+ case GL_TEXTURE_2D: glActiveTexture(GL_TEXTURE0); glUniform1i(texmodeloc, 1); break;
+ case GL_TEXTURE_RECTANGLE_ARB: glActiveTexture(GL_TEXTURE0+1); glUniform1i(texmodeloc, 2); break;
+ default: glUniform1i(texmodeloc, 3); break;
}
glBindTexture(m_type, s.id());
}
~UseTexture() {
- GLint texmodeloc = glGetUniformLocation(shader.program, "texMode");
-
+ GLint texmodeloc = glGetUniformLocation(Window::shader.program, "texMode");
glDisable(m_type);
glUniform1i(texmodeloc, 0);
}
diff --git a/game/video_driver.cc b/game/video_driver.cc
index 81b091e..b6a837a 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -10,7 +10,6 @@
#include <fstream>
#include <SDL.h>
-struct glshader::Shader shader;
namespace {
unsigned s_width;
@@ -31,11 +30,45 @@ namespace {
SDL_GLattr m_attr;
int m_value;
};
+
+ // FIXME: In general, shaders should be loaded from theme files.
+ // Does that apply to these core shaders too?
+
+ const char *vertex_glsl =
+ "void main()"
+ "{"
+ " gl_FrontColor = gl_Color;"
+ " gl_BackColor = gl_Color;"
+ " gl_TexCoord[0] = gl_MultiTexCoord0;"
+ " gl_Position = ftransform();"
+ "}\000";
+
+ const char *fragment_glsl =
+ "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);"
+ "}\000";
}
unsigned int screenW() { return s_width; }
unsigned int screenH() { return s_height; }
+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);
if( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) == -1 ) throw std::runtime_error("SDL_Init failed");
@@ -54,10 +87,10 @@ Window::Window(unsigned int width, unsigned int height, bool fs): m_windowW(widt
SDL_EnableUNICODE(SDL_ENABLE);
if (glewInit() != GLEW_OK) throw std::runtime_error("Initializing GLEW failed (is your OpenGL broken?)");
input::SDL::init();
- glshader::newShader(&shader);
+ shader = Shader(vertex_glsl, fragment_glsl);
}
-Window::~Window() { glshader::deleteShader(&shader); }
+Window::~Window() { }
void Window::blank() {
glClear(GL_COLOR_BUFFER_BIT);
diff --git a/game/video_driver.hh b/game/video_driver.hh
index c865815..2580e4c 100644
--- a/game/video_driver.hh
+++ b/game/video_driver.hh
@@ -1,5 +1,7 @@
#pragma once
+#include "glshader.hh"
+
unsigned int screenW();
unsigned int screenH();
static inline float virtH() { return float(screenH()) / screenW(); }
@@ -36,6 +38,8 @@ class Window {
/// take a screenshot
void screenshot();
+ static Shader shader; // Core shader program for general drawing
+
private:
SDL_Surface* screen;
unsigned int m_windowW, m_windowH;
|