From patchwork Tue Jun 21 12:49:16 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: alexandros.frantzis@linaro.org X-Patchwork-Id: 2123 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 3B63523F4F for ; Tue, 21 Jun 2011 12:49:21 +0000 (UTC) Received: from mail-vw0-f52.google.com (mail-vw0-f52.google.com [209.85.212.52]) by fiordland.canonical.com (Postfix) with ESMTP id 8D437A187E5 for ; Tue, 21 Jun 2011 12:49:20 +0000 (UTC) Received: by vws16 with SMTP id 16so4622674vws.11 for ; Tue, 21 Jun 2011 05:49:20 -0700 (PDT) Received: by 10.52.98.97 with SMTP id eh1mr9137913vdb.7.1308660559967; Tue, 21 Jun 2011 05:49:19 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.52.183.130 with SMTP id em2cs63919vdc; Tue, 21 Jun 2011 05:49:19 -0700 (PDT) Received: by 10.227.32.69 with SMTP id b5mr2031064wbd.99.1308660557781; Tue, 21 Jun 2011 05:49:17 -0700 (PDT) Received: from adelie.canonical.com (adelie.canonical.com [91.189.90.139]) by mx.google.com with ESMTP id ff9si11694547wbb.11.2011.06.21.05.49.17; Tue, 21 Jun 2011 05:49:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) client-ip=91.189.90.139; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) smtp.mail=bounces@canonical.com Received: from loganberry.canonical.com ([91.189.90.37]) by adelie.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1QZ0OK-0008In-TZ for ; Tue, 21 Jun 2011 12:49:16 +0000 Received: from loganberry.canonical.com (localhost [127.0.0.1]) by loganberry.canonical.com (Postfix) with ESMTP id DAF752E8043 for ; Tue, 21 Jun 2011 12:49:16 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glmark2 X-Launchpad-Branch: ~afrantzis/glmark2/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 84 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~afrantzis/glmark2/trunk] Rev 84: Merge port to LibMatrix/Program infrastructure. Message-Id: <20110621124916.14638.16667.launchpad@loganberry.canonical.com> Date: Tue, 21 Jun 2011 12:49:16 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13242"; Instance="initZopeless config overlay" X-Launchpad-Hash: fcd8392b36892182f964577fc7cb5fb37509fdda Merge authors: Alexandros Frantzis (afrantzis) ------------------------------------------------------------ revno: 84 [merge] committer: Alexandros Frantzis branch nick: trunk timestamp: Tue 2011-06-21 14:55:13 +0300 message: Merge port to LibMatrix/Program infrastructure. removed: src/matrix.cpp src/matrix.h src/shader.cpp src/shader.h src/vector.cpp src/vector.h added: src/libmatrix/ src/libmatrix/COPYING src/libmatrix/Makefile src/libmatrix/README src/libmatrix/mat.cc src/libmatrix/mat.h src/libmatrix/matrix_inverse_test.cc src/libmatrix/program.cc src/libmatrix/program.h src/libmatrix/stack.h src/libmatrix/vec.h modified: src/mesh.cpp src/mesh.h src/model.cpp src/scene.cpp src/scene.h src/scenebuild.cpp src/sceneshading.cpp src/scenetexture.cpp src/screen-sdl.cpp src/screen.h src/wscript_build --- lp:glmark2 https://code.launchpad.net/~afrantzis/glmark2/trunk You are subscribed to branch lp:glmark2. To unsubscribe from this branch go to https://code.launchpad.net/~afrantzis/glmark2/trunk/+edit-subscription === added directory 'src/libmatrix' === added file 'src/libmatrix/COPYING' --- src/libmatrix/COPYING 1970-01-01 00:00:00 +0000 +++ src/libmatrix/COPYING 2011-06-17 07:54:50 +0000 @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2010 Linaro Limited + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. === added file 'src/libmatrix/Makefile' --- src/libmatrix/Makefile 1970-01-01 00:00:00 +0000 +++ src/libmatrix/Makefile 2011-06-17 07:54:50 +0000 @@ -0,0 +1,17 @@ +TARGETS = libmatrix.a matrix_inverse_test +SRCS = mat.cc program.cc matrix_inverse_test.cc +OBJS = $(SRCS:.cc=.o) +CXXFLAGS = -Wall -Werror -pedantic -O3 + +default: $(TARGETS) + +mat.o : mat.cc mat.h +program.o: program.cc program.h +matrix_inverse_test.o: matrix_inverse_test.cc mat.h +matrix_inverse_test: matrix_inverse_test.o libmatrix.a + $(CXX) -o $@ $? +libmatrix.a : mat.o mat.h stack.h vec.h program.o program.h + $(AR) -r $@ $(OBJS) + +clean : + $(RM) $(OBJS) $(TARGETS) === added file 'src/libmatrix/README' --- src/libmatrix/README 1970-01-01 00:00:00 +0000 +++ src/libmatrix/README 2011-06-17 07:54:50 +0000 @@ -0,0 +1,11 @@ +libmatrix +========= + +A simple C++ template library that provides containers and arithmetic +operations for vectors, matrices and matrix stacks of 2, 3 and 4 dimensions. +Additionally, it provides implementations of the more common matrix +transformations described by the OpenGL programming guide. libmatrix does +not make any OpenGL calls, it merely replaces a portion of the fixed-function +vertex processing API that have been removed from newer releases of core OpenGL +and omitted from OpenGL ES. The goal is simply to provide developers an easier +point of entry into developing for OpenGL and OpenGL ES. === added file 'src/libmatrix/mat.cc' --- src/libmatrix/mat.cc 1970-01-01 00:00:00 +0000 +++ src/libmatrix/mat.cc 2011-06-17 07:54:50 +0000 @@ -0,0 +1,173 @@ +// +// Copyright (c) 2010 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#include +#include "mat.h" + +namespace LibMatrix +{ +namespace Mat4 +{ + +mat4 +translate(float x, float y, float z) +{ + mat4 t; + t[0][3] = x; + t[1][3] = y; + t[2][3] = z; + return t; +} + +mat4 +scale(float x, float y, float z) +{ + mat4 s; + s[0][0] = x; + s[1][1] = y; + s[2][2] = z; + return s; +} + +// +// As per the OpenGL "red book" definition of rotation, from the appendix +// on Homogeneous Coordinates and Transformation Matrices, the "upper left" +// 3x3 portion of the result matrix is formed by: +// +// M = uuT + (cos a)(I - uuT) + (sin a)S +// +// where u is the normalized input vector, uuT is the outer product of that +// vector and its transpose, I is the identity matrix and S is the matrix: +// +// | 0 -z' y' | +// | z' 0 -x' | +// | -y' x' 0 | +// +// where x', y' and z' are the elements of u +// +mat4 +rotate(float angle, float x, float y, float z) +{ + vec3 u(x, y, z); + u.normalize(); + mat3 uuT = outer(u, u); + mat3 s; + s[0][0] = 0; + s[0][1] = -u.z(); + s[0][2] = u.y(); + s[1][0] = u.z(); + s[1][1] = 0; + s[1][2] = -u.x(); + s[2][0] = -u.y(); + s[2][1] = u.x(); + s[2][2] = 0; + mat3 i; + i -= uuT; + // degrees to radians + float angleRadians(angle * M_PI / 180.0); + i *= cos(angleRadians); + s *= sin(angleRadians); + i += s; + mat3 m = uuT + i; + mat4 r; + r[0][0] = m[0][0]; + r[0][1] = m[0][1]; + r[0][2] = m[0][2]; + r[1][0] = m[1][0]; + r[1][1] = m[1][1]; + r[1][2] = m[1][2]; + r[2][0] = m[2][0]; + r[2][1] = m[2][1]; + r[2][2] = m[2][2]; + return r; +} + +mat4 +frustum(float left, float right, float bottom, float top, float near, float far) +{ + float twiceNear(2 * near); + float width(right - left); + float height(top - bottom); + float depth(far - near); + mat4 f; + f[0][0] = twiceNear / width; + f[0][2] = (right + left) / width; + f[1][1] = twiceNear / height; + f[1][2] = (top + bottom) / height; + f[2][2] = -(far + near) / depth; + f[2][3] = -(twiceNear * far) / depth; + f[3][2] = -1; + f[3][3] = 0; + return f; +} + +mat4 +ortho(float left, float right, float bottom, float top, float near, float far) +{ + float width(right - left); + float height(top - bottom); + float depth(far - near); + mat4 o; + o[0][0] = 2 / width; + o[0][3] = (right + left) / width; + o[1][1] = 2 / height; + o[1][3] = (top + bottom) / height; + o[2][2] = -2 / depth; + o[2][3] = (far + near) / depth; + return o; +} + +mat4 +perspective(float fovy, float aspect, float zNear, float zFar) +{ + // degrees to radians + float fovyRadians(fovy * M_PI / 180.0); + // cotangent(x) = 1/tan(x) + float f = 1/tan(fovyRadians / 2); + float depth(zNear - zFar); + mat4 p; + p[0][0] = f / aspect; + p[1][1] = f; + p[2][2] = (zFar + zNear) / depth; + p[2][3] = (2 * zFar * zNear) / depth; + p[3][2] = -1; + p[3][3] = 0; + return p; +} + +mat4 lookAt(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ) +{ + vec3 f(centerX - eyeX, centerY - eyeY, centerZ - eyeZ); + f.normalize(); + vec3 up(upX, upY, upZ); + vec3 s = vec3::cross(f, up); + vec3 u = vec3::cross(s, f); + s.normalize(); + u.normalize(); + mat4 la; + la[0][0] = s.x(); + la[0][1] = s.y(); + la[0][2] = s.z(); + la[1][0] = u.x(); + la[1][1] = u.y(); + la[1][2] = u.z(); + la[2][0] = -f.x(); + la[2][1] = -f.y(); + la[2][2] = -f.z(); + la *= translate(-eyeX, -eyeY, -eyeZ); + return la; +} + +} // namespace Mat4 + +} // namespace LibMatrix === added file 'src/libmatrix/mat.h' --- src/libmatrix/mat.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/mat.h 2011-06-17 07:54:50 +0000 @@ -0,0 +1,1074 @@ +// +// Copyright (c) 2010 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#ifndef MAT_H_ +#define MAT_H_ +#include +#include +#include +#include "vec.h" + +namespace LibMatrix +{ +// Proxy class for providing the functionality of a doubly-dimensioned array +// representation of matrices. Each matrix class defines its operator[] +// to return an ArrayProxy. The ArrayProxy then returns the appropriate item +// from its operator[]. +template +class ArrayProxy +{ +public: + ArrayProxy(T* data) { data_ = data; } + ~ArrayProxy() { data_ = 0; } + T& operator[](int index) + { + return data_[index * dimension]; + } + const T& operator[](int index) const + { + return data_[index * dimension]; + } +private: + T* data_; +}; + + +// Programming interfaces to all matrix objects are represented row-centric +// (i.e. C/C++ style references to the data appear as matrix[row][column]). +// However, the internal data representation is column-major, so when using +// the raw data access member to treat the data as a singly-dimensioned array, +// it does not have to be transposed. +template +class tmat2 +{ +public: + tmat2() + { + setIdentity(); + } + tmat2(const tmat2& m) + { + m_[0] = m.m_[0]; + m_[1] = m.m_[1]; + m_[2] = m.m_[2]; + m_[3] = m.m_[3]; + } + tmat2(const T& c0r0, const T& c0r1, const T& c1r0, const T& c1r1) + { + m_[0] = c0r0; + m_[1] = c0r1; + m_[2] = c1r0; + m_[3] = c1r1; + } + ~tmat2() {} + + void setIdentity() + { + m_[0] = 1; + m_[1] = 0; + m_[2] = 0; + m_[3] = 1; + } + + tmat2& transpose() + { + T tmp_val = m_[1]; + m_[1] = m_[2]; + m_[2] = tmp_val; + return *this; + } + + T determinant() + { + return (m_[0] * m_[3]) - (m_[2] * m_[1]); + } + + tmat2& inverse() throw(std::runtime_error) + { + T d(determinant()); + if (d == static_cast(0)) + { + throw std::runtime_error("Matrix is noninvertible!!!!"); + } + T c0r0(m_[3] / d); + T c0r1(-m_[1] / d); + T c1r0(-m_[2] / d); + T c1r1(m_[0] / d); + m_[0] = c0r0; + m_[1] = c0r1; + m_[2] = c1r0; + m_[3] = c1r1; + return *this; + } + + void print() const + { + static const int precision(6); + // row 0 + std::cout << "| "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2]; + std::cout << " |" << std::endl; + // row 1 + std::cout << "| "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3]; + std::cout << " |" << std::endl; + } + + operator const T*() const { return &m_[0];} + + bool operator==(const tmat2& rhs) const + { + return m_[0] == rhs.m_[0] && + m_[1] == rhs.m_[1] && + m_[2] == rhs.m_[2] && + m_[3] == rhs.m_[3]; + } + + bool operator!=(const tmat2& rhs) const + { + return !(*this == rhs); + } + + tmat2& operator=(const tmat2& rhs) + { + if (this != &rhs) + { + m_[0] = rhs.m_[0]; + m_[1] = rhs.m_[1]; + m_[2] = rhs.m_[2]; + m_[3] = rhs.m_[3]; + } + return *this; + } + + tmat2& operator+=(const tmat2& rhs) + { + m_[0] += rhs.m_[0]; + m_[1] += rhs.m_[1]; + m_[2] += rhs.m_[2]; + m_[3] += rhs.m_[3]; + return *this; + } + + const tmat2 operator+(const tmat2& rhs) + { + return tmat2(*this) += rhs; + } + + tmat2& operator-=(const tmat2& rhs) + { + m_[0] -= rhs.m_[0]; + m_[1] -= rhs.m_[1]; + m_[2] -= rhs.m_[2]; + m_[3] -= rhs.m_[3]; + return *this; + } + + const tmat2 operator-(const tmat2& rhs) + { + return tmat2(*this) += rhs; + } + + tmat2& operator*=(const tmat2& rhs) + { + T c0r0((m_[0] * rhs.m_[0]) + (m_[2] * rhs.m_[1])); + T c0r1((m_[1] * rhs.m_[0]) + (m_[3] * rhs.m_[1])); + T c1r0((m_[0] * rhs.m_[2]) + (m_[2] * rhs.m_[3])); + T c1r1((m_[1] * rhs.m_[2]) + (m_[3] * rhs.m_[3])); + m_[0] = c0r0; + m_[1] = c0r1; + m_[2] = c1r0; + m_[3] = c1r1; + return *this; + } + + const tmat2 operator*(const tmat2& rhs) + { + return tmat2(*this) *= rhs; + } + + tmat2& operator*=(const T& rhs) + { + m_[0] *= rhs; + m_[1] *= rhs; + m_[2] *= rhs; + m_[3] *= rhs; + return *this; + } + + const tmat2 operator*(const T& rhs) + { + return tmat2(*this) *= rhs; + } + + tmat2& operator/=(const T& rhs) + { + m_[0] /= rhs; + m_[1] /= rhs; + m_[2] /= rhs; + m_[3] /= rhs; + return *this; + } + + const tmat2 operator/(const T& rhs) + { + return tmat2(*this) /= rhs; + } + + ArrayProxy operator[](int index) + { + return ArrayProxy(&m_[index]); + } + const ArrayProxy operator[](int index) const + { + return ArrayProxy(const_cast(&m_[index])); + } + +private: + T m_[4]; +}; + +template +const tmat2 operator*(const T& lhs, const tmat2& rhs) +{ + return tmat2(rhs) * lhs; +} + +template +const tvec2 operator*(const tvec2& lhs, const tmat2& rhs) +{ + T x((lhs.x() * rhs[0][0]) + (lhs.y() * rhs[1][0])); + T y((lhs.x() * rhs[0][1]) + (lhs.y() * rhs[1][1])); + return tvec2(x,y); +} + +template +const tvec2 operator*(const tmat2& lhs, const tvec2& rhs) +{ + T x((lhs[0][0] * rhs.x()) + (lhs[0][1] * rhs.y())); + T y((lhs[1][0] * rhs.x()) + (lhs[1][1] * rhs.y())); + return tvec2(x, y); +} + +template +const tmat2 outer(const tvec2& a, const tvec2& b) +{ + tmat2 product; + product[0][0] = a.x() * b.x(); + product[0][1] = a.x() * b.y(); + product[1][0] = a.y() * b.x(); + product[1][1] = a.y() * b.y(); + return product; +} + +template +class tmat3 +{ +public: + tmat3() + { + setIdentity(); + } + tmat3(const tmat3& m) + { + m_[0] = m.m_[0]; + m_[1] = m.m_[1]; + m_[2] = m.m_[2]; + m_[3] = m.m_[3]; + m_[4] = m.m_[4]; + m_[5] = m.m_[5]; + m_[6] = m.m_[6]; + m_[7] = m.m_[7]; + m_[8] = m.m_[8]; + } + tmat3(const T& c0r0, const T& c0r1, const T& c0r2, + const T& c1r0, const T& c1r1, const T& c1r2, + const T& c2r0, const T& c2r1, const T& c2r2) + { + m_[0] = c0r0; + m_[1] = c0r1; + m_[2] = c0r2; + m_[3] = c1r0; + m_[4] = c1r1; + m_[5] = c1r2; + m_[6] = c2r0; + m_[7] = c2r1; + m_[8] = c2r2; + } + ~tmat3() {} + + void setIdentity() + { + m_[0] = 1; + m_[1] = 0; + m_[2] = 0; + m_[3] = 0; + m_[4] = 1; + m_[5] = 0; + m_[6] = 0; + m_[7] = 0; + m_[8] = 1; + } + + tmat3& transpose() + { + T tmp_val = m_[1]; + m_[1] = m_[3]; + m_[3] = tmp_val; + tmp_val = m_[2]; + m_[2] = m_[6]; + m_[6] = tmp_val; + tmp_val = m_[5]; + m_[5] = m_[7]; + m_[7] = tmp_val; + return *this; + } + + T determinant() + { + tmat2 minor0(m_[4], m_[5], m_[7], m_[8]); + tmat2 minor3(m_[1], m_[2], m_[7], m_[8]); + tmat2 minor6(m_[1], m_[2], m_[4], m_[5]); + return (m_[0] * minor0.determinant()) - + (m_[3] * minor3.determinant()) + + (m_[6] * minor6.determinant()); + } + + tmat3& inverse() throw(std::runtime_error) + { + T d(determinant()); + if (d == static_cast(0)) + { + throw std::runtime_error("Matrix is noninvertible!!!!"); + } + tmat2 minor0(m_[4], m_[5], m_[7], m_[8]); + tmat2 minor1(m_[7], m_[8], m_[1], m_[2]); + tmat2 minor2(m_[1], m_[2], m_[4], m_[5]); + tmat2 minor3(m_[6], m_[8], m_[3], m_[5]); + tmat2 minor4(m_[0], m_[2], m_[6], m_[8]); + tmat2 minor5(m_[3], m_[5], m_[0], m_[2]); + tmat2 minor6(m_[3], m_[4], m_[6], m_[7]); + tmat2 minor7(m_[6], m_[7], m_[0], m_[1]); + tmat2 minor8(m_[0], m_[1], m_[3], m_[4]); + m_[0] = minor0.determinant() / d; + m_[1] = minor1.determinant() / d; + m_[2] = minor2.determinant() / d; + m_[3] = minor3.determinant() / d; + m_[4] = minor4.determinant() / d; + m_[5] = minor5.determinant() / d; + m_[6] = minor6.determinant() / d; + m_[7] = minor7.determinant() / d; + m_[8] = minor8.determinant() / d; + return *this; + } + + void print() const + { + static const int precision(6); + // row 0 + std::cout << "| "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[6]; + std::cout << " |" << std::endl; + // row 1 + std::cout << "| "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[4]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[7]; + std::cout << " |" << std::endl; + // row 2 + std::cout << "| "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[5]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[8]; + std::cout << " |" << std::endl; + } + + operator const T*() const { return &m_[0];} + + bool operator==(const tmat3& rhs) const + { + return m_[0] == rhs.m_[0] && + m_[1] == rhs.m_[1] && + m_[2] == rhs.m_[2] && + m_[3] == rhs.m_[3] && + m_[4] == rhs.m_[4] && + m_[5] == rhs.m_[5] && + m_[6] == rhs.m_[6] && + m_[7] == rhs.m_[7] && + m_[8] == rhs.m_[8]; + } + + bool operator!=(const tmat3& rhs) const + { + return !(*this == rhs); + } + + tmat3& operator=(const tmat3& rhs) + { + if (this != &rhs) + { + m_[0] = rhs.m_[0]; + m_[1] = rhs.m_[1]; + m_[2] = rhs.m_[2]; + m_[3] = rhs.m_[3]; + m_[4] = rhs.m_[4]; + m_[5] = rhs.m_[5]; + m_[6] = rhs.m_[6]; + m_[7] = rhs.m_[7]; + m_[8] = rhs.m_[8]; + } + return *this; + } + + tmat3& operator+=(const tmat3& rhs) + { + m_[0] += rhs.m_[0]; + m_[1] += rhs.m_[1]; + m_[2] += rhs.m_[2]; + m_[3] += rhs.m_[3]; + m_[4] += rhs.m_[4]; + m_[5] += rhs.m_[5]; + m_[6] += rhs.m_[6]; + m_[7] += rhs.m_[7]; + m_[8] += rhs.m_[8]; + return *this; + } + + const tmat3 operator+(const tmat3& rhs) + { + return tmat3(*this) += rhs; + } + + tmat3& operator-=(const tmat3& rhs) + { + m_[0] -= rhs.m_[0]; + m_[1] -= rhs.m_[1]; + m_[2] -= rhs.m_[2]; + m_[3] -= rhs.m_[3]; + m_[4] -= rhs.m_[4]; + m_[5] -= rhs.m_[5]; + m_[6] -= rhs.m_[6]; + m_[7] -= rhs.m_[7]; + m_[8] -= rhs.m_[8]; + return *this; + } + + const tmat3 operator-(const tmat3& rhs) + { + return tmat3(*this) -= rhs; + } + + tmat3& operator*=(const tmat3& rhs) + { + T c0r0((m_[0] * rhs.m_[0]) + (m_[3] * rhs.m_[1]) + (m_[6] * rhs.m_[2])); + T c0r1((m_[1] * rhs.m_[0]) + (m_[4] * rhs.m_[1]) + (m_[7] * rhs.m_[2])); + T c0r2((m_[2] * rhs.m_[0]) + (m_[5] * rhs.m_[1]) + (m_[8] * rhs.m_[2])); + T c1r0((m_[0] * rhs.m_[3]) + (m_[3] * rhs.m_[4]) + (m_[6] * rhs.m_[5])); + T c1r1((m_[1] * rhs.m_[3]) + (m_[4] * rhs.m_[4]) + (m_[7] * rhs.m_[5])); + T c1r2((m_[2] * rhs.m_[3]) + (m_[5] * rhs.m_[4]) + (m_[8] * rhs.m_[5])); + T c2r0((m_[0] * rhs.m_[6]) + (m_[3] * rhs.m_[7]) + (m_[6] * rhs.m_[8])); + T c2r1((m_[1] * rhs.m_[6]) + (m_[4] * rhs.m_[7]) + (m_[7] * rhs.m_[8])); + T c2r2((m_[2] * rhs.m_[6]) + (m_[5] * rhs.m_[7]) + (m_[8] * rhs.m_[8])); + m_[0] = c0r0; + m_[1] = c0r1; + m_[2] = c0r2; + m_[3] = c1r0; + m_[4] = c1r1; + m_[5] = c1r2; + m_[6] = c2r0; + m_[7] = c2r1; + m_[8] = c2r2; + return *this; + } + + const tmat3 operator*(const tmat3& rhs) + { + return tmat3(*this) *= rhs; + } + + tmat3& operator*=(const T& rhs) + { + m_[0] *= rhs; + m_[1] *= rhs; + m_[2] *= rhs; + m_[3] *= rhs; + m_[4] *= rhs; + m_[5] *= rhs; + m_[6] *= rhs; + m_[7] *= rhs; + m_[8] *= rhs; + return *this; + } + + const tmat3 operator*(const T& rhs) + { + return tmat3(*this) *= rhs; + } + + tmat3& operator/=(const T& rhs) + { + m_[0] /= rhs; + m_[1] /= rhs; + m_[2] /= rhs; + m_[3] /= rhs; + m_[4] /= rhs; + m_[5] /= rhs; + m_[6] /= rhs; + m_[7] /= rhs; + m_[8] /= rhs; + return *this; + } + + const tmat3 operator/(const T& rhs) + { + return tmat3(*this) /= rhs; + } + + ArrayProxy operator[](int index) + { + return ArrayProxy(&m_[index]); + } + const ArrayProxy operator[](int index) const + { + return ArrayProxy(const_cast(&m_[index])); + } + +private: + T m_[9]; +}; + +template +const tmat3 operator*(const T& lhs, const tmat3& rhs) +{ + return tmat3(rhs) * lhs; +} + +template +const tvec3 operator*(const tvec3& lhs, const tmat3& rhs) +{ + T x((lhs.x() * rhs[0][0]) + (lhs.y() * rhs[1][0]) + (lhs.z() * rhs[2][0])); + T y((lhs.x() * rhs[0][1]) + (lhs.y() * rhs[1][1]) + (lhs.z() * rhs[2][1])); + T z((lhs.x() * rhs[0][2]) + (lhs.y() * rhs[1][2]) + (lhs.z() * rhs[2][2])); + return tvec3(x, y, z); +} + +template +const tvec3 operator*(const tmat3& lhs, const tvec3& rhs) +{ + T x((lhs[0][0] * rhs.x()) + (lhs[0][1] * rhs.y()) + (lhs[0][2] * rhs.z())); + T y((lhs[1][0] * rhs.x()) + (lhs[1][1] * rhs.y()) + (lhs[1][2] * rhs.z())); + T z((lhs[2][0] * rhs.x()) + (lhs[2][1] * rhs.y()) + (lhs[2][2] * rhs.z())); + return tvec3(x, y, z); +} + +template +const tmat3 outer(const tvec3& a, const tvec3& b) +{ + tmat3 product; + product[0][0] = a.x() * b.x(); + product[0][1] = a.x() * b.y(); + product[0][2] = a.x() * b.z(); + product[1][0] = a.y() * b.x(); + product[1][1] = a.y() * b.y(); + product[1][2] = a.y() * b.z(); + product[2][0] = a.z() * b.x(); + product[2][1] = a.z() * b.y(); + product[2][2] = a.z() * b.z(); + return product; +} + +template +class tmat4 +{ +public: + tmat4() + { + setIdentity(); + } + tmat4(const tmat4& m) + { + m_[0] = m.m_[0]; + m_[1] = m.m_[1]; + m_[2] = m.m_[2]; + m_[3] = m.m_[3]; + m_[4] = m.m_[4]; + m_[5] = m.m_[5]; + m_[6] = m.m_[6]; + m_[7] = m.m_[7]; + m_[8] = m.m_[8]; + m_[9] = m.m_[9]; + m_[10] = m.m_[10]; + m_[11] = m.m_[11]; + m_[12] = m.m_[12]; + m_[13] = m.m_[13]; + m_[14] = m.m_[14]; + m_[15] = m.m_[15]; + } + ~tmat4() {} + + void setIdentity() + { + m_[0] = 1; + m_[1] = 0; + m_[2] = 0; + m_[3] = 0; + m_[4] = 0; + m_[5] = 1; + m_[6] = 0; + m_[7] = 0; + m_[8] = 0; + m_[9] = 0; + m_[10] = 1; + m_[11] = 0; + m_[12] = 0; + m_[13] = 0; + m_[14] = 0; + m_[15] = 1; + } + + tmat4& transpose() + { + T tmp_val = m_[1]; + m_[1] = m_[4]; + m_[4] = tmp_val; + tmp_val = m_[2]; + m_[2] = m_[8]; + m_[8] = tmp_val; + tmp_val = m_[3]; + m_[3] = m_[12]; + m_[12] = tmp_val; + tmp_val = m_[6]; + m_[6] = m_[9]; + m_[9] = tmp_val; + tmp_val = m_[7]; + m_[7] = m_[13]; + m_[13] = tmp_val; + tmp_val = m_[11]; + m_[11] = m_[14]; + m_[14] = tmp_val; + return *this; + } + + T determinant() + { + tmat3 minor0(m_[5], m_[6], m_[7], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]); + tmat3 minor4(m_[1], m_[2], m_[3], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]); + tmat3 minor8(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[13], m_[14], m_[15]); + tmat3 minor12(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[9], m_[10], m_[11]); + return (m_[0] * minor0.determinant()) - + (m_[4] * minor4.determinant()) + + (m_[8] * minor8.determinant()) - + (m_[12] * minor12.determinant()); + } + + tmat4& inverse() throw(std::runtime_error) + { + T d(determinant()); + if (d == static_cast(0)) + { + throw std::runtime_error("Matrix is noninvertible!!!!"); + } + tmat3 minor0(m_[5], m_[6], m_[7], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]); + tmat3 minor1(m_[1], m_[2], m_[3], m_[13], m_[14], m_[15], m_[9], m_[10], m_[11]); + tmat3 minor2(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[13], m_[14], m_[15]); + tmat3 minor3(m_[1], m_[2], m_[3], m_[9], m_[10], m_[11], m_[5], m_[6], m_[7]); + + tmat3 minor4(m_[4], m_[6], m_[7], m_[12], m_[14], m_[15], m_[8], m_[10], m_[11]); + tmat3 minor5(m_[0], m_[2], m_[3], m_[8], m_[10], m_[11], m_[12], m_[14], m_[15]); + tmat3 minor6(m_[0], m_[2], m_[3], m_[12], m_[14], m_[15], m_[4], m_[6], m_[7]); + tmat3 minor7(m_[0], m_[2], m_[3], m_[4], m_[6], m_[7], m_[8], m_[10], m_[11]); + + tmat3 minor8(m_[4], m_[5], m_[7], m_[8], m_[9], m_[11], m_[12], m_[13], m_[15]); + tmat3 minor9(m_[0], m_[1], m_[3], m_[12], m_[13], m_[15], m_[8], m_[9], m_[11]); + tmat3 minor10(m_[0], m_[1], m_[3], m_[4], m_[5], m_[7], m_[12], m_[13], m_[15]); + tmat3 minor11(m_[0], m_[1], m_[3], m_[8], m_[9], m_[11], m_[4], m_[5], m_[7]); + + tmat3 minor12(m_[4], m_[5], m_[6], m_[12], m_[13], m_[14], m_[8], m_[9], m_[10]); + tmat3 minor13(m_[0], m_[1], m_[2], m_[8], m_[9], m_[10], m_[12], m_[13], m_[14]); + tmat3 minor14(m_[0], m_[1], m_[2], m_[12], m_[13], m_[14], m_[4], m_[5], m_[6]); + tmat3 minor15(m_[0], m_[1], m_[2], m_[4], m_[5], m_[6], m_[8], m_[9], m_[10]); + m_[0] = minor0.determinant() / d; + m_[1] = minor1.determinant() / d; + m_[2] = minor2.determinant() / d; + m_[3] = minor3.determinant() / d; + m_[4] = minor4.determinant() / d; + m_[5] = minor5.determinant() / d; + m_[6] = minor6.determinant() / d; + m_[7] = minor7.determinant() / d; + m_[8] = minor8.determinant() / d; + m_[9] = minor9.determinant() / d; + m_[10] = minor10.determinant() / d; + m_[11] = minor11.determinant() / d; + m_[12] = minor12.determinant() / d; + m_[13] = minor13.determinant() / d; + m_[14] = minor14.determinant() / d; + m_[15] = minor15.determinant() / d; + return *this; + } + + void print() const + { + static const int precision(6); + // row 0 + std::cout << "| "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[4]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[8]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[12]; + std::cout << " |" << std::endl; + // row 1 + std::cout << "| "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[5]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[9]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[13]; + std::cout << " |" << std::endl; + // row 2 + std::cout << "| "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[6]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[10]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[14]; + std::cout << " |" << std::endl; + // row 3 + std::cout << "| "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[7]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[11]; + std::cout << " "; + std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[15]; + std::cout << " |" << std::endl; + } + + operator const T*() const { return &m_[0];} + + bool operator==(const tmat4& rhs) const + { + return m_[0] == rhs.m_[0] && + m_[1] == rhs.m_[1] && + m_[2] == rhs.m_[2] && + m_[3] == rhs.m_[3] && + m_[4] == rhs.m_[4] && + m_[5] == rhs.m_[5] && + m_[6] == rhs.m_[6] && + m_[7] == rhs.m_[7] && + m_[8] == rhs.m_[8] && + m_[9] == rhs.m_[9] && + m_[10] == rhs.m_[10] && + m_[11] == rhs.m_[11] && + m_[12] == rhs.m_[12] && + m_[13] == rhs.m_[13] && + m_[14] == rhs.m_[14] && + m_[15] == rhs.m_[15]; + } + + bool operator!=(const tmat4& rhs) const + { + return !(*this == rhs); + } + + tmat4& operator=(const tmat4& rhs) + { + if (this != &rhs) + { + m_[0] = rhs.m_[0]; + m_[1] = rhs.m_[1]; + m_[2] = rhs.m_[2]; + m_[3] = rhs.m_[3]; + m_[4] = rhs.m_[4]; + m_[5] = rhs.m_[5]; + m_[6] = rhs.m_[6]; + m_[7] = rhs.m_[7]; + m_[8] = rhs.m_[8]; + m_[9] = rhs.m_[9]; + m_[10] = rhs.m_[10]; + m_[11] = rhs.m_[11]; + m_[12] = rhs.m_[12]; + m_[13] = rhs.m_[13]; + m_[14] = rhs.m_[14]; + m_[15] = rhs.m_[15]; + } + return *this; + } + + tmat4& operator+=(const tmat4& rhs) + { + m_[0] += rhs.m_[0]; + m_[1] += rhs.m_[1]; + m_[2] += rhs.m_[2]; + m_[3] += rhs.m_[3]; + m_[4] += rhs.m_[4]; + m_[5] += rhs.m_[5]; + m_[6] += rhs.m_[6]; + m_[7] += rhs.m_[7]; + m_[8] += rhs.m_[8]; + m_[9] += rhs.m_[9]; + m_[10] += rhs.m_[10]; + m_[11] += rhs.m_[11]; + m_[12] += rhs.m_[12]; + m_[13] += rhs.m_[13]; + m_[14] += rhs.m_[14]; + m_[15] += rhs.m_[15]; + return *this; + } + + const tmat4 operator+(const tmat4& rhs) + { + return tmat4(*this) += rhs; + } + + tmat4& operator-=(const tmat4& rhs) + { + m_[0] -= rhs.m_[0]; + m_[1] -= rhs.m_[1]; + m_[2] -= rhs.m_[2]; + m_[3] -= rhs.m_[3]; + m_[4] -= rhs.m_[4]; + m_[5] -= rhs.m_[5]; + m_[6] -= rhs.m_[6]; + m_[7] -= rhs.m_[7]; + m_[8] -= rhs.m_[8]; + m_[9] -= rhs.m_[9]; + m_[10] -= rhs.m_[10]; + m_[11] -= rhs.m_[11]; + m_[12] -= rhs.m_[12]; + m_[13] -= rhs.m_[13]; + m_[14] -= rhs.m_[14]; + m_[15] -= rhs.m_[15]; + return *this; + } + + const tmat4 operator-(const tmat4& rhs) + { + return tmat4(*this) -= rhs; + } + + tmat4& operator*=(const tmat4& rhs) + { + T c0r0((m_[0] * rhs.m_[0]) + (m_[4] * rhs.m_[1]) + (m_[8] * rhs.m_[2]) + (m_[12] * rhs.m_[3])); + T c0r1((m_[1] * rhs.m_[0]) + (m_[5] * rhs.m_[1]) + (m_[9] * rhs.m_[2]) + (m_[13] * rhs.m_[3])); + T c0r2((m_[2] * rhs.m_[0]) + (m_[6] * rhs.m_[1]) + (m_[10] * rhs.m_[2]) + (m_[14] * rhs.m_[3])); + T c0r3((m_[3] * rhs.m_[0]) + (m_[7] * rhs.m_[1]) + (m_[11] * rhs.m_[2]) + (m_[15] * rhs.m_[3])); + T c1r0((m_[0] * rhs.m_[4]) + (m_[4] * rhs.m_[5]) + (m_[8] * rhs.m_[6]) + (m_[12] * rhs.m_[7])); + T c1r1((m_[1] * rhs.m_[4]) + (m_[5] * rhs.m_[5]) + (m_[9] * rhs.m_[6]) + (m_[13] * rhs.m_[7])); + T c1r2((m_[2] * rhs.m_[4]) + (m_[6] * rhs.m_[5]) + (m_[10] * rhs.m_[6]) + (m_[14] * rhs.m_[7])); + T c1r3((m_[3] * rhs.m_[4]) + (m_[7] * rhs.m_[5]) + (m_[11] * rhs.m_[6]) + (m_[15] * rhs.m_[7])); + T c2r0((m_[0] * rhs.m_[8]) + (m_[4] * rhs.m_[9]) + (m_[8] * rhs.m_[10]) + (m_[12] * rhs.m_[11])); + T c2r1((m_[1] * rhs.m_[8]) + (m_[5] * rhs.m_[9]) + (m_[9] * rhs.m_[10]) + (m_[13] * rhs.m_[11])); + T c2r2((m_[2] * rhs.m_[8]) + (m_[6] * rhs.m_[9]) + (m_[10] * rhs.m_[10]) + (m_[14] * rhs.m_[11])); + T c2r3((m_[3] * rhs.m_[8]) + (m_[7] * rhs.m_[9]) + (m_[11] * rhs.m_[10]) + (m_[15] * rhs.m_[11])); + T c3r0((m_[0] * rhs.m_[12]) + (m_[4] * rhs.m_[13]) + (m_[8] * rhs.m_[14]) + (m_[12] * rhs.m_[15])); + T c3r1((m_[1] * rhs.m_[12]) + (m_[5] * rhs.m_[13]) + (m_[9] * rhs.m_[14]) + (m_[13] * rhs.m_[15])); + T c3r2((m_[2] * rhs.m_[12]) + (m_[6] * rhs.m_[13]) + (m_[10] * rhs.m_[14]) + (m_[14] * rhs.m_[15])); + T c3r3((m_[3] * rhs.m_[12]) + (m_[7] * rhs.m_[13]) + (m_[11] * rhs.m_[14]) + (m_[15] * rhs.m_[15])); + m_[0] = c0r0; + m_[1] = c0r1; + m_[2] = c0r2; + m_[3] = c0r3; + m_[4] = c1r0; + m_[5] = c1r1; + m_[6] = c1r2; + m_[7] = c1r3; + m_[8] = c2r0; + m_[9] = c2r1; + m_[10] = c2r2; + m_[11] = c2r3; + m_[12] = c3r0; + m_[13] = c3r1; + m_[14] = c3r2; + m_[15] = c3r3; + return *this; + } + + const tmat4 operator*(const tmat4& rhs) + { + return tmat4(*this) *= rhs; + } + + tmat4& operator*=(const T& rhs) + { + m_[0] *= rhs; + m_[1] *= rhs; + m_[2] *= rhs; + m_[3] *= rhs; + m_[4] *= rhs; + m_[5] *= rhs; + m_[6] *= rhs; + m_[7] *= rhs; + m_[8] *= rhs; + m_[9] *= rhs; + m_[10] *= rhs; + m_[11] *= rhs; + m_[12] *= rhs; + m_[13] *= rhs; + m_[14] *= rhs; + m_[15] *= rhs; + return *this; + } + + const tmat4 operator*(const T& rhs) + { + return tmat4(*this) *= rhs; + } + + tmat4& operator/=(const T& rhs) + { + m_[0] /= rhs; + m_[1] /= rhs; + m_[2] /= rhs; + m_[3] /= rhs; + m_[4] /= rhs; + m_[5] /= rhs; + m_[6] /= rhs; + m_[7] /= rhs; + m_[8] /= rhs; + m_[9] /= rhs; + m_[10] /= rhs; + m_[11] /= rhs; + m_[12] /= rhs; + m_[13] /= rhs; + m_[14] /= rhs; + m_[15] /= rhs; + return *this; + } + + const tmat4 operator/(const T& rhs) + { + return tmat4(*this) /= rhs; + } + + ArrayProxy operator[](int index) + { + return ArrayProxy(&m_[index]); + } + const ArrayProxy operator[](int index) const + { + return ArrayProxy(const_cast(&m_[index])); + } + +private: + T m_[16]; +}; + +template +const tmat4 operator*(const T& lhs, const tmat4& rhs) +{ + return tmat4(rhs) * lhs; +} + +template +const tvec4 operator*(const tvec4& lhs, const tmat4& rhs) +{ + T x((lhs.x() * rhs[0][0]) + (lhs.y() * rhs[1][0]) + (lhs.z() * rhs[2][0]) + (lhs.w() * rhs[3][0])); + T y((lhs.x() * rhs[0][1]) + (lhs.y() * rhs[1][1]) + (lhs.z() * rhs[2][1]) + (lhs.w() * rhs[3][1])); + T z((lhs.x() * rhs[0][2]) + (lhs.y() * rhs[1][2]) + (lhs.z() * rhs[2][2]) + (lhs.w() * rhs[3][2])); + T w((lhs.x() * rhs[0][3]) + (lhs.y() * rhs[1][3]) + (lhs.z() * rhs[2][3]) + (lhs.w() * rhs[3][3])); + return tvec4(x, y, z, w); +} + +template +const tvec4 operator*(const tmat4& lhs, const tvec4& rhs) +{ + T x((lhs[0][0] * rhs.x()) + (lhs[0][1] * rhs.y()) + (lhs[0][2] * rhs.z()) + (lhs[0][3] * rhs.w())); + T y((lhs[1][0] * rhs.x()) + (lhs[1][1] * rhs.y()) + (lhs[1][2] * rhs.z()) + (lhs[1][3] * rhs.w())); + T z((lhs[2][0] * rhs.x()) + (lhs[2][1] * rhs.y()) + (lhs[2][2] * rhs.z()) + (lhs[2][3] * rhs.w())); + T w((lhs[3][0] * rhs.x()) + (lhs[3][1] * rhs.y()) + (lhs[3][2] * rhs.z()) + (lhs[3][3] * rhs.w())); + return tvec4(x, y, z, w); +} + +template +const tmat4 outer(const tvec4& a, const tvec4& b) +{ + tmat4 product; + product[0][0] = a.x() * b.x(); + product[0][1] = a.x() * b.y(); + product[0][2] = a.x() * b.z(); + product[0][3] = a.x() * b.w(); + product[1][0] = a.y() * b.x(); + product[1][1] = a.y() * b.y(); + product[1][2] = a.y() * b.z(); + product[1][3] = a.y() * b.w(); + product[2][0] = a.z() * b.x(); + product[2][1] = a.z() * b.y(); + product[2][2] = a.z() * b.z(); + product[2][3] = a.z() * b.w(); + product[3][0] = a.w() * b.x(); + product[3][1] = a.w() * b.y(); + product[3][2] = a.w() * b.z(); + product[3][3] = a.w() * b.w(); + return product; +} + +// +// Convenience typedefs. These are here to present a homogeneous view of these +// objects with respect to shader source. +// +typedef tmat2 mat2; +typedef tmat3 mat3; +typedef tmat4 mat4; + +typedef tmat2 dmat2; +typedef tmat3 dmat3; +typedef tmat4 dmat4; + +typedef tmat2 imat2; +typedef tmat3 imat3; +typedef tmat4 imat4; + +typedef tmat2 umat2; +typedef tmat3 umat3; +typedef tmat4 umat4; + +typedef tmat2 bmat2; +typedef tmat3 bmat3; +typedef tmat4 bmat4; + +namespace Mat4 +{ + +// +// Some functions to generate transformation matrices that used to be provided +// by OpenGL. +// +mat4 translate(float x, float y, float z); +mat4 scale(float x, float y, float z); +mat4 rotate(float angle, float x, float y, float z); +mat4 frustum(float left, float right, float bottom, float top, float near, float far); +mat4 ortho(float left, float right, float bottom, float top, float near, float far); +mat4 perspective(float fovy, float aspect, float zNear, float zFar); +mat4 lookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ); + +} // namespace Mat4 +} // namespace LibMatrix +#endif // MAT_H_ === added file 'src/libmatrix/matrix_inverse_test.cc' --- src/libmatrix/matrix_inverse_test.cc 1970-01-01 00:00:00 +0000 +++ src/libmatrix/matrix_inverse_test.cc 2011-06-17 07:54:50 +0000 @@ -0,0 +1,152 @@ +// +// Copyright (c) 2010 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#include +#include "mat.h" + +using LibMatrix::mat4; +using LibMatrix::mat3; +using LibMatrix::mat2; +using std::cerr; +using std::cout; +using std::endl; + +bool mat2OK() +{ + mat2 m; + cout << "Starting with mat2 (should be identity): " << endl << endl; + m.print(); + + m[0][1] = -2.5; + + cout << endl << "Matrix should now have (0, 1) == -2.500000" << endl << endl; + m.print(); + + mat2 mi(m); + + cout << endl << "Copy of previous matrix (should have (0, 1) == -2.500000)" << endl << endl; + mi.print(); + + mi.inverse(); + + cout << endl << "Inverse of copy: " << endl << endl; + mi.print(); + + mat2 i = m * mi; + + cout << endl << "Product of original and inverse (should be identity): " << endl << endl; + i.print(); + + mat2 ident; + if (i != ident) + { + return false; + } + + return true; +} + +bool mat3OK() +{ + mat3 m; + cout << "Starting with mat3 (should be identity): " << endl << endl; + m.print(); + + m[1][2] = -2.5; + + cout << endl << "Matrix should now have (1, 2) == -2.500000" << endl << endl; + m.print(); + + mat3 mi(m); + + cout << endl << "Copy of previous matrix (should have (1, 2) == -2.500000)" << endl << endl; + mi.print(); + + mi.inverse(); + + cout << endl << "Inverse of copy: " << endl << endl; + mi.print(); + + mat3 i = m * mi; + + cout << endl << "Product of original and inverse (should be identity): " << endl << endl; + i.print(); + + mat3 ident; + if (i != ident) + { + return false; + } + + return true; +} + +bool mat4OK() +{ + mat4 m; + cout << "Starting with mat4 (should be identity): " << endl << endl; + m.print(); + + m[2][3] = -2.5; + + cout << endl << "Matrix should now have (2, 3) == -2.500000" << endl << endl; + m.print(); + + mat4 mi(m); + + cout << endl << "Copy of previous matrix (should have (2, 3) == -2.500000)" << endl << endl; + mi.print(); + + mi.inverse(); + + cout << endl << "Inverse of copy: " << endl << endl; + mi.print(); + + mat4 i = m * mi; + + cout << endl << "Product of original and inverse (should be identity): " << endl << endl; + i.print(); + + mat4 ident; + if (i != ident) + { + return false; + } + + return true; +} + +int +main(int argc, char** argv) +{ + if (!mat2OK()) + { + cerr << "mat2::inverse() does not work!" << endl; + return 1; + } + cout << "mat2::inverse() is okay!" << endl << endl; + + if (!mat3OK()) + { + cerr << "mat3::inverse() does not work!" << endl; + return 1; + } + cout << "mat3::inverse() is okay!" << endl << endl; + + if (!mat4OK()) + { + cerr << "mat4::inverse() does not work!" << endl; + return 1; + } + cout << "mat4::inverse() is okay!" << endl << endl; + + return 0; +} === added file 'src/libmatrix/program.cc' --- src/libmatrix/program.cc 1970-01-01 00:00:00 +0000 +++ src/libmatrix/program.cc 2011-06-17 13:09:21 +0000 @@ -0,0 +1,363 @@ +// +// Copyright (c) 2011 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#include +#include +#include +#include +#include + +#include "oglsdl.h" +#include "program.h" + +using std::string; +using LibMatrix::mat4; +using LibMatrix::vec2; +using LibMatrix::vec3; +using LibMatrix::vec4; + +bool +gotSource(const string& filename, string& source) +{ + using std::ifstream; + ifstream inputFile(filename.c_str()); + if (!inputFile) + { + std::cerr << "Failed to open \"" << filename << "\"" << std::endl; + return false; + } + + string curLine; + while (getline(inputFile, curLine)) + { + source += curLine; + source += '\n'; + } + + return true; +} + +Shader::Shader(unsigned int type, const string& source) : + handle_(0), + type_(type), + source_(source), + ready_(false), + valid_(false) +{ + // Create our shader and setup the source code. + handle_ = glCreateShader(type); + if (!handle_) + { + message_ = string("Failed to create the new shader."); + return; + } + const GLchar* shaderSource = source_.c_str(); + glShaderSource(handle_, 1, &shaderSource, NULL); + GLint param = 0; + glGetShaderiv(handle_, GL_SHADER_SOURCE_LENGTH, ¶m); + if (static_cast(param) != source_.length() + 1) + { + std::ostringstream o(string("Expected shader source length ")); + o << source_.length() << ", but got " << param << std::endl; + message_ = o.str(); + return; + } + valid_ = true; +} + +Shader::~Shader() +{ + handle_ = 0; + type_ = 0; + ready_ = false; + valid_ = false; +} + +void +Shader::compile() +{ + // Make sure we have a good shader and haven't already compiled it. + if (!valid_ || ready_) + { + return; + } + glCompileShader(handle_); + GLint param = 0; + glGetShaderiv(handle_, GL_COMPILE_STATUS, ¶m); + if (param == GL_FALSE) + { + glGetShaderiv(handle_, GL_INFO_LOG_LENGTH, ¶m); + GLchar* infoLog = new GLchar[param + 1]; + glGetShaderInfoLog(handle_, param + 1, NULL, infoLog); + message_ = infoLog; + delete [] infoLog; + return; + } + ready_ = true; +} + +void +Shader::attach(unsigned int program) +{ + // Shader must be valid and compiled to be attached to a program. + if (!valid_ || !ready_) + { + return; + } + glAttachShader(program, handle_); +} + +void +Shader::release() +{ + if (handle_) + { + glDeleteShader(handle_); + } + handle_ = 0; + type_ = 0; + ready_ = false; + valid_ = false; +} + +Program::Program() : + handle_(0), + ready_(false), + valid_(false) +{ +} + +Program::~Program() +{ + // First release all of the shader resources attached to us and clean up + // our handle. + release(); +} + +void +Program::init() +{ + handle_ = glCreateProgram(); + if (!handle_) + { + message_ = string("Failed to create the new program"); + return; + } + + valid_ = true; +} + +void +Program::release() +{ + // First delete all of the shader resources attached to us. + for (std::vector::iterator shaderIt = shaders_.begin(); shaderIt != shaders_.end(); shaderIt++) + { + shaderIt->release(); + } + + // Clear out the shader vector so we're ready to reuse it. + shaders_.clear(); + + // Clear out the error string to make sure we don't return anything stale. + message_.clear(); + + if (handle_) + { + glDeleteProgram(handle_); + } + handle_ = 0; + ready_ = false; + valid_ = false; +} +void +Program::addShader(unsigned int type, const string& source) +{ + if (!valid_) + { + return; + } + + Shader shader(type, source); + if (!shader.valid()) + { + message_ = shader.errorMessage(); + valid_ = false; + return; + } + + shader.compile(); + + if (!shader.ready()) + { + message_ = shader.errorMessage(); + valid_ = false; + return; + } + + shader.attach(handle_); + shaders_.push_back(shader); + return; +} + +void +Program::build() +{ + if (!valid_ || ready_) + { + return; + } + + if (shaders_.empty()) + { + message_ = string("There are no shaders attached to this program"); + return; + } + + glLinkProgram(handle_); + GLint param = 1; + glGetProgramiv(handle_, GL_LINK_STATUS, ¶m); + if (param == GL_FALSE) + { + glGetProgramiv(handle_, GL_INFO_LOG_LENGTH, ¶m); + GLchar* infoLog = new GLchar[param + 1]; + glGetProgramInfoLog(handle_, param + 1, NULL, infoLog); + message_ = infoLog; + delete [] infoLog; + return; + } + ready_ = true; +} + +void +Program::start() +{ + if (!valid_ || !ready_) + { + return; + } + glUseProgram(handle_); +} + +void +Program::stop() +{ + glUseProgram(0); +} + +void +Program::loadUniformMatrix(const mat4& m, const string& name) +{ + ready_ = false; + GLint location = glGetUniformLocation(handle_, name.c_str()); + if (location < 0) + { + message_ = string("Failed to get uniform location for \"") + name + + string("\""); + return; + } + + // Our matrix representation is column-major, so transpose is false here. + glUniformMatrix4fv(location, 1, GL_FALSE, m); + ready_ = true; +} + +void +Program::loadUniformVector(const vec2& v, const string& name) +{ + ready_ = false; + GLint location = glGetUniformLocation(handle_, name.c_str()); + if (location < 0) + { + message_ = string("Failed to get uniform location for \"") + name + + string("\""); + return; + } + + glUniform2fv(location, 1, v); + ready_ = true; +} + +void +Program::loadUniformVector(const vec3& v, const string& name) +{ + ready_ = false; + GLint location = glGetUniformLocation(handle_, name.c_str()); + if (location < 0) + { + message_ = string("Failed to get uniform location for \"") + name + + string("\""); + return; + } + + glUniform3fv(location, 1, v); + ready_ = true; +} + +void +Program::loadUniformVector(const vec4& v, const string& name) +{ + ready_ = false; + GLint location = glGetUniformLocation(handle_, name.c_str()); + if (location < 0) + { + message_ = string("Failed to get uniform location for \"") + name + + string("\""); + return; + } + + glUniform4fv(location, 1, v); + ready_ = true; +} + +void +Program::loadUniformScalar(const float& f, const string& name) +{ + ready_ = false; + GLint location = glGetUniformLocation(handle_, name.c_str()); + if (location < 0) + { + message_ = string("Failed to get uniform location for \"") + name + + string("\""); + return; + } + + glUniform1f(location, f); + ready_ = true; +} + +void +Program::loadUniformScalar(const int& i, const string& name) +{ + ready_ = false; + GLint location = glGetUniformLocation(handle_, name.c_str()); + if (location < 0) + { + message_ = string("Failed to get uniform location for \"") + name + + string("\""); + return; + } + + glUniform1i(location, i); + ready_ = true; +} + +int +Program::getAttribIndex(const string& name) +{ + GLint index = glGetAttribLocation(handle_, name.c_str()); + if (index < 0) + { + message_ = string("Failed to get attribute location for \"") + name + + string("\""); + } + return index; +} === added file 'src/libmatrix/program.h' --- src/libmatrix/program.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/program.h 2011-06-17 07:54:50 +0000 @@ -0,0 +1,151 @@ +// +// Copyright (c) 2011 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#ifndef PROGRAM_H_ +#define PROGRAM_H_ + +#include +#include +#include "mat.h" + +// Simple shader container. Abstracts all of the OpenGL bits, but leaves +// much of the semantics intact. This is typically only referenced directly +// by the program object. +class Shader +{ +public: + Shader() : + handle_(0), + type_(0), + ready_(false), + valid_(false) {} + Shader(const Shader& shader) : + handle_(shader.handle_), + type_(shader.type_), + source_(shader.source_), + message_(shader.message_), + ready_(shader.ready_), + valid_(shader.valid_) {} + Shader(unsigned int type, const std::string& source); + ~Shader(); + + // Compiles the shader source so that it can be linked into a + // program. + // + // Make sure the shader is "valid" before calling this one. + void compile(); + + // Attaches a compiled shader to a program in preparation for + // linking. + // + // Make sure the shader is "ready" before calling this one. + void attach(unsigned int program); + + // Release any resources associated with this shader back to + // OpenGL + void release(); + + // If "valid" then the shader has successfully been created. + // If "ready" then the shader has successfully been compiled. + // If either is false, then additional information can be obtained + // from the error message. + bool valid() const { return valid_; } + bool ready() const { return ready_; } + const std::string& errorMessage() const { return message_; } + +private: + unsigned int handle_; + unsigned int type_; + std::string source_; + std::string message_; + bool ready_; + bool valid_; +}; + +// Simple program container. Abstracts all of the OpenGL bits, but leaves +// much of the semantics intact. +class Program +{ +public: + Program(); + ~Program(); + + // Initialize the program object for use. + void init(); + + // Release any resources associated with this program back to + // OpenGL + void release(); + + // Create a new shader of the given type and source, compile it and + // attach it to the program. + // + // Make sure the program is "valid" before calling this one. + void addShader(unsigned int type, const std::string& source); + + // Link all of the attached shaders into a runnable program for use + // in a rendering operation. + // + // Make sure the program is "valid" and that at least one shader + // has been successfully added before calling this one. + void build(); + + // Bind the program for use by the rendering context (i.e. actually + // run it). + // + // Make sure the program is "ready" before calling this one. + void start(); + + // Unbind the program from use by the rendering context (i.e. stop + // using it). + void stop(); + + // These members cause data to be bound to program variables, so + // the program must be bound for use for these to be effective. + // + // Load a matrix into the named uniform variable in the program. + void loadUniformMatrix(const LibMatrix::mat4& m, const std::string& name); + // Load a vector into the named uniform variable in the program. + void loadUniformVector(const LibMatrix::vec2& v, const std::string& name); + // Load a vector into the named uniform variable in the program. + void loadUniformVector(const LibMatrix::vec3& v, const std::string& name); + // Load a vector into the named uniform variable in the program. + void loadUniformVector(const LibMatrix::vec4& v, const std::string& name); + // Load a scalar into the named uniform variable in the program. + void loadUniformScalar(const float& f, const std::string& name); + // Load a scalar into the named uniform variable in the program. + void loadUniformScalar(const int& i, const std::string& name); + + // Get the handle to a named program input (the location in OpenGL + // vernacular). Typically used in conjunction with various VertexAttrib + // interfaces. + int getAttribIndex(const std::string& name); + + // If "valid" then the program has successfully been created. + // If "ready" then the program has successfully been built. + // If either is false, then additional information can be obtained + // from the error message. + bool valid() const { return valid_; } + bool ready() const { return ready_; } + const std::string& errorMessage() const { return message_; } + +private: + unsigned int handle_; + std::vector shaders_; + std::string message_; + bool ready_; + bool valid_; +}; + +// Handy utility for extracting shader source from a named file +bool gotSource(const std::string& filename, std::string& sourceOut); + +#endif // PROGRAM_H_ === added file 'src/libmatrix/stack.h' --- src/libmatrix/stack.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/stack.h 2011-06-17 07:54:50 +0000 @@ -0,0 +1,106 @@ +// +// Copyright (c) 2010 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#ifndef STACK_H_ +#define STACK_H_ + +#include +#include "mat.h" + +namespace LibMatrix +{ +// +// Simple matrix stack implementation suitable for tracking OpenGL matrix +// state. Default construction puts an identity matrix on the top of the +// stack. +// +template +class MatrixStack +{ +public: + MatrixStack() + { + theStack_.push_back(T()); + } + MatrixStack(const T& matrix) + { + theStack_.push_back(matrix); + } + ~MatrixStack() {} + + const T& getCurrent() const { return theStack_.back(); } + + void push() + { + theStack_.push_back(theStack_.back()); + } + void pop() + { + theStack_.pop_back(); + } + void loadIdentity() + { + theStack_.back().setIdentity(); + } + T& operator*=(const T& rhs) + { + T& curMatrix = theStack_.back(); + curMatrix *= rhs; + return curMatrix; + } + void print() const + { + const T& curMatrix = theStack_.back(); + curMatrix.print(); + } + unsigned int getDepth() const { return theStack_.size(); } +private: + std::vector theStack_; +}; + +class Stack4 : public MatrixStack +{ +public: + void translate(float x, float y, float z) + { + *this *= Mat4::translate(x, y, z); + } + void scale(float x, float y, float z) + { + *this *= Mat4::scale(x, y, z); + } + void rotate(float angle, float x, float y, float z) + { + *this *= Mat4::rotate(angle, x, y, z); + } + void frustum(float left, float right, float bottom, float top, float near, float far) + { + *this *= Mat4::frustum(left, right, bottom, top, near, far); + } + void ortho(float left, float right, float bottom, float top, float near, float far) + { + *this *= Mat4::ortho(left, right, bottom, top, near, far); + } + void perspective(float fovy, float aspect, float zNear, float zFar) + { + *this *= Mat4::perspective(fovy, aspect, zNear, zFar); + } + void lookAt(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ) + { + *this *= Mat4::lookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ); + } +}; + +} // namespace LibMatrix + +#endif // STACK_H_ === added file 'src/libmatrix/vec.h' --- src/libmatrix/vec.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/vec.h 2011-06-17 07:54:50 +0000 @@ -0,0 +1,500 @@ +// +// Copyright (c) 2010 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#ifndef VEC_H_ +#define VEC_H_ + +#include // only needed for print() functions... +#include + +namespace LibMatrix +{ +template +class tvec2 +{ +public: + tvec2() : + x_(0), + y_(0) {} + tvec2(T t) : + x_(t), + y_(t) {} + tvec2(T x, T y) : + x_(x), + y_(y) {} + tvec2(const tvec2& v) : + x_(v.x_), + y_(v.y_) {} + ~tvec2() {} + + void print() const + { + std::cout << "| " << x_ << " " << y_ << " |" << std::endl; + } + operator const T*() const { return &x_;} + + const T x() const { return x_; } + const T y() const { return y_; } + + void x(const T& val) { x_ = val; } + void y(const T& val) { y_ = val; } + + tvec2& operator=(const tvec2& rhs) + { + if (this != &rhs) + { + x_ = rhs.x_; + y_ = rhs.y_; + } + return *this; + } + + tvec2& operator/=(const T& rhs) + { + x_ /= rhs; + y_ /= rhs; + return *this; + } + + const tvec2 operator/(const T& rhs) + { + return tvec2(*this) /= rhs; + } + + tvec2& operator*=(const T& rhs) + { + x_ *= rhs; + y_ *= rhs; + return *this; + } + + const tvec2 operator*(const T& rhs) + { + return tvec2(*this) *= rhs; + } + + tvec2& operator+=(const T& rhs) + { + x_ += rhs; + y_ += rhs; + return *this; + } + + const tvec2 operator+(const T& rhs) + { + return tvec2(*this) += rhs; + } + + tvec2& operator+=(const tvec2& rhs) + { + x_ += rhs.x_; + y_ += rhs.y_; + return *this; + } + + const tvec2 operator+(const tvec2& rhs) + { + return tvec2(*this) += rhs; + } + + tvec2& operator-=(const T& rhs) + { + x_ -= rhs; + y_ -= rhs; + return *this; + } + + const tvec2 operator-(const T& rhs) + { + return tvec2(*this) -= rhs; + } + + tvec2& operator-=(const tvec2& rhs) + { + x_ -= rhs.x_; + y_ -= rhs.y_; + return *this; + } + + const tvec2 operator-(const tvec2& rhs) + { + return tvec2(*this) -= rhs; + } + + float length() const + { + return sqrt(dot(*this, *this)); + } + + void normalize() + { + float l = length(); + x_ /= l; + y_ /= l; + } + + static T dot(const tvec2& v1, const tvec2& v2) + { + return (v1.x_ * v2.x_) + (v1.y_ * v2.y_); + } + +private: + T x_; + T y_; +}; + +template +class tvec3 +{ +public: + tvec3() : + x_(0), + y_(0), + z_(0) {} + tvec3(T t) : + x_(t), + y_(t), + z_(t) {} + tvec3(T x, T y, T z) : + x_(x), + y_(y), + z_(z) {} + tvec3(const tvec3& v) : + x_(v.x_), + y_(v.y_), + z_(v.z_) {} + ~tvec3() {} + + void print() const + { + std::cout << "| " << x_ << " " << y_ << " " << z_ << " |" << std::endl; + } + operator const T*() const { return &x_;} + + const T x() const { return x_; } + const T y() const { return y_; } + const T z() const { return z_; } + + void x(const T& val) { x_ = val; } + void y(const T& val) { y_ = val; } + void z(const T& val) { z_ = val; } + + tvec3& operator=(const tvec3& rhs) + { + if (this != &rhs) + { + x_ = rhs.x_; + y_ = rhs.y_; + z_ = rhs.z_; + } + return *this; + } + + tvec3& operator/=(const T& rhs) + { + x_ /= rhs; + y_ /= rhs; + z_ /= rhs; + return *this; + } + + const tvec3 operator/(const T& rhs) + { + return tvec3(*this) /= rhs; + } + + tvec3& operator*=(const T& rhs) + { + x_ *= rhs; + y_ *= rhs; + z_ *= rhs; + return *this; + } + + const tvec3 operator*(const T& rhs) + { + return tvec3(*this) *= rhs; + } + + tvec3& operator+=(const T& rhs) + { + x_ += rhs; + y_ += rhs; + z_ += rhs; + return *this; + } + + const tvec3 operator+(const T& rhs) + { + return tvec3(*this) += rhs; + } + + tvec3& operator+=(const tvec3& rhs) + { + x_ += rhs.x_; + y_ += rhs.y_; + z_ += rhs.z_; + return *this; + } + + const tvec3 operator+(const tvec3& rhs) + { + return tvec3(*this) += rhs; + } + + tvec3& operator-=(const T& rhs) + { + x_ -= rhs; + y_ -= rhs; + z_ -= rhs; + return *this; + } + + const tvec3 operator-(const T& rhs) + { + return tvec3(*this) -= rhs; + } + + tvec3& operator-=(const tvec3& rhs) + { + x_ -= rhs.x_; + y_ -= rhs.y_; + z_ -= rhs.z_; + return *this; + } + + const tvec3 operator-(const tvec3& rhs) + { + return tvec3(*this) -= rhs; + } + + float length() const + { + return sqrt(dot(*this, *this)); + } + + void normalize() + { + float l = length(); + x_ /= l; + y_ /= l; + z_ /= l; + } + + static T dot(const tvec3& v1, const tvec3& v2) + { + return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_); + } + + static tvec3 cross(const tvec3& u, const tvec3& v) + { + return tvec3((u.y_ * v.z_) - (u.z_ * v.y_), + (u.z_ * v.x_) - (u.x_ * v.z_), + (u.x_ * v.y_) - (u.y_ * v.x_)); + } + +private: + T x_; + T y_; + T z_; +}; + +template +class tvec4 +{ +public: + tvec4() : + x_(0), + y_(0), + z_(0), + w_(0) {} + tvec4(T t) : + x_(t), + y_(t), + z_(t), + w_(t) {} + tvec4(T x, T y, T z, T w) : + x_(x), + y_(y), + z_(z), + w_(w) {} + tvec4(const tvec4& v) : + x_(v.x_), + y_(v.y_), + z_(v.z_), + w_(v.w_) {} + ~tvec4() {} + + void print() const + { + std::cout << "| " << x_ << " " << y_ << " " << z_ << " " << w_ << " |" << std::endl; + } + operator const T*() const { return &x_;} + + const T x() const { return x_; } + const T y() const { return y_; } + const T z() const { return z_; } + const T w() const { return w_; } + + void x(const T& val) { x_ = val; } + void y(const T& val) { y_ = val; } + void z(const T& val) { z_ = val; } + void w(const T& val) { w_ = val; } + + tvec4& operator=(const tvec4& rhs) + { + if (this != &rhs) + { + x_ = rhs.x_; + y_ = rhs.y_; + z_ = rhs.z_; + w_ = rhs.w_; + } + return *this; + } + + tvec4& operator/=(const T& rhs) + { + x_ /= rhs; + y_ /= rhs; + z_ /= rhs; + w_ /= rhs; + return *this; + } + + const tvec4 operator/(const T& rhs) + { + return tvec4(*this) /= rhs; + } + + tvec4& operator*=(const T& rhs) + { + x_ *= rhs; + y_ *= rhs; + z_ *= rhs; + w_ *= rhs; + return *this; + } + + const tvec4 operator*(const T& rhs) + { + return tvec4(*this) *= rhs; + } + + tvec4& operator+=(const T& rhs) + { + x_ += rhs; + y_ += rhs; + z_ += rhs; + w_ += rhs; + return *this; + } + + const tvec4 operator+(const T& rhs) + { + return tvec4(*this) += rhs; + } + + tvec4& operator+=(const tvec4& rhs) + { + x_ += rhs.x_; + y_ += rhs.y_; + z_ += rhs.z_; + w_ += rhs.w_; + return *this; + } + + const tvec4 operator+(const tvec4& rhs) + { + return tvec4(*this) += rhs; + } + + tvec4& operator-=(const T& rhs) + { + x_ -= rhs; + y_ -= rhs; + z_ -= rhs; + w_ -= rhs; + return *this; + } + + const tvec4 operator-(const T& rhs) + { + return tvec4(*this) -= rhs; + } + + tvec4& operator-=(const tvec4& rhs) + { + x_ -= rhs.x_; + y_ -= rhs.y_; + z_ -= rhs.z_; + w_ -= rhs.w_; + return *this; + } + + const tvec4 operator-(const tvec4& rhs) + { + return tvec4(*this) -= rhs; + } + + float length() const + { + return sqrt(dot(*this, *this)); + } + + void normalize() + { + float l = length(); + x_ /= l; + y_ /= l; + z_ /= l; + w_ /= l; + } + + static T dot(const tvec4& v1, const tvec4& v2) + { + return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_) + (v1.w_ * v2.w_); + } + +private: + T x_; + T y_; + T z_; + T w_; +}; + +// +// Convenience typedefs. These are here to present a homogeneous view of these +// objects with respect to shader source. +// +typedef tvec2 vec2; +typedef tvec3 vec3; +typedef tvec4 vec4; + +typedef tvec2 dvec2; +typedef tvec3 dvec3; +typedef tvec4 dvec4; + +typedef tvec2 ivec2; +typedef tvec3 ivec3; +typedef tvec4 ivec4; + +typedef tvec2 uvec2; +typedef tvec3 uvec3; +typedef tvec4 uvec4; + +typedef tvec2 bvec2; +typedef tvec3 bvec3; +typedef tvec4 bvec4; + +} // namespace LibMatrix + +#endif // VEC_H_ === removed file 'src/matrix.cpp' --- src/matrix.cpp 2011-01-25 15:00:12 +0000 +++ src/matrix.cpp 1970-01-01 00:00:00 +0000 @@ -1,265 +0,0 @@ -/* - * Copyright © 2010-2011 Linaro Limited - * - * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. - * - * glmark2 is free software: you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later - * version. - * - * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * glmark2. If not, see . - * - * Authors: - * Alexandros Frantzis (glmark2) - */ -#include "matrix.h" - -/** - * Multiply arrays representing 4x4 matrices in column-major order. - * - * The result is stored in the first matrix. - * - * @param m the first matrix - * @param n the second matrix - */ -static void multiply(GLfloat *m, const GLfloat *n) -{ - GLfloat tmp[16]; - const GLfloat *row, *column; - div_t d; - int i, j; - - for (i = 0; i < 16; i++) { - tmp[i] = 0; - d = div(i, 4); - row = n + d.quot * 4; - column = m + d.rem; - for (j = 0; j < 4; j++) - tmp[i] += row[j] * column[j * 4]; - } - memcpy(m, &tmp, sizeof tmp); -} - -/** - * Multiply this matrix with another. - * - * @param pM the matrix to multiply with. - * - * @return reference to this matrix (multiplied) - */ -Matrix4f &Matrix4f::operator*=(const Matrix4f &pM) -{ - multiply(m, pM.m); - - return *this; -} - -/** - * Rotates a matrix. - * - * @param angle the angle to rotate - * @param x the x component of the rotation axis - * @param y the y component of the rotation axis - * @param z the z component of the rotation axis - * - * @return reference to the matrix - */ -Matrix4f &Matrix4f::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) -{ - double s, c; - - sincos(angle, &s, &c); - - GLfloat r[16] = { - x * x * (1 - c) + c, y * x * (1 - c) + z * s, x * z * (1 - c) - y * s, 0, - x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0, - x * z * (1 - c) + y * s, y * z * (1 - c) - x * s, z * z * (1 - c) + c, 0, - 0, 0, 0, 1 - }; - - multiply(m, r); - - return *this; -} - -/** - * Translates a matrix. - * - * @param x the x component of the translation - * @param y the y component of the translation - * @param z the z component of the translation - * - * @return reference to the matrix - */ -Matrix4f &Matrix4f::translate(GLfloat x, GLfloat y, GLfloat z) -{ - GLfloat t[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 }; - - multiply(m, t); - - return *this; -} - -/** - * Transposes a matrix. - * - * @return reference to the matrix - */ -Matrix4f &Matrix4f::transpose() -{ - GLfloat t[16] = { - m[0], m[4], m[8], m[12], - m[1], m[5], m[9], m[13], - m[2], m[6], m[10], m[14], - m[3], m[7], m[11], m[15]}; - - memcpy(m, t, sizeof(m)); - - return *this; -} - -/** - * Makes this matrix an identity matrix. - * - * @return reference to the matrix - */ -Matrix4f &Matrix4f::identity() -{ - m[0] = 1.0; m[4] = 0.0; m[8] = 0.0; m[12] = 0.0; - m[1] = 0.0; m[5] = 1.0; m[9] = 0.0; m[13] = 0.0; - m[2] = 0.0; m[6] = 0.0; m[10] = 1.0; m[14] = 0.0; - m[3] = 0.0; m[7] = 0.0; m[11] = 0.0; m[15] = 1.0; - - return *this; -} - -/** - * Makes this matrix a perspective projection matrix. - * - * @param fovy field of view angle in degrees in the y direction - * @param aspect aspect ratio of view - * @param zNear the distance from the viewer to the near clipping plane - * @param zFar the distance from the viewer to the far clipping plane - * - * @return reference to the matrix - */ -Matrix4f &Matrix4f::perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) -{ - GLfloat sine, cotangent, deltaZ; - GLfloat radians = fovy / 2 * M_PI / 180; - - deltaZ = zFar - zNear; - sine = sin(radians); - - if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) { - return *this; - } - - cotangent = cos(radians) / sine; - - identity(); - m[0] = cotangent / aspect; - m[5] = cotangent; - m[10] = -(zFar + zNear) / deltaZ; - m[11] = -1; - m[14] = -2 * zNear * zFar / deltaZ; - m[15] = 0; - - return *this; -} - -/** - * Inverts this matrix. - * - * This method can currently handle only pure translation-rotation matrices. - * - * @return reference to the matrix - */ -Matrix4f &Matrix4f::invert() -{ - // If the bottom row is [0, 0, 0, 1] this is a pure translation-rotation - // transformation matrix and we can optimize the matrix inversion. - // Read http://www.gamedev.net/community/forums/topic.asp?topic_id=425118 - // for an explanation. - if (m[3] == 0.0 && m[7] == 0.0 && m[11] == 0.0 && m[15] == 1.0) { - // Extract and invert the translation part 't'. The inverse of a - // translation matrix can be calculated by negating the translation - // coordinates. - Matrix4f t(1.0, 1.0, 1.0); - t.m[12] = -m[12]; t.m[13] = -m[13]; t.m[14] = -m[14]; - - // Invert the rotation part 'r'. The inverse of a rotation matrix is - // equal to its transpose. - m[12] = m[13] = m[14] = 0; - this->transpose(); - - // inv(m) = inv(r) * inv(t) - *this *= t; - } - else { - // Don't care about the general case for now - } - - return *this; -} - -/** - * Creates an empty matrix. - * - * All matrix components are 0.0 expect the lower right - * which is 1.0. - */ -Matrix4f::Matrix4f() -{ - memset(m, 0, sizeof(m)); - m[15] = 1.0; -} - -/** - * Copy constructor. - * - * @param mat the matrix to copy the contents of. - */ -Matrix4f::Matrix4f(Matrix4f &mat) -{ - memcpy(m, mat.m, sizeof(m)); -} - -/** - * Creates a matrix with specified values in the diagonal. - * - * The lower right value is initialized to 1.0. - * - * @param x the x component of the diagonal - * @param y the y component of the diagonal - * @param z the z component of the diagonal - */ -Matrix4f::Matrix4f(GLfloat x, GLfloat y, GLfloat z) -{ - memset(m, 0, sizeof(m)); - m[0] = x; - m[5] = y; - m[10] = z; - m[15] = 1.0; -} - -/** - * Displays a matrix. - * - * @param str string to display before matrix - */ -void Matrix4f::display(const char *str) -{ - int r; - if (str != NULL) - printf("%s\n", str); - for(r = 0; r < 4; r++) - printf("%f %f %f %f\n", m[r], m[r + 4], m[r + 8], m[r + 12]); -} === removed file 'src/matrix.h' --- src/matrix.h 2011-01-25 15:06:04 +0000 +++ src/matrix.h 1970-01-01 00:00:00 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright © 2010-2011 Linaro Limited - * - * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. - * - * glmark2 is free software: you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later - * version. - * - * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * glmark2. If not, see . - * - * Authors: - * Alexandros Frantzis (glmark2) - */ -#ifndef GLMARK2_MATRIX_H_ -#define GLMARK2_MATRIX_H_ - -#include "oglsdl.h" - -#include -#include - -class Matrix4f -{ - -public: - GLfloat m[16]; - - Matrix4f(); - Matrix4f(Matrix4f &mat); - Matrix4f(GLfloat x, GLfloat y, GLfloat z); - - Matrix4f &translate(GLfloat x, GLfloat y, GLfloat z); - Matrix4f &rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); - Matrix4f &transpose(); - Matrix4f &perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); - Matrix4f &identity(); - Matrix4f &invert(); - - Matrix4f &operator*=(const Matrix4f &pM); - - void display(const char *str); -}; - -#endif === modified file 'src/mesh.cpp' --- src/mesh.cpp 2011-06-07 09:40:55 +0000 +++ src/mesh.cpp 2011-06-17 13:16:16 +0000 @@ -22,17 +22,7 @@ * Alexandros Frantzis (glmark2) */ #include "mesh.h" -#include "shader.h" - -Texel::Texel() -{ - u = 0; v = 0; -} - -Texel::Texel(GLfloat pU, GLfloat pV) -{ - u = pU; v = pV; -} + Mesh::Mesh() { @@ -74,7 +64,7 @@ unsigned i, j; unsigned k = 0; - Vector3f a, b, c, d, n; + LibMatrix::vec3 a, b, c, d, n; mMode = GL_TRIANGLES; mVertexQty = wraps_qty * per_wrap_qty * 6; @@ -87,60 +77,66 @@ float phi = 2 * M_PI * wrap_frac; float theta = 2 * M_PI * (i + wrap_frac) / (float)wraps_qty; float r = major_radius + minor_radius * (float)cos(phi); - a.x = (float)sin(theta) * r; - a.y = minor_radius * (float)sin(phi); - a.z = (float)cos(theta) * r; + a.x((float)sin(theta) * r); + a.y(minor_radius * (float)sin(phi)); + a.z((float)cos(theta) * r); theta = 2 * M_PI * (i + wrap_frac + 1) / (float)wraps_qty; - b.x = (float)sin(theta) * r; - b.y = minor_radius * (float)sin(phi); - b.z = (float)cos(theta) * r; + b.x((float)sin(theta) * r); + b.y(minor_radius * (float)sin(phi)); + b.z((float)cos(theta) * r); wrap_frac = (j + 1) / (float)per_wrap_qty; phi = 2 * M_PI * wrap_frac; theta = 2 * M_PI * (i + wrap_frac) / (float)wraps_qty; r = major_radius + minor_radius * (float)cos(phi); - c.x = (float)sin(theta) * r; - c.y = minor_radius * (float)sin(phi); - c.z = (float)cos(theta) * r; + c.x((float)sin(theta) * r); + c.y(minor_radius * (float)sin(phi)); + c.z((float)cos(theta) * r); theta = 2 * M_PI * (i + wrap_frac + 1) / (float)wraps_qty; - d.x = (float)sin(theta) * r; - d.y = minor_radius * (float)sin(phi); - d.z = (float)cos(theta) * r; + d.x((float)sin(theta) * r); + d.y(minor_radius * (float)sin(phi)); + d.z((float)cos(theta) * r); - n = normal(a, b, c); + n = LibMatrix::vec3::cross(b - a, c - a); + n.normalize(); mVertex[k].n = n; mVertex[k].v = a; k++; mVertex[k].n = n; mVertex[k].v = b; k++; mVertex[k].n = n; mVertex[k].v = c; k++; - n = normal(a, b, c); + n = LibMatrix::vec3::cross(c - b, d - b); + n.normalize(); mVertex[k].n = n; mVertex[k].v = b; k++; mVertex[k].n = n; mVertex[k].v = c; k++; mVertex[k].n = n; mVertex[k].v = d; k++; } } -void Mesh::render_array() +void Mesh::render_array(int vertex_loc, int normal_loc, int texcoord_loc) { - // Enable the attributes - glEnableVertexAttribArray(Shader::VertexAttribLocation); - glEnableVertexAttribArray(Shader::NormalAttribLocation); - glEnableVertexAttribArray(Shader::TexCoordAttribLocation); + // Enable the attributes (texcoord is optional) + glEnableVertexAttribArray(vertex_loc); + glEnableVertexAttribArray(normal_loc); + if (texcoord_loc >= 0) + glEnableVertexAttribArray(texcoord_loc); glBindBuffer(GL_ARRAY_BUFFER, 0); - glVertexAttribPointer(Shader::VertexAttribLocation, 3, GL_FLOAT, - GL_FALSE, sizeof(Vertex), &mVertex[0].v.x); - glVertexAttribPointer(Shader::NormalAttribLocation, 3, GL_FLOAT, - GL_FALSE, sizeof(Vertex), &mVertex[0].n.x); - glVertexAttribPointer(Shader::TexCoordAttribLocation, 2, GL_FLOAT, - GL_FALSE, sizeof(Vertex), &mVertex[0].t.u); + glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, + 8 * sizeof(float), mVertex[0].v); + glVertexAttribPointer(normal_loc, 3, GL_FLOAT, GL_FALSE, + 8 * sizeof(float), mVertex[0].n); + if (texcoord_loc >= 0) { + glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, + 8 * sizeof(float), mVertex[0].t); + } glDrawArrays(GL_TRIANGLES, 0, mVertexQty); // Disable the attributes - glDisableVertexAttribArray(Shader::TexCoordAttribLocation); - glDisableVertexAttribArray(Shader::NormalAttribLocation); - glDisableVertexAttribArray(Shader::VertexAttribLocation); + glDisableVertexAttribArray(vertex_loc); + glDisableVertexAttribArray(normal_loc); + if (texcoord_loc >= 0) + glDisableVertexAttribArray(texcoord_loc); } void Mesh::build_vbo() @@ -149,38 +145,43 @@ printf("Building vbo for mesh... "); #endif - Vector3f *vertex; - Texel *texel; - Vector3f *normal; + float *vertex; + float *texel; + float *normal; - vertex = new Vector3f[mVertexQty]; - texel = new Texel[mVertexQty]; - normal = new Vector3f[mVertexQty]; + vertex = new float[mVertexQty * 3]; + texel = new float[mVertexQty * 2]; + normal = new float[mVertexQty * 3]; for(unsigned i = 0; i < mVertexQty; i++) { - vertex[i] = mVertex[i].v; - texel[i] = mVertex[i].t; - normal[i] = mVertex[i].n; + vertex[3 * i] = mVertex[i].v.x(); + vertex[3 * i + 1] = mVertex[i].v.y(); + vertex[3 * i + 2] = mVertex[i].v.z(); + texel[2 * i] = mVertex[i].t.x(); + texel[2 * i + 1] = mVertex[i].t.y(); + normal[3 * i] = mVertex[i].n.x(); + normal[3 * i + 1] = mVertex[i].n.y(); + normal[3 * i + 2] = mVertex[i].n.z(); } // Generate And Bind The Vertex Buffer glGenBuffers(1, &mVBOVertices); glBindBuffer(GL_ARRAY_BUFFER, mVBOVertices); // Load The Data - glBufferData(GL_ARRAY_BUFFER, mVertexQty * sizeof(Vector3f), vertex, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, mVertexQty * 3 * sizeof(float), vertex, GL_STATIC_DRAW); // Generate And Bind The normal Buffer glGenBuffers(1, &mVBONormals); glBindBuffer(GL_ARRAY_BUFFER, mVBONormals); // Load The Data - glBufferData(GL_ARRAY_BUFFER, mVertexQty * sizeof(Vector3f), normal, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, mVertexQty * 3 * sizeof(float), normal, GL_STATIC_DRAW); // Generate And Bind The Texture Coordinate Buffer glGenBuffers(1, &mVBOTexCoords); glBindBuffer(GL_ARRAY_BUFFER, mVBOTexCoords); // Load The Data - glBufferData(GL_ARRAY_BUFFER, mVertexQty * sizeof(Texel), texel, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, mVertexQty * 2 * sizeof(float), texel, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -200,24 +201,28 @@ glDeleteBuffers(1, &mVBOTexCoords); } -void Mesh::render_vbo() +void Mesh::render_vbo(int vertex_loc, int normal_loc, int texcoord_loc) { - // Enable the attributes - glEnableVertexAttribArray(Shader::VertexAttribLocation); - glEnableVertexAttribArray(Shader::NormalAttribLocation); - glEnableVertexAttribArray(Shader::TexCoordAttribLocation); + // Enable the attributes (texcoord is optional) + glEnableVertexAttribArray(vertex_loc); + glEnableVertexAttribArray(normal_loc); + if (texcoord_loc >= 0) + glEnableVertexAttribArray(texcoord_loc); glBindBuffer(GL_ARRAY_BUFFER, mVBOVertices); - glVertexAttribPointer(Shader::VertexAttribLocation, 3, GL_FLOAT, GL_FALSE, 0, 0); + glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, mVBONormals); - glVertexAttribPointer(Shader::NormalAttribLocation, 3, GL_FLOAT, GL_FALSE, 0, 0); - glBindBuffer(GL_ARRAY_BUFFER, mVBOTexCoords); - glVertexAttribPointer(Shader::TexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, 0); + glVertexAttribPointer(normal_loc, 3, GL_FLOAT, GL_FALSE, 0, 0); + if (texcoord_loc >= 0) { + glBindBuffer(GL_ARRAY_BUFFER, mVBOTexCoords); + glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, 0, 0); + } glDrawArrays(GL_TRIANGLES, 0, mVertexQty); // Disable the attributes - glDisableVertexAttribArray(Shader::TexCoordAttribLocation); - glDisableVertexAttribArray(Shader::NormalAttribLocation); - glDisableVertexAttribArray(Shader::VertexAttribLocation); + glDisableVertexAttribArray(vertex_loc); + glDisableVertexAttribArray(normal_loc); + if (texcoord_loc >= 0) + glDisableVertexAttribArray(texcoord_loc); } === modified file 'src/mesh.h' --- src/mesh.h 2011-06-07 09:40:55 +0000 +++ src/mesh.h 2011-06-17 13:16:16 +0000 @@ -25,26 +25,15 @@ #define GLMARK2_MESH_H_ #include "screen.h" -#include "vector.h" +#include "vec.h" #include #include -class Texel -{ -public: - GLfloat u, v; - - Texel(); - Texel(GLfloat pU, GLfloat pV); -}; - -class Vertex -{ -public: - Vector3f v; - Vector3f n; - Texel t; +struct Vertex { + LibMatrix::vec3 v; + LibMatrix::vec3 n; + LibMatrix::vec2 t; }; // Data for a mesh to be rendered by vertex arrays' or vbos' has 3 verticies per @@ -67,10 +56,10 @@ void reset(); void make_cube(); void make_torus(); - void render_array(); + void render_array(int vertex_loc, int normal_loc, int texcoord_loc); void build_vbo(); void delete_vbo(); - void render_vbo(); + void render_vbo(int vertex_loc, int normal_loc, int texcoord_loc); }; #endif === modified file 'src/model.cpp' --- src/model.cpp 2011-06-07 09:40:55 +0000 +++ src/model.cpp 2011-06-17 09:39:44 +0000 @@ -22,6 +22,7 @@ * Alexandros Frantzis (glmark2) */ #include "model.h" +#include "vec.h" long filelength(int f) { @@ -82,11 +83,13 @@ #ifdef _DEBUG printf("Calculating normals for model... "); #endif - Vector3f n; + LibMatrix::vec3 n; for(unsigned i = 0; i < mPolygonQty; i++) { - n = normal(mVertex[mPolygon[i].mA].v, mVertex[mPolygon[i].mB].v, mVertex[mPolygon[i].mC].v); + n = LibMatrix::vec3::cross(mVertex[mPolygon[i].mB].v - mVertex[mPolygon[i].mA].v, + mVertex[mPolygon[i].mC].v - mVertex[mPolygon[i].mA].v); + n.normalize(); mVertex[mPolygon[i].mA].n += n; mVertex[mPolygon[i].mB].n += n; mVertex[mPolygon[i].mC].n += n; @@ -102,21 +105,22 @@ void Model::center() { - Vector3f center; - Vector3f max = mVertex[0].v, min = mVertex[0].v; + LibMatrix::vec3 max(mVertex[0].v); + LibMatrix::vec3 min(mVertex[0].v); for(unsigned i = 1; i < mVertexQty; i++) { - if(mVertex[i].v.x > max.x) max.x = mVertex[i].v.x; - if(mVertex[i].v.y > max.y) max.y = mVertex[i].v.y; - if(mVertex[i].v.z > max.z) max.z = mVertex[i].v.z; + if(mVertex[i].v.x() > max.x()) max.x(mVertex[i].v.x()); + if(mVertex[i].v.y() > max.y()) max.y(mVertex[i].v.y()); + if(mVertex[i].v.z() > max.z()) max.z(mVertex[i].v.z()); - if(mVertex[i].v.x < min.x) min.x = mVertex[i].v.x; - if(mVertex[i].v.y < min.y) min.y = mVertex[i].v.y; - if(mVertex[i].v.z < min.z) min.z = mVertex[i].v.z; + if(mVertex[i].v.x() < min.x()) min.x(mVertex[i].v.x()); + if(mVertex[i].v.y() < min.y()) min.y(mVertex[i].v.y()); + if(mVertex[i].v.z() < min.z()) min.z(mVertex[i].v.z()); } - center = (max + min) / 2.0f; + LibMatrix::vec3 center(max + min); + center /= 2.0f; for(unsigned i = 0; i < mVertexQty; i++) mVertex[i].v -= center; @@ -210,9 +214,11 @@ mVertexQty = l_qty; mVertex = new Vertex[mVertexQty]; for (i = 0; i < l_qty; i++) { - nread = fread (&mVertex[i].v.x, sizeof(float), 1, l_file); - nread = fread (&mVertex[i].v.y, sizeof(float), 1, l_file); - nread = fread (&mVertex[i].v.z, sizeof(float), 1, l_file); + float f[3]; + nread = fread (f, sizeof(float), 3, l_file); + mVertex[i].v.x(f[0]); + mVertex[i].v.y(f[1]); + mVertex[i].v.z(f[2]); } break; @@ -245,8 +251,10 @@ case 0x4140: nread = fread (&l_qty, sizeof (unsigned short), 1, l_file); for (i = 0; i < l_qty; i++) { - nread = fread (&mVertex[i].t.u, sizeof (float), 1, l_file); - nread = fread (&mVertex[i].t.v, sizeof (float), 1, l_file); + float f[2]; + nread = fread (f, sizeof(float), 2, l_file); + mVertex[i].t.x(f[0]); + mVertex[i].t.y(f[1]); } break; === modified file 'src/scene.cpp' --- src/scene.cpp 2011-06-15 11:20:45 +0000 +++ src/scene.cpp 2011-06-17 13:16:16 +0000 @@ -22,6 +22,7 @@ * Alexandros Frantzis (glmark2) */ #include "scene.h" +#include "log.h" #include #include @@ -154,3 +155,50 @@ return std::sqrt(s); } + +bool +Scene::load_shaders(Program &program, + const std::string &vtx_shader_filename, + const std::string &frg_shader_filename) +{ + std::string vtx_shader; + std::string frg_shader; + + if (!gotSource(vtx_shader_filename, vtx_shader)) + return false; + + if (!gotSource(frg_shader_filename, frg_shader)) + return false; + + program.init(); + + program.addShader(GL_VERTEX_SHADER, vtx_shader); + if (!program.valid()) { + Log::error("Failed to add vertex shader from file %s:\n %s\n", + vtx_shader_filename.c_str(), + program.errorMessage().c_str()); + program.release(); + return false; + } + + program.addShader(GL_FRAGMENT_SHADER, frg_shader); + if (!program.valid()) { + Log::error("Failed to add fragment shader from file %s:\n %s\n", + frg_shader_filename.c_str(), + program.errorMessage().c_str()); + program.release(); + return false; + } + + program.build(); + if (!program.ready()) { + Log::error("Failed to link program created from files %s and %s: %s\n", + vtx_shader_filename.c_str(), + frg_shader_filename.c_str(), + program.errorMessage().c_str()); + program.release(); + return false; + } + + return true; +} === modified file 'src/scene.h' --- src/scene.h 2011-06-16 07:43:05 +0000 +++ src/scene.h 2011-06-17 13:16:16 +0000 @@ -29,7 +29,8 @@ #include "mesh.h" #include "model.h" #include "texture.h" -#include "shader.h" +#include "vec.h" +#include "program.h" #include @@ -90,6 +91,10 @@ virtual ValidationResult validate() { return ValidationUnknown; } + static bool load_shaders(Program &program, + const std::string &vtx_shader_filename, + const std::string &frg_shader_filename); + protected: Scene(Screen &pScreen, const std::string &name); std::string construct_title(const std::string &title); @@ -124,7 +129,10 @@ ~SceneBuild(); protected: - Shader mShader; + Program mProgram; + int mVertexAttribLocation; + int mNormalAttribLocation; + int mTexcoordAttribLocation; Mesh mMesh; float mRotation; @@ -147,12 +155,15 @@ ~SceneTexture(); protected: - Shader mShader; + Program mProgram; + int mVertexAttribLocation; + int mNormalAttribLocation; + int mTexcoordAttribLocation; Mesh mCubeMesh; GLuint mTexture; - Vector3f mRotation; - Vector3f mRotationSpeed; + LibMatrix::vec3 mRotation; + LibMatrix::vec3 mRotationSpeed; }; class SceneShading : public Scene @@ -170,7 +181,10 @@ ~SceneShading(); protected: - Shader mShader; + Program mProgram; + int mVertexAttribLocation; + int mNormalAttribLocation; + int mTexcoordAttribLocation; Mesh mMesh; float mRotation; === modified file 'src/scenebuild.cpp' --- src/scenebuild.cpp 2011-06-15 11:44:36 +0000 +++ src/scenebuild.cpp 2011-06-17 13:16:16 +0000 @@ -23,6 +23,8 @@ */ #include "scene.h" #include "log.h" +#include "mat.h" +#include "stack.h" #include SceneBuild::SceneBuild(Screen &pScreen) : @@ -38,6 +40,8 @@ int SceneBuild::load() { + static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.vert"); + static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.frag"); Model model; if(!model.load_3ds(GLMARK_DATA_PATH"/models/horse.3ds")) @@ -46,8 +50,12 @@ model.calculate_normals(); model.convert_to_mesh(&mMesh); - mShader.load(GLMARK_DATA_PATH"/shaders/light-basic.vert", - GLMARK_DATA_PATH"/shaders/light-basic.frag"); + if (!Scene::load_shaders(mProgram, vtx_shader_filename, frg_shader_filename)) + return 0; + + mVertexAttribLocation = mProgram.getAttribIndex("position"); + mNormalAttribLocation = mProgram.getAttribIndex("normal"); + mTexcoordAttribLocation = mProgram.getAttribIndex("texcoord"); mRotationSpeed = 36.0f; @@ -59,34 +67,32 @@ void SceneBuild::unload() { mMesh.reset(); - mShader.remove(); - mShader.unload(); + + mProgram.stop(); + mProgram.release(); } void SceneBuild::setup() { Scene::setup(); - GLfloat lightAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f}; - GLfloat lightDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f}; - GLfloat lightPosition[] = {20.0f, 20.0f, 10.0f, 1.0f}; - GLfloat materialColor[] = {1.0f, 1.0f, 1.0f, 1.0f}; - + static const LibMatrix::vec4 lightAmbient(0.0f, 0.0f, 0.0f, 1.0f); + static const LibMatrix::vec4 lightDiffuse(0.8f, 0.8f, 0.8f, 1.0f); + static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f); + static const LibMatrix::vec4 materialColor(1.0f, 1.0f, 1.0f, 1.0f); mUseVbo = (mOptions["use-vbo"].value == "true"); if (mUseVbo) mMesh.build_vbo(); - mShader.use(); + mProgram.start(); // Load lighting and material uniforms - glUniform4fv(mShader.mLocations.LightSourcePosition, 1, lightPosition); - - glUniform3fv(mShader.mLocations.LightSourceAmbient, 1, lightAmbient); - glUniform3fv(mShader.mLocations.LightSourceDiffuse, 1, lightDiffuse); - - glUniform4fv(mShader.mLocations.MaterialColor, 1, materialColor); + mProgram.loadUniformVector(lightAmbient, "LightSourceAmbient"); + mProgram.loadUniformVector(lightPosition, "LightSourcePosition"); + mProgram.loadUniformVector(lightDiffuse, "LightSourceDiffuse"); + mProgram.loadUniformVector(materialColor, "MaterialColor"); mCurrentFrame = 0; mRotation = 0.0; @@ -98,7 +104,7 @@ void SceneBuild::teardown() { - mShader.remove(); + mProgram.stop(); if (mUseVbo) mMesh.delete_vbo(); @@ -126,27 +132,33 @@ void SceneBuild::draw() { + LibMatrix::Stack4 model_view; + // Load the ModelViewProjectionMatrix uniform in the shader - Matrix4f model_view(1.0f, 1.0f, 1.0f); - Matrix4f model_view_proj(mScreen.mProjection); + LibMatrix::mat4 model_view_proj(mScreen.mProjection); model_view.translate(0.0f, 0.0f, -2.5f); - model_view.rotate(2 * M_PI * mRotation / 360.0, 0.0f, 1.0f, 0.0f); - model_view_proj *= model_view; + model_view.rotate(mRotation, 0.0f, 1.0f, 0.0f); + model_view_proj *= model_view.getCurrent(); - glUniformMatrix4fv(mShader.mLocations.ModelViewProjectionMatrix, 1, - GL_FALSE, model_view_proj.m); + mProgram.loadUniformMatrix(model_view_proj, "ModelViewProjectionMatrix"); // Load the NormalMatrix uniform in the shader. The NormalMatrix is the // inverse transpose of the model view matrix. - model_view.invert().transpose(); - glUniformMatrix4fv(mShader.mLocations.NormalMatrix, 1, - GL_FALSE, model_view.m); + LibMatrix::mat4 normal_matrix(model_view.getCurrent()); + normal_matrix.inverse().transpose(); + mProgram.loadUniformMatrix(normal_matrix, "NormalMatrix"); - if (mUseVbo) - mMesh.render_vbo(); - else - mMesh.render_array(); + if (mUseVbo) { + mMesh.render_vbo(mVertexAttribLocation, + mNormalAttribLocation, + mTexcoordAttribLocation); + } + else { + mMesh.render_array(mVertexAttribLocation, + mNormalAttribLocation, + mTexcoordAttribLocation); + } } Scene::ValidationResult === modified file 'src/sceneshading.cpp' --- src/sceneshading.cpp 2011-06-16 07:43:05 +0000 +++ src/sceneshading.cpp 2011-06-17 13:16:16 +0000 @@ -22,7 +22,9 @@ * Alexandros Frantzis (glmark2) */ #include "scene.h" -#include "matrix.h" +#include "mat.h" +#include "stack.h" +#include "vec.h" #include "log.h" #include @@ -66,48 +68,55 @@ { Scene::setup(); - GLfloat lightAmbient[] = {0.1f, 0.1f, 0.1f, 1.0f}; - GLfloat lightDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f}; - GLfloat lightSpecular[] = {0.8f, 0.8f, 0.8f, 1.0f}; - GLfloat lightPosition[] = {20.0f, 20.0f, 10.0f, 1.0f}; - - float materialAmbient[] = {1.0f, 1.0f, 1.0f, 1.0f}; - float materialDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; - float materialSpecular[] = {1.0f, 1.0f, 1.0f, 1.0f}; - float materialColor[] = {0.0f, 0.0f, 1.0f, 1.0f}; - + static const LibMatrix::vec3 lightAmbient(0.1f, 0.1f, 0.1f); + static const LibMatrix::vec3 lightDiffuse(0.8f, 0.8f, 0.8f); + static const LibMatrix::vec3 lightSpecular(0.8f, 0.8f, 0.8f); + static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f); + + static const LibMatrix::vec3 materialAmbient(1.0f, 1.0f, 1.0f); + static const LibMatrix::vec3 materialDiffuse(1.0f, 1.0f, 1.0f); + static const LibMatrix::vec3 materialSpecular(1.0f, 1.0f, 1.0f); + static const LibMatrix::vec4 materialColor(0.0f, 0.0f, 1.0f, 1.0f); + + std::string vtx_shader_filename; + std::string frg_shader_filename; const std::string &shading = mOptions["shading"].value; if (shading == "gouraud") { - mShader.load(GLMARK_DATA_PATH"/shaders/light-basic.vert", - GLMARK_DATA_PATH"/shaders/light-basic.frag"); + vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.vert"; + frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.frag"; } else if (shading == "phong") { - mShader.load(GLMARK_DATA_PATH"/shaders/light-advanced.vert", - GLMARK_DATA_PATH"/shaders/light-advanced.frag"); + vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-advanced.vert"; + frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-advanced.frag"; } - mShader.use(); + if (!Scene::load_shaders(mProgram, vtx_shader_filename, frg_shader_filename)) + return; + + mProgram.start(); + + mVertexAttribLocation = mProgram.getAttribIndex("position"); + mNormalAttribLocation = mProgram.getAttribIndex("normal"); + mTexcoordAttribLocation = mProgram.getAttribIndex("texcoord"); // Load lighting and material uniforms - glUniform4fv(mShader.mLocations.LightSourcePosition, 1, lightPosition); - - glUniform3fv(mShader.mLocations.LightSourceAmbient, 1, lightAmbient); - glUniform3fv(mShader.mLocations.LightSourceDiffuse, 1, lightDiffuse); - glUniform3fv(mShader.mLocations.LightSourceSpecular, 1, lightSpecular); - - glUniform3fv(mShader.mLocations.MaterialAmbient, 1, materialAmbient); - glUniform3fv(mShader.mLocations.MaterialDiffuse, 1, materialDiffuse); - glUniform3fv(mShader.mLocations.MaterialSpecular, 1, materialSpecular); - glUniform4fv(mShader.mLocations.MaterialColor, 1, materialColor); + mProgram.loadUniformVector(lightAmbient, "LightSourceAmbient"); + mProgram.loadUniformVector(lightPosition, "LightSourcePosition"); + mProgram.loadUniformVector(lightDiffuse, "LightSourceDiffuse"); + mProgram.loadUniformVector(lightSpecular, "LightSourceSpecular"); + + mProgram.loadUniformVector(materialAmbient, "MaterialAmbient"); + mProgram.loadUniformVector(materialDiffuse, "MaterialDiffuse"); + mProgram.loadUniformVector(materialSpecular, "MaterialSpecular"); + mProgram.loadUniformVector(materialColor, "MaterialColor"); // Calculate and load the half vector - Vector3f halfVector = Vector3f(lightPosition[0], lightPosition[1], lightPosition[2]); - halfVector.normalize(); - halfVector += Vector3f(0.0, 0.0, 1.0); - halfVector.normalize(); - glUniform3fv(mShader.mLocations.LightSourceHalfVector, 1, - (GLfloat *)&halfVector); + LibMatrix::vec3 halfVector(lightPosition[0], lightPosition[1], lightPosition[2]); + halfVector.normalize(); + halfVector += LibMatrix::vec3(0.0, 0.0, 1.0); + halfVector.normalize(); + mProgram.loadUniformVector(halfVector, "LightSourceHalfVector"); mCurrentFrame = 0; mRotation = 0.0f; @@ -118,8 +127,8 @@ void SceneShading::teardown() { - mShader.remove(); - mShader.unload(); + mProgram.stop(); + mProgram.release(); Scene::teardown(); } @@ -145,23 +154,24 @@ void SceneShading::draw() { // Load the ModelViewProjectionMatrix uniform in the shader - Matrix4f model_view(1.0f, 1.0f, 1.0f); - Matrix4f model_view_proj(mScreen.mProjection); + LibMatrix::Stack4 model_view; + LibMatrix::mat4 model_view_proj(mScreen.mProjection); model_view.translate(0.0f, 0.0f, -5.0f); - model_view.rotate(2 * M_PI * mRotation / 360.0, 0.0f, 1.0f, 0.0f); - model_view_proj *= model_view; + model_view.rotate(mRotation, 0.0f, 1.0f, 0.0f); + model_view_proj *= model_view.getCurrent(); - glUniformMatrix4fv(mShader.mLocations.ModelViewProjectionMatrix, 1, - GL_FALSE, model_view_proj.m); + mProgram.loadUniformMatrix(model_view_proj, "ModelViewProjectionMatrix"); // Load the NormalMatrix uniform in the shader. The NormalMatrix is the // inverse transpose of the model view matrix. - model_view.invert().transpose(); - glUniformMatrix4fv(mShader.mLocations.NormalMatrix, 1, - GL_FALSE, model_view.m); + LibMatrix::mat4 normal_matrix(model_view.getCurrent()); + normal_matrix.inverse().transpose(); + mProgram.loadUniformMatrix(normal_matrix, "NormalMatrix"); - mMesh.render_vbo(); + mMesh.render_vbo(mVertexAttribLocation, + mNormalAttribLocation, + mTexcoordAttribLocation); } Scene::ValidationResult === modified file 'src/scenetexture.cpp' --- src/scenetexture.cpp 2011-06-16 07:39:55 +0000 +++ src/scenetexture.cpp 2011-06-17 13:16:16 +0000 @@ -22,9 +22,12 @@ * Alexandros Frantzis (glmark2) */ #include "scene.h" -#include "matrix.h" +#include "mat.h" +#include "stack.h" +#include "vec.h" #include "log.h" +#include "program.h" #include SceneTexture::SceneTexture(Screen &pScreen) : @@ -40,6 +43,8 @@ int SceneTexture::load() { + static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.vert"); + static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic-tex.frag"); Model model; if(!model.load_3ds(GLMARK_DATA_PATH"/models/cube.3ds")) @@ -49,10 +54,14 @@ model.convert_to_mesh(&mCubeMesh); mCubeMesh.build_vbo(); - mShader.load(GLMARK_DATA_PATH"/shaders/light-basic.vert", - GLMARK_DATA_PATH"/shaders/light-basic-tex.frag"); - - mRotationSpeed = Vector3f(36.0f, 36.0f, 36.0f); + if (!Scene::load_shaders(mProgram, vtx_shader_filename, frg_shader_filename)) + return 0; + + mVertexAttribLocation = mProgram.getAttribIndex("position"); + mNormalAttribLocation = mProgram.getAttribIndex("normal"); + mTexcoordAttribLocation = mProgram.getAttribIndex("texcoord"); + + mRotationSpeed = LibMatrix::vec3(36.0f, 36.0f, 36.0f); mRunning = false; @@ -62,17 +71,19 @@ void SceneTexture::unload() { mCubeMesh.reset(); - mShader.unload(); + + mProgram.stop(); + mProgram.release(); } void SceneTexture::setup() { Scene::setup(); - GLfloat lightAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f}; - GLfloat lightDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f}; - GLfloat lightPosition[] = {20.0f, 20.0f, 10.0f, 1.0f}; - GLfloat materialColor[] = {1.0f, 1.0f, 1.0f, 1.0f}; + static const LibMatrix::vec4 lightAmbient(0.0f, 0.0f, 0.0f, 1.0f); + static const LibMatrix::vec4 lightDiffuse(0.8f, 0.8f, 0.8f, 1.0f); + static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f); + static const LibMatrix::vec4 materialColor(1.0f, 1.0f, 1.0f, 1.0f); // Create texture according to selected filtering GLint min_filter = GL_NONE; @@ -95,18 +106,16 @@ Texture::load(GLMARK_DATA_PATH"/textures/crate-base.bmp", &mTexture, min_filter, mag_filter, 0); - mShader.use(); + mProgram.start(); // Load lighting and material uniforms - glUniform4fv(mShader.mLocations.LightSourcePosition, 1, lightPosition); - - glUniform3fv(mShader.mLocations.LightSourceAmbient, 1, lightAmbient); - glUniform3fv(mShader.mLocations.LightSourceDiffuse, 1, lightDiffuse); - - glUniform4fv(mShader.mLocations.MaterialColor, 1, materialColor); + mProgram.loadUniformVector(lightAmbient, "LightSourceAmbient"); + mProgram.loadUniformVector(lightPosition, "LightSourcePosition"); + mProgram.loadUniformVector(lightDiffuse, "LightSourceDiffuse"); + mProgram.loadUniformVector(materialColor, "MaterialColor"); mCurrentFrame = 0; - mRotation = Vector3f(); + mRotation = LibMatrix::vec3(); mRunning = true; mStartTime = SDL_GetTicks() / 1000.0; mLastUpdateTime = mStartTime; @@ -114,7 +123,7 @@ void SceneTexture::teardown() { - mShader.remove(); + mProgram.stop(); glDeleteTextures(1, &mTexture); Scene::teardown(); @@ -141,28 +150,29 @@ void SceneTexture::draw() { // Load the ModelViewProjectionMatrix uniform in the shader - Matrix4f model_view(1.0f, 1.0f, 1.0f); - Matrix4f model_view_proj(mScreen.mProjection); + LibMatrix::Stack4 model_view; + LibMatrix::mat4 model_view_proj(mScreen.mProjection); model_view.translate(0.0f, 0.0f, -5.0f); - model_view.rotate(2 * M_PI * mRotation.x / 360.0, 1.0f, 0.0f, 0.0f); - model_view.rotate(2 * M_PI * mRotation.y / 360.0, 0.0f, 1.0f, 0.0f); - model_view.rotate(2 * M_PI * mRotation.z / 360.0, 0.0f, 0.0f, 1.0f); - model_view_proj *= model_view; + model_view.rotate(mRotation.x(), 1.0f, 0.0f, 0.0f); + model_view.rotate(mRotation.y(), 0.0f, 1.0f, 0.0f); + model_view.rotate(mRotation.z(), 0.0f, 0.0f, 1.0f); + model_view_proj *= model_view.getCurrent(); - glUniformMatrix4fv(mShader.mLocations.ModelViewProjectionMatrix, 1, - GL_FALSE, model_view_proj.m); + mProgram.loadUniformMatrix(model_view_proj, "ModelViewProjectionMatrix"); // Load the NormalMatrix uniform in the shader. The NormalMatrix is the // inverse transpose of the model view matrix. - model_view.invert().transpose(); - glUniformMatrix4fv(mShader.mLocations.NormalMatrix, 1, - GL_FALSE, model_view.m); + LibMatrix::mat4 normal_matrix(model_view.getCurrent()); + normal_matrix.inverse().transpose(); + mProgram.loadUniformMatrix(normal_matrix, "NormalMatrix"); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mTexture); - mCubeMesh.render_vbo(); + mCubeMesh.render_vbo(mVertexAttribLocation, + mNormalAttribLocation, + mTexcoordAttribLocation); } Scene::ValidationResult @@ -170,7 +180,7 @@ { static const double radius_3d(std::sqrt(3.0)); - if (mRotation.x != 0 || mRotation.y != 0 || mRotation.z != 0) + if (mRotation.x() != 0 || mRotation.y() != 0 || mRotation.z() != 0) return Scene::ValidationUnknown; Screen::Pixel ref; === modified file 'src/screen-sdl.cpp' --- src/screen-sdl.cpp 2011-04-26 12:10:35 +0000 +++ src/screen-sdl.cpp 2011-06-17 08:27:49 +0000 @@ -61,10 +61,11 @@ SDL_WM_SetCaption("glmark2 " GLMARK_VERSION, NULL); - mProjection.perspective(60.0, mWidth / (float)mHeight, 1.0, 1024.0); + mProjection = LibMatrix::Mat4::perspective(60.0, mWidth / (float)mHeight, + 1.0, 1024.0); #ifdef _DEBUG - mProjection.display("Projection"); + mProjection.print(); #endif mInitSuccess = 1; === modified file 'src/screen.h' --- src/screen.h 2011-06-15 10:11:13 +0000 +++ src/screen.h 2011-06-17 08:27:49 +0000 @@ -25,7 +25,7 @@ #define GLMARK2_SCREEN_H_ #include "oglsdl.h" -#include "matrix.h" +#include "mat.h" #include #include @@ -58,7 +58,7 @@ int mHeight; int mBpp; int mFullScreen; - Matrix4f mProjection; + LibMatrix::mat4 mProjection; int mInitSuccess; virtual void clear() {} === removed file 'src/shader.cpp' --- src/shader.cpp 2011-02-26 19:57:48 +0000 +++ src/shader.cpp 1970-01-01 00:00:00 +0000 @@ -1,179 +0,0 @@ -/* - * Copyright © 2008 Ben Smith - * Copyright © 2010-2011 Linaro Limited - * - * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. - * - * glmark2 is free software: you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later - * version. - * - * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * glmark2. If not, see . - * - * Authors: - * Ben Smith (original glmark benchmark) - * Alexandros Frantzis (glmark2) - */ -#include "shader.h" - -char *readShaderFile(const char *FileName) -{ - FILE *fp; - char *DATA = NULL; - - int flength = 0; - - fp = fopen(FileName,"rt"); - - fseek(fp, 0, SEEK_END); - - flength = ftell(fp); - - rewind(fp); - - - DATA = (char *)malloc(sizeof(char) * (flength+1)); - flength = fread(DATA, sizeof(char), flength, fp); - DATA[flength] = '\0'; - - fclose(fp); - - return DATA; -} - -Shader::~Shader() -{ - unload(); -} - -void Shader::load(const char *pVertexShaderFileName, const char *pFragmentShaderFileName) -{ - char *vertex_shader_source, *fragment_shader_source; - char msg[512]; - GLint status; - - mVertexShader = glCreateShader(GL_VERTEX_SHADER); - mFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - - vertex_shader_source = readShaderFile(pVertexShaderFileName); - - fragment_shader_source = readShaderFile(pFragmentShaderFileName); - - const char *vs = vertex_shader_source; - const char *fs = fragment_shader_source; - - glShaderSource(mVertexShader, 1, &vs, NULL); - glShaderSource(mFragmentShader, 1, &fs, NULL); - - free(vertex_shader_source); - free(fragment_shader_source); - - glCompileShader(mVertexShader); - glGetShaderiv(mVertexShader, GL_COMPILE_STATUS, &status); - if (status == GL_FALSE) { - glGetShaderInfoLog(mVertexShader, sizeof msg, NULL, msg); - fprintf(stderr, "Error compiling %s: %s", pVertexShaderFileName, - strlen(msg) > 0 ? msg : "[No info]"); - } - - glCompileShader(mFragmentShader); - glGetShaderiv(mFragmentShader, GL_COMPILE_STATUS, &status); - if (status == GL_FALSE) { - glGetShaderInfoLog(mFragmentShader, sizeof msg, NULL, msg); - fprintf(stderr, "Error compiling %s: %s", pFragmentShaderFileName, - strlen(msg) > 0 ? msg : "[No info]"); - } - - mShaderProgram = glCreateProgram(); - glAttachShader(mShaderProgram, mFragmentShader); - glAttachShader(mShaderProgram, mVertexShader); - glBindAttribLocation(mShaderProgram, VertexAttribLocation, "position"); - glBindAttribLocation(mShaderProgram, NormalAttribLocation, "normal"); - glBindAttribLocation(mShaderProgram, TexCoordAttribLocation, "texcoord"); - - glLinkProgram(mShaderProgram); - glGetProgramiv(mShaderProgram, GL_LINK_STATUS, &status); - if (status == GL_FALSE) { - glGetProgramInfoLog(mShaderProgram, sizeof msg, NULL, msg); - fprintf(stderr, "Error linking shader program: %s", - strlen(msg) > 0 ? msg : "[No info]"); - } - - mLocations.ModelViewProjectionMatrix = glGetUniformLocation(mShaderProgram, - "ModelViewProjectionMatrix"); - mLocations.NormalMatrix = glGetUniformLocation(mShaderProgram, - "NormalMatrix"); - mLocations.LightSourcePosition = glGetUniformLocation(mShaderProgram, - "LightSourcePosition"); - mLocations.LightSourceHalfVector = glGetUniformLocation(mShaderProgram, - "LightSourceHalfVector"); - - mLocations.LightSourceAmbient = glGetUniformLocation(mShaderProgram, - "LightSourceAmbient"); - mLocations.LightSourceDiffuse = glGetUniformLocation(mShaderProgram, - "LightSourceDiffuse"); - mLocations.LightSourceSpecular = glGetUniformLocation(mShaderProgram, - "LightSourceSpecular"); - - mLocations.MaterialAmbient = glGetUniformLocation(mShaderProgram, - "MaterialAmbient"); - mLocations.MaterialDiffuse = glGetUniformLocation(mShaderProgram, - "MaterialDiffuse"); - mLocations.MaterialSpecular = glGetUniformLocation(mShaderProgram, - "MaterialSpecular"); - mLocations.MaterialColor = glGetUniformLocation(mShaderProgram, - "MaterialColor"); - mLocations.MaterialTexture0 = glGetUniformLocation(mShaderProgram, - "MaterialTexture0"); - glUseProgram(mShaderProgram); - glUniform1i(mLocations.MaterialTexture0, 0); - glUseProgram(0); - -#ifdef _DEBUG - printf("Uniform Locations: %d %d %d %d %d %d %d %d %d %d %d %d\n", - mLocations.ModelViewProjectionMatrix, - mLocations.NormalMatrix, - mLocations.LightSourcePosition, - mLocations.LightSourceHalfVector, - mLocations.LightSourceAmbient, - mLocations.LightSourceDiffuse, - mLocations.LightSourceSpecular, - mLocations.MaterialAmbient, - mLocations.MaterialDiffuse, - mLocations.MaterialSpecular, - mLocations.MaterialColor, - mLocations.MaterialTexture0); -#endif - -} - -void Shader::use() -{ - glUseProgram(mShaderProgram); -} - -void Shader::remove() -{ - glUseProgram(0); -} - -void Shader::unload() -{ - glDetachShader(mShaderProgram, mVertexShader); - glDetachShader(mShaderProgram, mFragmentShader); - - glDeleteShader(mVertexShader); - glDeleteShader(mFragmentShader); - glDeleteProgram(mShaderProgram); - - mVertexShader = 0; - mFragmentShader = 0; - mShaderProgram = 0; -} === removed file 'src/shader.h' --- src/shader.h 2011-01-25 15:06:04 +0000 +++ src/shader.h 1970-01-01 00:00:00 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright © 2008 Ben Smith - * Copyright © 2010-2011 Linaro Limited - * - * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. - * - * glmark2 is free software: you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later - * version. - * - * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * glmark2. If not, see . - * - * Authors: - * Ben Smith (original glmark benchmark) - * Alexandros Frantzis (glmark2) - */ -#ifndef GLMARK2_SHADER_H_ -#define GLMARK2_SHADER_H_ - -#include "oglsdl.h" - -#include -#include - -class Shader -{ -public: - ~Shader(); - void load(const char *pVertexShaderFileName, const char *pFragmentShaderFileName); - void unload(); - - void use(); - void remove(); - - GLuint mVertexShader; - GLuint mFragmentShader; - int mShaderProgram; - struct { - GLint ModelViewProjectionMatrix; - GLint NormalMatrix; - GLint LightSourcePosition; - GLint LightSourceHalfVector; - GLint LightSourceAmbient; - GLint LightSourceDiffuse; - GLint LightSourceSpecular; - GLint MaterialAmbient; - GLint MaterialDiffuse; - GLint MaterialSpecular; - GLint MaterialColor; - GLint MaterialTexture0; - } mLocations; - - enum { - VertexAttribLocation = 0, - NormalAttribLocation = 1, - TexCoordAttribLocation = 2 - }; -}; - -#endif === removed file 'src/vector.cpp' --- src/vector.cpp 2011-01-25 15:00:12 +0000 +++ src/vector.cpp 1970-01-01 00:00:00 +0000 @@ -1,148 +0,0 @@ -/* - * Copyright © 2008 Ben Smith - * Copyright © 2010-2011 Linaro Limited - * - * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. - * - * glmark2 is free software: you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later - * version. - * - * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * glmark2. If not, see . - * - * Authors: - * Ben Smith (original glmark benchmark) - * Alexandros Frantzis (glmark2) - */ -#include "vector.h" - -Vector3f::Vector3f() -{ - x = 0.0f; y = 0.0f; z = 0.0f; -} - -Vector3f::Vector3f(GLfloat pX, GLfloat pY, GLfloat pZ) -{ - x = pX; y = pY; z = pZ; -} - -void Vector3f::display() -{ - printf("(%f, %f, %f)\n", x, y, z); -} - -float Vector3f::length() -{ - return sqrt(x * x + y * y + z * z); -} - -void Vector3f::normalize() -{ - GLfloat l = length(); - x /= l; y /= l; z /= l; -} - -Vector3f &Vector3f::operator=(const Vector3f &pV) -{ - x = pV.x; - y = pV.y; - z = pV.z; - return *this; -} - -Vector3f &Vector3f::operator+=(const Vector3f &pV) -{ - x += pV.x; - y += pV.y; - z += pV.z; - return *this; -} - -Vector3f &Vector3f::operator-=(const Vector3f &pV) -{ - x -= pV.x; - y -= pV.y; - z -= pV.z; - return *this; -} - -Vector3f &Vector3f::operator*=(float pF) -{ - x *= pF; - y *= pF; - z *= pF; - return *this; -} - -Vector3f &Vector3f::operator*=(double pF) -{ - x *= pF; - y *= pF; - z *= pF; - return *this; -} - -Vector3f &Vector3f::operator/=(float pF) -{ - x /= pF; - y /= pF; - z /= pF; - return *this; -} - -Vector3f operator+(const Vector3f &pA, const Vector3f &pB) -{ - Vector3f v = pA; - return v += pB; -} - -Vector3f operator-(const Vector3f &pA, const Vector3f &pB) -{ - Vector3f v = pA; - return v -= pB; -} - -Vector3f operator*(const Vector3f &pA, const float &pB) -{ - Vector3f v = pA; - return v *= pB; -} - -Vector3f operator/(const Vector3f &pA, const float &pB) -{ - Vector3f v = pA; - return v /= pB; -} - -Vector3f operator*(const Vector3f &pA, const double &pB) -{ - Vector3f v = pA; - return v *= pB; -} - -Vector3f cross(const Vector3f &pA, const Vector3f &pB) -{ - return Vector3f(pA.y * pB.z - pA.z * pB.y, - pA.z * pB.x - pA.x * pB.z, - pA.x * pB.y - pA.y * pB.x); -} - -float dot(const Vector3f &pA, const Vector3f &pB) -{ - return pA.x * pB.x + pA.y * pB.y + pA.z * pB.z; -} - -Vector3f normal(const Vector3f &pA, const Vector3f &pB, const Vector3f &pC) -{ - Vector3f n = cross(pB - pA, pC - pA); - n.normalize(); - return n; -} - === removed file 'src/vector.h' --- src/vector.h 2011-01-25 15:06:04 +0000 +++ src/vector.h 1970-01-01 00:00:00 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright © 2008 Ben Smith - * Copyright © 2010-2011 Linaro Limited - * - * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. - * - * glmark2 is free software: you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later - * version. - * - * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * glmark2. If not, see . - * - * Authors: - * Ben Smith (original glmark benchmark) - * Alexandros Frantzis (glmark2) - */ -#ifndef GLMARK2_VECTOR_H_ -#define GLMARK2_VECTOR_H_ - -#include "oglsdl.h" - -#include -#include - -class Vector3f -{ - union - { - struct { GLfloat x; GLfloat y; GLfloat z; }; - GLfloat v[3]; - }; - -public: - - Vector3f(); - Vector3f(GLfloat pX, GLfloat pY, GLfloat pZ); - - void display(); - float length(); - void normalize(); - - Vector3f &operator=(const Vector3f &pV); - Vector3f &operator+=(const Vector3f &pV); - Vector3f &operator-=(const Vector3f &pV); - Vector3f &operator*=(float pF); - Vector3f &operator/=(float pF); - Vector3f &operator*=(double pF); -}; - -extern Vector3f operator+(const Vector3f &pA, const Vector3f &pB); -extern Vector3f operator-(const Vector3f &pA, const Vector3f &pB); -extern Vector3f operator*(const Vector3f &pA, const float &pB); -extern Vector3f operator/(const Vector3f &pA, const float &pB); - -extern Vector3f operator*(const Vector3f &pA, const double &pB); - -extern float dot(const Vector3f &pA, const Vector3f &pB); -extern Vector3f cross(const Vector3f &pA, const Vector3f &pB); -extern Vector3f normal(const Vector3f &pA, const Vector3f &pB, const Vector3f &pC); - -#endif === modified file 'src/wscript_build' --- src/wscript_build 2011-01-25 00:59:11 +0000 +++ src/wscript_build 2011-06-17 13:09:21 +0000 @@ -2,19 +2,39 @@ common_sources = [f for f in all_sources if f.name.find('screen-') == -1] gl_sources = ['screen-sdl.cpp', 'screen-sdl-gl.cpp'] glesv2_sources = ['screen-sdl.cpp', 'screen-sdl-glesv2.cpp'] +libmatrix_sources = [f for f in bld.path.ant_glob('libmatrix/*.cc') + if not f.name.endswith('test.cc')] if bld.env.USE_GL: bld( + features = ['cxx', 'cxxstlib'], + source = libmatrix_sources, + target = 'matrix', + lib = ['m'], + includes = ['.'], + export_includes = 'libmatrix', + defines = ['USE_GL'] + ) + bld( features = ['cxx', 'cprogram'], source = common_sources + gl_sources, target = 'glmark2', - uselib = ['sdl', 'gl'], + use = ['sdl', 'gl', 'matrix'], lib = ['m'], defines = ['USE_GL'] ) if bld.env.USE_GLESv2: bld( + features = ['cxx', 'cxxstlib'], + source = libmatrix_sources, + target = 'matrix-es2', + lib = ['m'], + includes = ['.'], + export_includes = 'libmatrix', + defines = ['USE_GLESv2'] + ) + bld( features = ['c', 'cstlib'], source = bld.path.ant_glob('sdlgles/*.c'), target = 'sdlgles', @@ -24,8 +44,7 @@ features = ['cxx', 'cprogram'], source = common_sources + glesv2_sources, target = 'glmark2-es2', - uselib = ['sdl', 'glesv2'], - use = ['sdlgles'], + use = ['sdl', 'glesv2', 'sdlgles', 'matrix-es2'], lib = ['m', 'dl'], defines = ['USE_GLESv2'] )