|
From: Lasse Kärkkäi. <tr...@us...> - 2011-03-13 00:49:49
|
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Feb 28 01:22:47 2011 +0100
The longest journey towards legacy-free OpenGL
* Fixes/extensions to glmath.
* Separate uniform functions for Mat3/Mat4.
* Hardcoded position (modelviewprojection) matrix - glTranslatef & friends do nothing now => major b0rkage.
* Normal matrix uses the position matrix directly for now (should be inverse transpose).
---
game/glmath.hh | 8 ++++++++
game/glshader.cc | 4 ++--
game/glshader.hh | 5 ++++-
game/video_driver.cc | 43 +++++++++++++++++++++++--------------------
game/video_driver.hh | 1 +
5 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/game/glmath.hh b/game/glmath.hh
index a013fe5..96bc1c3 100644
--- a/game/glmath.hh
+++ b/game/glmath.hh
@@ -10,9 +10,15 @@
namespace glmath {
+ struct vec4;
+
struct vec3 {
GLfloat x, y, z;
+ explicit vec3(GLfloat const* arr) { std::copy(arr, arr + 3, &x); }
explicit vec3(float x = 0.0, float y = 0.0, float z = 0.0): x(x), y(y), z(z) {}
+ explicit vec3(vec4 const& v);
+ GLfloat& operator[](unsigned j) { return (&x)[j]; }
+ GLfloat const& operator[](unsigned j) const { return (&x)[j]; }
};
struct vec4 {
@@ -24,6 +30,8 @@ namespace glmath {
GLfloat const& operator[](unsigned j) const { return (&x)[j]; }
};
+ inline vec3::vec3(vec4 const& v): x(v.x), y(v.y), z(v.z) {}
+
static inline vec3 operator*(float k, vec3 const& v) { return vec3(k * v.x, k * v.y, k * v.z); }
static inline float dot(vec3 const& a, vec3 const& b) {
diff --git a/game/glshader.cc b/game/glshader.cc
index 6b9242a..e3710f7 100644
--- a/game/glshader.cc
+++ b/game/glshader.cc
@@ -123,7 +123,7 @@ Shader& Shader::link() {
Shader& Shader::bind() {
glutil::GLErrorChecker ec("Shader::bind");
glUseProgram(program);
- setUniformMatrix("colorMatrix", getColorMatrix());
+ setUniformMat4("colorMatrix", getColorMatrix());
return *this;
}
@@ -158,7 +158,7 @@ void VertexArray::Draw(GLint mode) {
}
if (vertNormal != -1) {
glEnableVertexAttribArray(vertNormal);
- glVertexAttribPointer(vertNormal, 4, GL_FLOAT, GL_FALSE, stride, ptr + 2);
+ glVertexAttribPointer(vertNormal, 3, GL_FLOAT, GL_FALSE, stride, ptr + 2);
}
if (vertColor != -1) {
glEnableVertexAttribArray(vertColor);
diff --git a/game/glshader.hh b/game/glshader.hh
index d3355a8..4a08121 100644
--- a/game/glshader.hh
+++ b/game/glshader.hh
@@ -53,7 +53,10 @@ struct Shader: public boost::noncopyable {
Shader& setUniform(const std::string& uniform, float x, float y, float z, float w) {
glUniform4f((*this)[uniform], x, y, z, w); return *this;
}
- Shader& setUniformMatrix(const std::string& uniform, GLfloat const* m) {
+ Shader& setUniformMat3(const std::string& uniform, GLfloat const* m) {
+ glUniformMatrix3fv((*this)[uniform], 1, GL_FALSE, m); return *this;
+ }
+ Shader& setUniformMat4(const std::string& uniform, GLfloat const* m) {
glUniformMatrix4fv((*this)[uniform], 1, GL_FALSE, m); return *this;
}
diff --git a/game/video_driver.cc b/game/video_driver.cc
index 2ea6d62..5a4e9ce 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -89,35 +89,35 @@ Window::Window(unsigned int width, unsigned int height, bool fs): m_windowW(widt
.compileFile(getThemePath("shaders/core.frag"))
.link()
.bind()
- .setUniformMatrix("colorMatrix", glmath::mat4::identity());
+ .setUniformMat4("colorMatrix", glmath::mat4::identity());
shader("surface")
.setDefines("#define ENABLE_TEXTURING 1\n")
.compileFile(getThemePath("shaders/core.vert"))
.compileFile(getThemePath("shaders/core.frag"))
.link()
.bind()
- .setUniformMatrix("colorMatrix", glmath::mat4::identity());
+ .setUniformMat4("colorMatrix", glmath::mat4::identity());
shader("texture")
.setDefines("#define ENABLE_TEXTURING 2\n#define ENABLE_VERTEX_COLOR\n")
.compileFile(getThemePath("shaders/core.vert"))
.compileFile(getThemePath("shaders/core.frag"))
.link()
.bind()
- .setUniformMatrix("colorMatrix", glmath::mat4::identity());
+ .setUniformMat4("colorMatrix", glmath::mat4::identity());
shader("3dobject")
.setDefines("#define ENABLE_LIGHTING\n")
.compileFile(getThemePath("shaders/core.vert"))
.compileFile(getThemePath("shaders/core.frag"))
.link()
.bind()
- .setUniformMatrix("colorMatrix", glmath::mat4::identity());
+ .setUniformMat4("colorMatrix", glmath::mat4::identity());
shader("dancenote")
.setDefines("#define ENABLE_TEXTURING 2\n#define ENABLE_VERTEX_COLOR\n")
.compileFile(getThemePath("shaders/dancenote.vert"))
.compileFile(getThemePath("shaders/core.frag"))
.link()
.bind()
- .setUniformMatrix("colorMatrix", glmath::mat4::identity());
+ .setUniformMat4("colorMatrix", glmath::mat4::identity());
view(0); // For loading screens
}
@@ -138,8 +138,26 @@ void Window::updateStereo(float sepFactor) {
}
}
+void Window::updateTransforms() {
+ // Setup the projection matrix for 2D translates
+ using namespace glmath;
+ float h = virtH();
+ const float f = near_ / z0;
+ mat4 position = frustum(-0.5f * f, 0.5f * f, 0.5f * h * f, -0.5f * h * f, near_, far_) * translate(vec3(0.0, 0.0, -z0));
+ mat3 normal(position);
+ for (ShaderMap::iterator it = m_shaders.begin(); it != m_shaders.end(); ++it) {
+ Shader& sh = *it->second;
+ sh.bind();
+ sh.setUniformMat4("positionMatrix", position);
+ try {
+ sh.setUniformMat3("normalMatrix", normal);
+ } catch(...) {} // Not fatal if normalMatrix is missing (only 3d objects use it)
+ }
+}
+
void Window::render(boost::function<void (void)> drawFunc) {
glutil::GLErrorChecker glerror("Window::render");
+ updateTransforms();
if (s_width < screen->w || s_height < screen->h) glClear(GL_COLOR_BUFFER_BIT); // Black bars
bool stereo = config["graphic/stereo3d"].b();
int type = config["graphic/stereo3dtype"].i();
@@ -215,21 +233,6 @@ void Window::view(unsigned num) {
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
shader("color").bind();
- // Setup the projection matrix for 2D translates
- using namespace glmath;
- glMatrixMode(GL_PROJECTION);
- float h = virtH();
- // OpenGL normalized coordinates go from -1 to 1, change scale so that our 2D translates can use the Performous normalized coordinates instead
- //upload(scale(vec3(2.0f, 2.0f / h, 1.0f)));
- // Note: we do the frustum on MODELVIEW so that 2D positioning can be done via projection matrix.
- // glTranslatef on that will move the image, not the camera (i.e. far-away and nearby objects move the same amount)
- glMatrixMode(GL_MODELVIEW);
- const float f = near_ / z0;
- /*upload(
- scale(vec3(0.5, 0.5 * h, 1.0))
- * frustum(-0.5f * f, 0.5f * f, 0.5f * h * f, -0.5f * h * f, near_, far_)
- * translate(vec3(0.0, 0.0, -z0))
- );*/
// Setup views
double vx = 0.5f * (screen->w - s_width);
double vy = 0.5f * (screen->h - s_height);
diff --git a/game/video_driver.hh b/game/video_driver.hh
index 7a11fa6..7ae29dc 100644
--- a/game/video_driver.hh
+++ b/game/video_driver.hh
@@ -63,6 +63,7 @@ private:
/// @param num 0 = no stereo, 1 = left eye, 2 = right eye
void view(unsigned num);
void updateStereo(float separation);
+ void updateTransforms();
SDL_Surface* screen;
unsigned int m_windowW, m_windowH;
unsigned int m_fsW, m_fsH;
|