- removed MD5 related classes as we will not support it after all.

This commit is contained in:
Mark Vejvoda
2012-07-31 16:49:31 +00:00
parent 61256fe999
commit 19937c7512
19 changed files with 0 additions and 10256 deletions

View File

@@ -1,281 +0,0 @@
// ==============================================================
// This file is part of MegaGlest (www.glest.org)
//
// ArbProgram.cpp -- Copyright (c) 2007 David Henry
// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda
//
// This code is licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license.php
//
// Open Source Initiative OSI - The MIT License (MIT):Licensing
//
// The MIT License (MIT)
// Copyright (c) <year> <copyright holders>
//
// 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.//
//
// Implementation of ARB program related classes.
//
/////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include "ArbProgram.h"
namespace Shared { namespace Graphics { namespace md5 {
using std::cout;
using std::cerr;
using std::endl;
/////////////////////////////////////////////////////////////////////////////
//
// Global ARB program related functions.
//
/////////////////////////////////////////////////////////////////////////////
static GLboolean ArbVpCapable = GL_FALSE;
static GLboolean ArbFpCapable = GL_FALSE;
// --------------------------------------------------------------------------
// hasArbVertexProgramSupport
// hasArbFragmentProgramSupport
//
// Return true if the host has ARB program support (vertex or fragment).
// --------------------------------------------------------------------------
GLboolean hasArbVertexProgramSupport () {
return ArbVpCapable;
}
GLboolean hasArbFragmentProgramSupport () {
return ArbFpCapable;
}
// --------------------------------------------------------------------------
// initArbProgramHandling
//
// Initialize variables and extensions needed for using ARB Programs.
// This function should be called before any shader usage (at application
// initialization for example).
// --------------------------------------------------------------------------
void initArbProgramHandling () {
// Check for extensions needed for ARB program support on host
ArbVpCapable = glewIsSupported ("GL_ARB_vertex_program");
ArbFpCapable = glewIsSupported ("GL_ARB_fragment_program");
if (!hasArbVertexProgramSupport ())
cerr << "* missing GL_ARB_vertex_program extension" << endl;
if (!hasArbFragmentProgramSupport ())
cerr << "* missing GL_ARB_fragment_program extension" << endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// class ArbProgram implementation.
//
/////////////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------------
// ArbProgram::ArbProgram
//
// Constructor.
// --------------------------------------------------------------------------
ArbProgram::ArbProgram (const string &filename)
: _name (filename), _handle (0), _fail (true) {
}
// --------------------------------------------------------------------------
// ArbProgram::~ArbProgram
//
// Destructor. Destroy the program handle.
// --------------------------------------------------------------------------
ArbProgram::~ArbProgram () {
if (glIsProgramARB (_handle))
glDeleteProgramsARB (1, &_handle);
}
// -------------------------------------------------------------------------
// ArbProgram::use
// ArbProgram::unuse
//
// Bind/unbind the program.
// -------------------------------------------------------------------------
void ArbProgram::use () const {
const GLenum target = programType ();
glEnable (target);
glBindProgramARB (target, _handle);
}
void ArbProgram::unuse () const {
const GLenum target = programType ();
glBindProgramARB (target, 0);
glDisable (target);
}
// -------------------------------------------------------------------------
// ArbProgram::printProgramString
//
// Print the ARB program string until a given position. This is
// usefull for printing code until error position.
// -------------------------------------------------------------------------
void ArbProgram::printProgramString (int errPos) {
int i = 0;
cerr << endl << " > ";
for (i = 0; i < (errPos + 1) && _code[i]; i++) {
cerr.put (_code[i]);
if (_code[i] == '\n')
cerr << " > ";
}
cerr << " <---" << endl << endl;
}
// -------------------------------------------------------------------------
// ArbProgram::load
//
// Create and load the program.
// -------------------------------------------------------------------------
void ArbProgram::load () throw (std::runtime_error) {
const GLchar *code = _code.c_str ();
const GLenum target = programType ();
// Generate a program object handle
glGenProgramsARB (1, &_handle);
// Make the "current" program object progid
glBindProgramARB (target, _handle);
// Specify the program for the current object
glProgramStringARB (target, GL_PROGRAM_FORMAT_ASCII_ARB,
_code.size (), code);
// Check for errors and warnings...
if (GL_INVALID_OPERATION == glGetError ()) {
const GLubyte *errString;
GLint errPos;
// Find the error position
glGetIntegerv (GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
// Print implementation-dependent program
// errors and warnings string
errString = glGetString (GL_PROGRAM_ERROR_STRING_ARB);
cerr << "Error in " << ((GL_VERTEX_PROGRAM_ARB == target) ?
"vertex" : "fragment");
cerr << " program at position: " << errPos << endl << errString;
printProgramString (errPos);
_fail = true;
throw std::runtime_error ("Compilation failed");
}
}
// -------------------------------------------------------------------------
// ArbProgram::loadProgramFile
//
// Load program's code from file. The code is stored into the
// _code string member variable.
// -------------------------------------------------------------------------
void ArbProgram::loadProgramFile (const string &filename) throw (std::runtime_error) {
// Open the file
std::ifstream ifs (filename.c_str (), std::ios::in | std::ios::binary);
if (ifs.fail ())
throw std::runtime_error ("Couldn't open prog file: " + filename);
// Read whole file into string
_code.assign (std::istreambuf_iterator<char>(ifs),
std::istreambuf_iterator<char>());
// Close file
ifs.close ();
}
/////////////////////////////////////////////////////////////////////////////
//
// class ArbVertexProgram implementation.
//
/////////////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------------
// ArbVertexProgram::ArbVertexProgram
//
// Constructor. Read vertex program code from file and load it.
// --------------------------------------------------------------------------
ArbVertexProgram::ArbVertexProgram (const string &filename) : ArbProgram (filename) {
try {
// Load program code from file
loadProgramFile (filename);
// load the program from code buffer
load ();
cout << "* Vertex program \"" << _name << "\" loaded" << endl;
}
catch (std::runtime_error &err) {
cerr << "Error: Faild to create vertex program from " << _name;
cerr << endl << "Reason: " << err.what () << endl;
}
}
/////////////////////////////////////////////////////////////////////////////
//
// class ArbFragmentProgram implementation.
//
/////////////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------------
// ArbFragmentProgram::ArbFragmentProgram
//
// Constructor. Read fragment program code from file and load it.
// --------------------------------------------------------------------------
ArbFragmentProgram::ArbFragmentProgram (const string &filename) : ArbProgram (filename) {
try {
// Load program code from file
loadProgramFile (filename);
// load the program from code buffer
load ();
cout << "* Fragment program \"" << _name << "\" loaded" << endl;
}
catch (std::runtime_error &err) {
cerr << "Error: Faild to create fragment program from " << _name;
cerr << endl << "Reason: " << err.what () << endl;
}
}
}}} //end namespace

View File

@@ -1,71 +0,0 @@
// ==============================================================
// This file is part of MegaGlest (www.glest.org)
//
// GlErrors.cpp -- Copyright (c) 2006-2007 David Henry
// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda
//
// This code is licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license.php
//
// Open Source Initiative OSI - The MIT License (MIT):Licensing
//
// The MIT License (MIT)
// Copyright (c) <year> <copyright holders>
//
// 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.//
//
// OpenGL error management.
//
/////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // _WIN32
#include <GL/glew.h>
#include <iostream>
#include "GlErrors.h"
namespace Shared { namespace Graphics { namespace md5 {
using std::cerr;
using std::endl;
// -------------------------------------------------------------------------
// checkOpenGLErrors
//
// Print the last OpenGL error code. @file is the filename where the
// function has been called, @line is the line number. You should use
// this function like this:
// checkOpenGLErrors (__FILE__, __LINE__);
// -------------------------------------------------------------------------
GLenum checkOpenGLErrors (const char *file, int line) {
GLenum errCode = glGetError ();
if (errCode != GL_NO_ERROR)
cerr << "(GL) " << file << " (" << line << "): "
<< gluErrorString (errCode) << endl;
return errCode;
}
}}} //end namespace

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,473 +0,0 @@
// ==============================================================
// This file is part of MegaGlest (www.glest.org)
//
// Shader.cpp -- Copyright (c) 2006-2007 David Henry
// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda
//
// This code is licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license.php
//
// Open Source Initiative OSI - The MIT License (MIT):Licensing
//
// The MIT License (MIT)
// Copyright (c) <year> <copyright holders>
//
// 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.//
//
// Implementation of GLSL shader related classes.
//
/////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include "ShaderManager.h"
#include "GlErrors.h"
namespace Shared { namespace Graphics { namespace md5 {
using std::cout;
using std::cerr;
using std::endl;
/////////////////////////////////////////////////////////////////////////////
//
// Global shader related functions.
//
/////////////////////////////////////////////////////////////////////////////
static GLboolean GLSLCapable = GL_FALSE;
// --------------------------------------------------------------------------
// hasShaderSupport
//
// Return true if the host has GLSL, so that we can use shaders.
// --------------------------------------------------------------------------
GLboolean hasShaderSupport () {
return GLSLCapable;
}
// --------------------------------------------------------------------------
// checkExtensionPresence
//
// Check if an extension is present on the host OpenGL implementation.
// Increment @missing if the extension is missing.
// --------------------------------------------------------------------------
static void checkExtensionPresence (const string &name, int &missing) {
if (!glewIsSupported (name.c_str ()))
{
cerr << "* missing " << name << " extension" << endl;
missing++;
}
}
// --------------------------------------------------------------------------
// initShaderHandling
//
// Initialize variables and extensions needed for using GLSL. This
// function should be called before any shader usage (at application
// initialization for example).
// --------------------------------------------------------------------------
void initShaderHandling () {
int missing = 0;
// Check for extensions needed for GLSL support on host
checkExtensionPresence ("GL_ARB_shader_objects", missing);
checkExtensionPresence ("GL_ARB_shading_language_100", missing);
checkExtensionPresence ("GL_ARB_vertex_shader", missing);
checkExtensionPresence ("GL_ARB_fragment_shader", missing);
// Disable GLSL if one extension is missing
if (missing > 0)
GLSLCapable = GL_FALSE;
else
GLSLCapable = GL_TRUE;
}
/////////////////////////////////////////////////////////////////////////////
//
// class Shader implementation.
//
/////////////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------------
// Shader::Shader
//
// Constructor.
// --------------------------------------------------------------------------
Shader::Shader (const string &filename)
: _name (filename), _handle (0), _compiled (0) {
}
// --------------------------------------------------------------------------
// Shader::~Shader
//
// Destructor. Destroy the shader handle.
// --------------------------------------------------------------------------
Shader::~Shader () {
if (GLEW_VERSION_2_0)
{
if (glIsShader (_handle))
glDeleteShader (_handle);
}
else
{
GLint type;
glGetObjectParameterivARB (_handle, GL_OBJECT_TYPE_ARB, &type);
if (GL_SHADER_OBJECT_ARB == type)
glDeleteObjectARB (_handle);
}
}
// -------------------------------------------------------------------------
// Shader::printInfoLog
//
// Print log info about a vertex or a fragment shader.
// -------------------------------------------------------------------------
void Shader::printInfoLog () const {
GLint infologLength = 0;
// First check for previous OpenGL errors...
checkOpenGLErrors (__FILE__, __LINE__);
// Get log's length
if (GLEW_VERSION_2_0)
glGetShaderiv (_handle, GL_INFO_LOG_LENGTH, &infologLength);
else
glGetObjectParameterivARB (_handle, GL_OBJECT_INFO_LOG_LENGTH_ARB,
&infologLength);
// If log is empty, quit
if (infologLength <= 1)
return;
try
{
GLchar *infoLog = new GLchar[infologLength];
// Get the log...
if (GLEW_VERSION_2_0)
glGetShaderInfoLog (_handle, infologLength, NULL, infoLog);
else
glGetInfoLogARB (_handle, infologLength, NULL, infoLog);
// ...and print it to standard output
cout << "Shader \"" << _name << "\" InfoLog ("
<< infologLength << "):" << endl << infoLog << endl;
delete [] infoLog;
}
catch (std::bad_alloc &err)
{
cerr << "Error: memory allocation failed for shader info log"
<< endl << " Reason: " << err.what () << endl;
}
}
// -------------------------------------------------------------------------
// Shader::compile
//
// Create and compile the shader.
// -------------------------------------------------------------------------
void Shader::compile ()
throw (std::runtime_error) {
const GLchar *code = _code.c_str ();
if (GLEW_VERSION_2_0)
{
// Create a shader object
_handle = glCreateShader (shaderType ());
// Upload shader code to OpenGL
glShaderSource (_handle, 1, &code, NULL);
// Compile shader
glCompileShader (_handle);
glGetShaderiv (_handle, GL_COMPILE_STATUS, &_compiled);
printInfoLog ();
// Check for success
if (GL_FALSE == _compiled)
throw std::runtime_error ("Compilation failed");
}
else
{
// Create a shader object
_handle = glCreateShaderObjectARB (shaderType ());
// Upload shader code to OpenGL
glShaderSourceARB (_handle, 1, &code, NULL);
// Compile shader
glCompileShaderARB (_handle);
glGetObjectParameterivARB (_handle, GL_OBJECT_COMPILE_STATUS_ARB, &_compiled);
printInfoLog ();
// Check for success
if (GL_FALSE == _compiled)
throw std::runtime_error ("Compilation failed");
}
}
// -------------------------------------------------------------------------
// Shader::loadShaderFile
//
// Load shader's GLSL code from file. The code is stored into the
// _code string member variable.
// -------------------------------------------------------------------------
void Shader::loadShaderFile (const string &filename) throw (std::runtime_error) {
// Open the file
std::ifstream ifs (filename.c_str (), std::ios::in | std::ios::binary);
if (ifs.fail ())
throw std::runtime_error ("Couldn't open shader file: " + filename);
// Read whole file into string
_code.assign (std::istreambuf_iterator<char>(ifs),
std::istreambuf_iterator<char>());
// Close file
ifs.close ();
}
/////////////////////////////////////////////////////////////////////////////
//
// class VertexShader implementation.
//
/////////////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------------
// VertexShader::VertexShader
//
// Constructor. Read vertex shader code from file and compile it.
// --------------------------------------------------------------------------
VertexShader::VertexShader (const string &filename)
: Shader (filename) {
try
{
// Load shader code from file
loadShaderFile (filename);
// Compile the shader
compile ();
cout << "* Vertex shader \"" << _name << "\" compiled" << endl;
}
catch (std::runtime_error &err)
{
cerr << "Error: Faild to create vertex shader from " << _name << endl;
cerr << "Reason: " << err.what () << endl;
}
}
/////////////////////////////////////////////////////////////////////////////
//
// class FragmentShader implementation.
//
/////////////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------------
// FragmentShader::FragmentShader
//
// Constructor. Read fragment shader code from file and compile it.
// --------------------------------------------------------------------------
FragmentShader::FragmentShader (const string &filename)
: Shader (filename) {
try
{
// Load shader code from file
loadShaderFile (filename);
// Compile the shader
compile ();
cout << "* Fragment shader \"" << _name << "\" compiled" << endl;
}
catch (std::runtime_error &err)
{
cerr << "Error: Faild to create fragment shader from " << _name << endl;
cerr << "Reason: " << err.what () << endl;
}
}
/////////////////////////////////////////////////////////////////////////////
//
// class ShaderProgram implementation.
//
/////////////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------------
// ShaderProgram::ShaderProgram
//
// Constructor. Link vertex and fragment shader. If the vertex shader
// or the fragment shader is invalid (has failed to compile), the
// shader program creation is aborted.
// --------------------------------------------------------------------------
ShaderProgram::ShaderProgram (const string &filename,
const VertexShader &vertexShader,
const FragmentShader &fragmentShader)
: _name (filename), _handle (0), _linked (0) {
try {
if (vertexShader.fail ())
throw std::runtime_error ("Invalid vertex shader");
if (fragmentShader.fail ())
throw std::runtime_error ("Invalid fragment shader");
if (GLEW_VERSION_2_0)
{
// Create program and attach vertex and fragment shaders
_handle = glCreateProgram ();
glAttachShader (_handle, vertexShader.handle ());
glAttachShader (_handle, fragmentShader.handle ());
// Perform link stage
glLinkProgram (_handle);
glGetProgramiv (_handle, GL_LINK_STATUS, &_linked);
// Validate program
glValidateProgram (_handle);
printInfoLog ();
// Check for success
if (GL_FALSE == _linked)
throw std::runtime_error ("Link stage failed");
}
else
{
// Create program and attach vertex and fragment shaders
_handle = glCreateProgramObjectARB ();
glAttachObjectARB (_handle, vertexShader.handle ());
glAttachObjectARB (_handle, fragmentShader.handle ());
// Perform link stage
glLinkProgramARB (_handle);
glGetObjectParameterivARB (_handle, GL_OBJECT_LINK_STATUS_ARB, &_linked);
// Validate program
glValidateProgramARB (_handle);
printInfoLog ();
// Check for success
if (GL_FALSE == _linked)
throw std::runtime_error ("Link stage failed");
}
cout << "* Shader \"" << _name << "\" successfully linked" << endl;
}
catch (std::runtime_error &err)
{
cerr << "Error: Faild to create shader " << _name << endl;
cerr << "Reason: " << err.what () << endl;
}
}
// --------------------------------------------------------------------------
// ShaderProgram::~ShaderProgram
//
// Destructor. Destroy the shader program handle.
// --------------------------------------------------------------------------
ShaderProgram::~ShaderProgram () {
if (GLEW_VERSION_2_0)
{
if (glIsProgram (_handle))
glDeleteProgram (_handle);
}
else
{
GLint type;
glGetObjectParameterivARB (_handle, GL_OBJECT_TYPE_ARB, &type);
if (GL_PROGRAM_OBJECT_ARB == type)
glDeleteObjectARB (_handle);
}
}
// -------------------------------------------------------------------------
// ShaderProgram::use
// ShaderProgram::unuse
//
// Bind/unbind the shader.
// -------------------------------------------------------------------------
void ShaderProgram::use () const {
if (GLEW_VERSION_2_0)
glUseProgram (_handle);
else
glUseProgramObjectARB (_handle);
}
void ShaderProgram::unuse () const {
if (GLEW_VERSION_2_0)
glUseProgram (0);
else
glUseProgramObjectARB (0);
}
// -------------------------------------------------------------------------
// ShaderProgram::printInfoLog
//
// Print log info about a shader program.
// -------------------------------------------------------------------------
void ShaderProgram::printInfoLog () const {
GLint infologLength = 0;
// First check for previous OpenGL errors...
checkOpenGLErrors (__FILE__, __LINE__);
// Get log's length
if (GLEW_VERSION_2_0)
glGetProgramiv (_handle, GL_INFO_LOG_LENGTH, &infologLength);
else
glGetObjectParameterivARB (_handle, GL_OBJECT_INFO_LOG_LENGTH_ARB,
&infologLength);
// If log is empty, quit
if (infologLength <= 1)
return;
try
{
GLchar *infoLog = new GLchar[infologLength];
// Get the log...
if (GLEW_VERSION_2_0)
glGetProgramInfoLog (_handle, infologLength, NULL, infoLog);
else
glGetInfoLogARB (_handle, infologLength, NULL, infoLog);
// ...and print it to standard output
cout << "Program \"" << _name << "\" InfoLog ("
<< infologLength << "):" << endl << infoLog << endl;
delete [] infoLog;
}
catch (std::bad_alloc &err)
{
cerr << "Error: memory allocation failed for shader program "
<< "info log" << endl << " Reason: " << err.what () << endl;
}
}
}}} //end namespace

View File

@@ -1,536 +0,0 @@
// ==============================================================
// This file is part of MegaGlest (www.glest.org)
//
// Texture.cpp -- Copyright (c) 2006 David Henry
// changed for use with MegaGlest: Copyright (C) 2011- by Mark Vejvoda
//
// This code is licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license.php
//
// Open Source Initiative OSI - The MIT License (MIT):Licensing
//
// The MIT License (MIT)
// Copyright (c) <year> <copyright holders>
//
// 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.//
//
// Implementation of an OpenGL texture classes.
//
/////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // _WIN32
#include <GL/glew.h>
#include <iostream>
#include <stdexcept>
#include "GlErrors.h"
#include "md5Texture.h"
#include "Image.h"
namespace Shared { namespace Graphics { namespace md5 {
using std::cout;
using std::cerr;
using std::endl;
using std::max;
/////////////////////////////////////////////////////////////////////////////
//
// class Texture implementation.
//
/////////////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------------
// Texture::Texture
//
// Constructor.
// --------------------------------------------------------------------------
Texture::Texture ()
: _handle (0), _flags (kDefault),
_standardCoordSystem (true), _fail (true) {
// Inhibit possible previous OpenGL error
checkOpenGLErrors (__FILE__, __LINE__);
}
// --------------------------------------------------------------------------
// Texture::~Texture
//
// Destructor. Delete texture object.
// --------------------------------------------------------------------------
Texture::~Texture () {
// Delete texture object
if (glIsTexture(_handle))
glDeleteTextures (1, &_handle);
}
// --------------------------------------------------------------------------
// Texture::bind
//
// Bind texture to the active texture unit.
// --------------------------------------------------------------------------
void Texture::bind () const {
glBindTexture (target (), _handle);
}
void Texture::bind (GLenum texUnit) const {
glActiveTexture (texUnit);
glBindTexture (target (), _handle);
}
// --------------------------------------------------------------------------
// Texture::getCompressionFormat
//
// Return the corresponding format for a compressed image given
// image's internal format (pixel components).
// --------------------------------------------------------------------------
GLint Texture::getCompressionFormat (GLint internalFormat) {
if (!GLEW_EXT_texture_compression_s3tc ||
!GLEW_ARB_texture_compression)
// No compression possible on this target machine
return internalFormat;
switch (internalFormat)
{
case 1:
return GL_COMPRESSED_LUMINANCE;
case 2:
return GL_COMPRESSED_LUMINANCE_ALPHA;
case 3:
return GL_COMPRESSED_RGB;
case 4:
return GL_COMPRESSED_RGBA;
default:
// Error!
throw std::invalid_argument ("Texture::getCompressionFormat: "
"Bad internal format");
}
}
// --------------------------------------------------------------------------
// Texture::getInternalFormat
//
// Return texture's internal format depending to whether compression
// is used or not.
// --------------------------------------------------------------------------
GLint Texture::getInternalFormat (GLint components) {
if (_flags & kCompress)
return getCompressionFormat (components);
else
return components;
}
/////////////////////////////////////////////////////////////////////////////
//
// class Texture2D implementation.
//
/////////////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------------
// Texture2D::Texture2D
//
// Constructors. Try to load a texture 2D. Don't throw any exception
// if it fails to create the texture; the program can still run whithout
// textures.
// --------------------------------------------------------------------------
Texture2D::Texture2D () : Texture () {
}
Texture2D::Texture2D (const string &filename, TextureFlags flags) {
try
{
// Load image file into a buffer
ImageBuffer ibuff (filename);
auto_ptr<Image> img (ImageFactory::createImage (ibuff));
// Create texture from image buffer
create (img.get (), flags);
}
catch (std::exception &err)
{
cerr << "Error: Couldn't create texture 2D from " << filename
<< endl << "Reason: " << err.what () << endl;
}
}
Texture2D::Texture2D (const Image *img, TextureFlags flags)
{
try
{
// Create texture from image buffer
create (img, flags);
}
catch (std::exception &err)
{
cerr << "Error: Couldn't create texture 2D from " << img->name ()
<< endl << "Reason: " << err.what () << endl;
}
}
// --------------------------------------------------------------------------
// Texture2D::create
//
// Create a texture 2D from an image.
// --------------------------------------------------------------------------
void
Texture2D::create (const Image *img, TextureFlags flags)
{
if (!img->pixels ())
throw std::runtime_error ("Invalid image data");
// Fill texture's vars
_name = img->name ();
_flags = flags;
_standardCoordSystem = img->stdCoordSystem ();
// Generate a texture name
glGenTextures (1, &_handle);
glBindTexture (target (), _handle);
// Setup texture filters
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (img->isCompressed ())
{
// Image use S3 compression. Only S3TC DXT1, DXT3
// and DXT5 formats are supported.
GLsizei mipWidth = img->width ();
GLsizei mipHeight = img->height ();
int offset = 0;
int blockSize = (img->format () == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
// Upload mipmaps to video memory
for (GLint mipLevel = 0; mipLevel < img->numMipmaps (); ++mipLevel)
{
GLsizei mipSize = ((mipWidth + 3) / 4) * ((mipHeight + 3) / 4) * blockSize;
glCompressedTexImage2D (GL_TEXTURE_2D, mipLevel, img->format (),
mipWidth, mipHeight, 0, mipSize,
img->pixels () + offset);
mipWidth = max (mipWidth >> 1, 1);
mipHeight = max (mipHeight >> 1, 1);
offset += mipSize;
}
}
else
{
// Build the texture and generate mipmaps
if (GLEW_SGIS_generate_mipmap && img->isPowerOfTwo ())
{
// Hardware mipmap generation
glTexParameteri (GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
glHint (GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
glTexImage2D (GL_TEXTURE_2D, 0, getInternalFormat (img->components ()),
img->width (), img->height (), 0, img->format (),
GL_UNSIGNED_BYTE, img->pixels ());
}
else
{
// No hardware mipmap generation support, fall back to the
// good old gluBuild2DMipmaps function
gluBuild2DMipmaps (GL_TEXTURE_2D, getInternalFormat (img->components ()),
img->width (), img->height (), img->format (),
GL_UNSIGNED_BYTE, img->pixels ());
}
}
// Does texture creation succeeded?
if (GL_NO_ERROR == checkOpenGLErrors (__FILE__, __LINE__))
_fail = false;
}
/////////////////////////////////////////////////////////////////////////////
//
// class TextureRectangle implementation.
//
/////////////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------------
// TextureRectangle::TextureRectangle
//
// Constructors. Try to load a texture rectangle. Don't throw any
// exception if it fails to create the texture; the program can still
// run whithout textures.
// --------------------------------------------------------------------------
TextureRectangle::TextureRectangle (const string &filename, TextureFlags flags)
: _width (0), _height (0)
{
try
{
// Check if is not a DDS image
if (filename.find (".dds") != string::npos)
throw ImageException ("Compressed textures are not supported for"
" texture rectangles!", filename);
// Load image file into a buffer
ImageBuffer ibuff (filename);
auto_ptr<Image> img (ImageFactory::createImage (ibuff));
// Create texture from image buffer
create (img.get (), flags);
}
catch (std::exception &err)
{
cerr << "Error: Couldn't create texture rectangle from "
<< filename << endl << "Reason: " << err.what () << endl;
}
}
TextureRectangle::TextureRectangle (const Image *img, TextureFlags flags)
: _width (0), _height (0)
{
try
{
// Check if is not a compressed DDS image
if (img->isCompressed ())
throw ImageException ("Compressed textures are not supported for"
" texture rectangles!", img->name ());
// Create texture from image buffer
create (img, flags);
}
catch (std::exception &err)
{
cerr << "Error: Couldn't create texture rectangle from "
<< img->name () << endl << "Reason: " << err.what () << endl;
}
}
// --------------------------------------------------------------------------
// TextureRectangle::create
//
// Create a texture rectangle from an image. No mipmap
// filtering is permitted for texture rectangles.
// --------------------------------------------------------------------------
void
TextureRectangle::create (const Image *img, TextureFlags flags)
{
if (!img->pixels ())
throw std::runtime_error ("Invalid image data");
// Get image info
_standardCoordSystem = img->stdCoordSystem ();
_width = img->width ();
_height = img->height ();
_name = img->name ();
_flags = flags;
// Generate a texture name
glGenTextures (1, &_handle);
glBindTexture (target (), _handle);
// Setup texture filters
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Create texture from image
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
getInternalFormat (img->components ()),
img->width (), img->height (), 0, img->format (),
GL_UNSIGNED_BYTE, img->pixels ());
// Does texture creation succeeded?
if (GL_NO_ERROR == checkOpenGLErrors (__FILE__, __LINE__))
_fail = false;
}
/////////////////////////////////////////////////////////////////////////////
//
// class TextureCubeMap implementation.
//
/////////////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------------
// TextureCubeMap::TextureCubeMap
//
// Constructors. Try to load a texture cube map. Don't throw any
// exception if it fails to create the texture; the program can still
// run whithout textures.
// --------------------------------------------------------------------------
TextureCubeMap::TextureCubeMap (const string &basename, const vector<string> &files,
TextureFlags flags)
{
try
{
_name = basename;
vector<ImagePtr> faces;
faces.reserve(6);
// Load images
for (int i = 0; i < 6; ++i)
{
ImageBuffer ibuff (files[i]);
faces.push_back (ImagePtr (ImageFactory::createImage (ibuff)));
}
// Create texture from faces
create (faces, flags);
}
catch (ImageException &err)
{
cerr << "Error: Couldn't create texture cube map from " << basename << endl;
cerr << "Reason: " << err.what () << " (" << err.which () << ")" << endl;
}
catch (std::exception &err)
{
cerr << "Error: Couldn't create texture cube map from " << basename << endl;
cerr << "Reason: " << err.what () << endl;
}
}
TextureCubeMap::TextureCubeMap (const string &basename, const vector<ImagePtr> &faces,
TextureFlags flags)
{
try
{
_name = basename;
// Create texture from image buffer
create (faces, flags);
}
catch (ImageException &err)
{
cerr << "Error: Couldn't create texture cube map from " << basename << endl;
cerr << "Reason: " << err.what () << " (" << err.which () << ")" << endl;
}
catch (std::exception &err)
{
cerr << "Error: Couldn't create texture cube map from " << basename << endl;
cerr << "Reason: " << err.what () << endl;
}
}
// --------------------------------------------------------------------------
// TextureCubeMap::create
//
// Create a cube map texture from images.
// --------------------------------------------------------------------------
void
TextureCubeMap::create (const vector<ImagePtr> &faces, TextureFlags flags)
{
// Create a list of image buffers and associate a target
// for each one
typedef map<const Image*, GLenum> TexTarget;
typedef TexTarget::value_type TexPair;
TexTarget texImages;
texImages.insert (TexPair (faces[0].get(), GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB));
texImages.insert (TexPair (faces[1].get(), GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB));
texImages.insert (TexPair (faces[2].get(), GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB));
texImages.insert (TexPair (faces[3].get(), GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB));
texImages.insert (TexPair (faces[4].get(), GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB));
texImages.insert (TexPair (faces[5].get(), GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB));
_standardCoordSystem = faces[0]->stdCoordSystem ();
_flags = flags;
// Generate a texture name
glGenTextures (1, &_handle);
glBindTexture (GL_TEXTURE_CUBE_MAP_ARB, _handle);
// Setup texture filters
glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// Load each side of the cube
for (TexTarget::iterator itor = texImages.begin ();
itor != texImages.end (); ++itor)
{
// Get image data
const Image *img = itor->first;
if (!img->pixels ())
throw std::runtime_error ("Invalid image data");
if (img->isCompressed ())
{
// Image use S3 compression
GLsizei mipWidth = img->width ();
GLsizei mipHeight = img->height ();
int offset = 0;
int blockSize =
(img->format () == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
// Upload mipmaps to video memory
for (GLint mipLevel = 0; mipLevel < img->numMipmaps (); ++mipLevel)
{
GLsizei mipSize = ((mipWidth + 3) / 4) *
((mipHeight + 3) / 4) * blockSize;
glCompressedTexImage2D (itor->second, mipLevel, img->format (),
mipWidth, mipHeight, 0, mipSize,
img->pixels () + offset);
mipWidth = max (mipWidth >> 1, 1);
mipHeight = max (mipHeight >> 1, 1);
offset += mipSize;
}
}
else
{
// No hardware mipmap generation support for texture cube
// maps, use gluBuild2DMipmaps function instead
gluBuild2DMipmaps (itor->second, getInternalFormat (img->components ()),
img->width (), img->height (), img->format (),
GL_UNSIGNED_BYTE, img->pixels ());
}
}
// Does texture creation succeeded?
if (GL_NO_ERROR == checkOpenGLErrors (__FILE__, __LINE__))
_fail = false;
}
}}} //end namespace

View File

@@ -1,591 +0,0 @@
// ==============================================================
// This file is part of MegaGlest (www.glest.org)
//
// Copyright (C) 2011- by Mark Vejvoda
//
// This code is licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license.php
//
// Open Source Initiative OSI - The MIT License (MIT):Licensing
//
// The MIT License (MIT)
// Copyright (c) <year> <copyright holders>
//
// 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.//
//
// ==============================================================
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <string>
#include <GL/glew.h>
#include "GlErrors.h"
#include "Mathlib.h"
#include "Md5Model.h"
#include "TextureManager.h"
#include "ArbProgram.h"
#include "ShaderManager.h"
#include "md5util.h"
namespace Shared { namespace Graphics { namespace md5 {
using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::vector;
// All vertex and fragment programs
ArbVertexProgram *vp_bump = NULL;
ArbVertexProgram *vp_bump_parallax = NULL;
ArbFragmentProgram *fp_diffuse = NULL;
ArbFragmentProgram *fp_diffuse_specular = NULL;
ArbFragmentProgram *fp_ds_parallax = NULL;
// Tangent uniform's location
GLint tangentLoc = -1;
int renderFlags = Md5Object::kDrawModel;
bool bAnimate = true;
bool bTextured = true;
bool bCullFace = true;
bool bBounds = false;
bool bParallax = false;
bool bLight = true;
bool bSmooth = true;
bool bWireframe = false;
bool bDrawNormals = false;
vector<string> animations;
// Camera
Vector3f rot, eye;
// -------------------------------------------------------------------------
// cleanupMD5OpenGL
//
// Application cleanup.
// -------------------------------------------------------------------------
void cleanupMD5OpenGL() {
//delete model;
//delete object;
//delete font;
//delete shader;
delete Md5Model::shader;
Md5Model::shader=NULL;
delete vp_bump;
delete vp_bump_parallax;
delete fp_diffuse;
delete fp_diffuse_specular;
delete fp_ds_parallax;
Texture2DManager::kill ();
}
// -------------------------------------------------------------------------
// initShader
//
// Shader's uniform variables initialization.
// -------------------------------------------------------------------------
void initShader () {
if (NULL == Md5Model::shader)
return;
Md5Model::shader->use();
if (GLEW_VERSION_2_0) {
GLuint prog = Md5Model::shader->handle ();
// Set uniform parameters
glUniform1i (glGetUniformLocation (prog, "decalMap"), 0);
glUniform1i (glGetUniformLocation (prog, "glossMap"), 1);
glUniform1i (glGetUniformLocation (prog, "normalMap"), 2);
glUniform1i (glGetUniformLocation (prog, "heightMap"), 3);
glUniform1i (glGetUniformLocation (prog, "parallaxMapping"), bParallax);
// Get attribute location
Md5Model::tangentLoc = glGetAttribLocation (prog, "tangent");
}
else {
GLhandleARB prog = Md5Model::shader->handle();
// Set uniform parameters
glUniform1iARB (glGetUniformLocationARB (prog, "decalMap"), 0);
glUniform1iARB (glGetUniformLocationARB (prog, "glossMap"), 1);
glUniform1iARB (glGetUniformLocationARB (prog, "normalMap"), 2);
glUniform1iARB (glGetUniformLocationARB (prog, "heightMap"), 3);
glUniform1iARB (glGetUniformLocationARB (prog, "parallaxMapping"), bParallax);
// Get attribute location
Md5Model::tangentLoc = glGetAttribLocationARB (prog, "tangent");
}
Md5Model::shader->unuse();
// Warn ff we fail to get tangent location... We'll can still use
// the shader, but without tangents
if(Md5Model::tangentLoc == -1)
cerr << "Warning! No \"tangent\" uniform found in shader!" << endl;
}
// -------------------------------------------------------------------------
// announceRenderPath
//
// Print info about a render path.
// -------------------------------------------------------------------------
void announceRenderPath (render_path_e path) {
cout << "Render path: ";
switch (path)
{
case R_normal:
cout << "no bump mapping (fixed pipeline)" << endl;
break;
case R_ARBfp_diffuse:
cout << "bump mapping, diffuse only "
<< "(ARB vp & fp)" << endl;
break;
case R_ARBfp_diffuse_specular:
cout << "bump mapping, diffuse and specular "
<< "(ARB vp & fp)" << endl;
break;
case R_ARBfp_ds_parallax:
cout << "bump mapping with parallax "
<< "(ARB fp & fp)" << endl;
break;
case R_shader:
cout << "bump mapping with parallax "
<< "(GLSL)" << endl;
break;
}
}
// -------------------------------------------------------------------------
// initMD5OpenGL
//
// OpenGL initialization.
// -------------------------------------------------------------------------
void initMD5OpenGL(string shaderPath) {
//glClearColor (0.5f, 0.5f, 0.5f, 0.0f);
//glShadeModel (GL_SMOOTH);
//glCullFace (GL_BACK);
//glEnable (GL_DEPTH_TEST);
// Initialize GLEW
GLenum err = glewInit ();
if(GLEW_OK != err) {
// Problem: glewInit failed, something is seriously wrong.
cerr << "Error: " << glewGetErrorString (err) << endl;
cleanupMD5OpenGL();
}
// Print some infos about user's OpenGL implementation
cout << "OpenGL Version String: " << glGetString (GL_VERSION) << endl;
cout << "GLU Version String: " << gluGetString (GLU_VERSION) << endl;
cout << "GLEW Version String: " << glewGetString (GLEW_VERSION) << endl;
// Initialize ARB vertex/fragment program support
initArbProgramHandling();
// Initialize GLSL shader support
initShaderHandling();
if(hasArbVertexProgramSupport () &&
hasArbFragmentProgramSupport ()) {
// Load ARB programs
vp_bump = new ArbVertexProgram(shaderPath + "bump.vp");
vp_bump_parallax = new ArbVertexProgram(shaderPath + "bumpparallax.vp");
fp_diffuse = new ArbFragmentProgram(shaderPath + "bumpd.fp");
fp_diffuse_specular = new ArbFragmentProgram(shaderPath + "bumpds.fp");
fp_ds_parallax = new ArbFragmentProgram(shaderPath + "bumpdsp.fp");
// Current ARB programs will be bump mapping with diffuse
// and specular components
Md5Model::vp = vp_bump;
Md5Model::fp = fp_diffuse_specular;
}
if(hasShaderSupport ()) {
// Load shader
VertexShader vs(shaderPath + "bump.vert");
FragmentShader fs(shaderPath + "bump.frag");
Md5Model::shader = new ShaderProgram(shaderPath + "bump mapping", vs, fs);
// Initialize shader's uniforms
initShader();
}
// Announce avalaible render paths, select the best
cout << endl << "Available render paths:" << endl;
cout << " [F3] - No bump mapping (fixed pipeline)" << endl;
Md5Model::renderPath = R_normal;
if (vp_bump && fp_diffuse) {
cout << " [F4] - Bump mapping, diffuse only "
<< "(ARB vp & fp)" << endl;
Md5Model::renderPath = R_ARBfp_diffuse;
}
if (vp_bump && fp_diffuse_specular) {
cout << " [F5] - Bump mapping, diffuse and specular "
<< "(ARB vp & fp)" << endl;
Md5Model::renderPath = R_ARBfp_diffuse_specular;
}
if (vp_bump_parallax && fp_ds_parallax) {
cout << " [F6] - Bump mapping with parallax "
<< "(ARB vp & fp)" << endl;
}
if (Md5Model::shader) {
cout << " [F7] - Bump mapping with parallax "
<< "(GLSL)" << endl;
Md5Model::renderPath = R_shader;
}
// Announce which path has been chosen by default
cout << endl;
announceRenderPath(Md5Model::renderPath);
checkOpenGLErrors (__FILE__, __LINE__);
}
// -------------------------------------------------------------------------
// extractFromQuotes
//
// Extract a string from quotes.
// -------------------------------------------------------------------------
inline const string extractFromQuotes (const string &str) {
string::size_type start = str.find_first_of ('\"') + 1;
string::size_type end = str.find_first_of ('\"', start) - 2;
return str.substr (start, end);
}
// -------------------------------------------------------------------------
// getMD5ObjectFromLoaderScript
//
// Parse a script file for loading md5mesh and animations.
// -------------------------------------------------------------------------
Md5Object * getMD5ObjectFromLoaderScript(const string &filename) {
// Open the file to parse
std::ifstream file (filename.c_str(), std::ios::in);
if (file.fail ()) {
cerr << "Couldn't open " << filename << endl;
cleanupMD5OpenGL();
}
// Get texture manager
Texture2DManager *texMgr = Texture2DManager::getInstance();
Md5Model *model = NULL;
Md5Object *object = NULL;
while (!file.eof ()) {
string token, buffer;
string meshFile, animFile, textureFile;
string meshName, animName;
// Peek next token
file >> token;
if (token == "model") {
std::getline (file, buffer);
meshFile = extractFromQuotes (buffer);
// Delete previous model and object if existing
delete model;
delete object;
// Load mesh model
model = new Md5Model(meshFile);
object = new Md5Object(model);
}
else if (token == "anim") {
std::getline (file, buffer);
animFile = extractFromQuotes (buffer);
try {
// Load animation
if (model) {
model->addAnim(animFile);
}
}
catch (Md5Exception &err) {
cerr << "Failed to load animation "
<< animFile << endl;
cerr << "Reason: " << err.what ()
<< " (" << err.which () << ")" << endl;
}
}
else if (token == "hide") {
std::getline (file, buffer);
meshName = extractFromQuotes (buffer);
// Set mesh's render state
if (model) {
model->setMeshRenderState (meshName, Md5Mesh::kHide);
}
}
else if ((token == "decalMap") ||
(token == "specularMap") ||
(token == "normalMap") ||
(token == "heightMap")) {
// Get the next token and extract the mesh name
file >> buffer;
long start = buffer.find_first_of ('\"') + 1;
long end = buffer.find_first_of ('\"', start) - 1;
meshName = buffer.substr (start, end);
// Get the rest of line and extract texture's filename
std::getline (file, buffer);
textureFile = extractFromQuotes (buffer);
// If the model has been loaded, setup
// the texture to the desired mesh
if (model) {
Texture2D *tex = texMgr->load (textureFile);
if (tex->fail ())
cerr << "failed to load " << textureFile << endl;
if (token == "decalMap")
model->setMeshDecalMap (meshName, tex);
else if (token == "specularMap")
model->setMeshSpecularMap (meshName, tex);
else if (token == "normalMap")
model->setMeshNormalMap (meshName, tex);
else if (token == "heightMap")
model->setMeshHeightMap (meshName, tex);
}
}
else if (token == "setAnim") {
std::getline (file, buffer);
animName = extractFromQuotes (buffer);
// Set object's default animation
object->setAnim (animName);
}
}
file.close ();
if (!model || !object)
throw Md5Exception ("No mesh found!", filename);
return object;
}
// -------------------------------------------------------------------------
// setupLight
//
// Setup light position and enable light0.
// -------------------------------------------------------------------------
void setupLight(GLfloat x, GLfloat y, GLfloat z) {
GLfloat lightPos[4];
lightPos[0] = x;
lightPos[1] = y;
lightPos[2] = z;
lightPos[3] = 1.0f;
glDisable (GL_LIGHTING);
glDisable (GL_LIGHT0);
if (bLight)
{
glPushMatrix ();
glLoadIdentity ();
glLightfv (GL_LIGHT0, GL_POSITION, lightPos);
glPopMatrix ();
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
}
}
// -------------------------------------------------------------------------
// drawObb
//
// Draw an Oriented Bouding Box.
// -------------------------------------------------------------------------
void drawObb(const OBBox_t &obb) {
Vector3f corners[8];
corners[0] = Vector3f (-obb.extent._x, -obb.extent._y, -obb.extent._z);
corners[1] = Vector3f ( obb.extent._x, -obb.extent._y, -obb.extent._z);
corners[2] = Vector3f ( obb.extent._x, obb.extent._y, -obb.extent._z);
corners[3] = Vector3f (-obb.extent._x, obb.extent._y, -obb.extent._z);
corners[4] = Vector3f (-obb.extent._x, -obb.extent._y, obb.extent._z);
corners[5] = Vector3f ( obb.extent._x, -obb.extent._y, obb.extent._z);
corners[6] = Vector3f ( obb.extent._x, obb.extent._y, obb.extent._z);
corners[7] = Vector3f (-obb.extent._x, obb.extent._y, obb.extent._z);
glPushAttrib (GL_ENABLE_BIT);
glDisable (GL_TEXTURE_2D);
glDisable (GL_LIGHTING);
for (int i = 0; i < 8; ++i) {
corners[i] += obb.center;
obb.world.transform (corners[i]);
}
GLuint indices[24] =
{
0, 1, 1, 2, 2, 3, 3, 0,
4, 5, 5, 6, 6, 7, 7, 4,
0, 4, 1, 5, 2, 6, 3, 7
};
glColor3f (1.0, 0.0, 0.0);
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (3, GL_FLOAT, 0, corners);
glDrawElements (GL_LINES, 24, GL_UNSIGNED_INT, indices);
glDisableClientState (GL_VERTEX_ARRAY);
// GL_ENABLE_BIT
glPopAttrib();
}
// -------------------------------------------------------------------------
// drawAxes
//
// Draw the X, Y and Z axes at the center of world.
// -------------------------------------------------------------------------
void drawAxes(const Matrix4x4f &modelView) {
// Setup world model view matrix
glLoadIdentity ();
glMultMatrixf (modelView._m);
// Draw the three axes
glBegin (GL_LINES);
// X-axis in red
glColor3f (1.0f, 0.0f, 0.0f);
glVertex3fv (kZeroVectorf._v);
glVertex3fv (kZeroVectorf + Vector3f (10.0f, 0.0f, 0.0));
// Y-axis in green
glColor3f (0.0f, 1.0f, 0.0f);
glVertex3fv (kZeroVectorf._v);
glVertex3fv (kZeroVectorf + Vector3f (0.0f, 10.0f, 0.0));
// Z-axis in blue
glColor3f (0.0f, 0.0f, 1.0f);
glVertex3fv (kZeroVectorf._v);
glVertex3fv (kZeroVectorf + Vector3f (0.0f, 0.0f, 10.0));
glEnd ();
}
// -------------------------------------------------------------------------
// renderMD5Object
//
// Render the 3D part of the scene.
// -------------------------------------------------------------------------
void renderMD5Object(Md5Object *object, double anim, Matrix4x4f *modelViewMatrix) {
if(!object) {
return;
}
// Clear the window
//glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
// Camera rotation
Matrix4x4f camera;
#if 0
camera.identity ();
glTranslated (-eye._x, -eye._y, -eye._z);
glRotated (rot._x, 1.0f, 0.0f, 0.0f);
glRotated (rot._y, 0.0f, 1.0f, 0.0f);
glRotated (rot._z, 0.0f, 0.0f, 1.0f);
#else
camera.fromEulerAngles (degToRad (rot._x),
degToRad (rot._y),
degToRad (rot._z));
camera.setTranslation (-eye);
#endif
Matrix4x4f axisRotation
= RotationMatrix (kXaxis, -kPiOver2)
* RotationMatrix (kZaxis, -kPiOver2);
Matrix4x4f final = camera * axisRotation;
//glMultMatrixf (final._m);
if(modelViewMatrix) {
final = *modelViewMatrix;
}
// Setup scene lighting
setupLight (0.0f, 20.0f, 100.0f);
// Enable/disable texture mapping (fixed pipeline)
if (bTextured)
glEnable (GL_TEXTURE_2D);
else
glDisable (GL_TEXTURE_2D);
// Enable/disable backface culling
if (bCullFace)
glEnable (GL_CULL_FACE);
else
glDisable (GL_CULL_FACE);
// Setup polygon mode and shade model
glPolygonMode (GL_FRONT_AND_BACK, bWireframe ? GL_LINE : GL_FILL);
glShadeModel (bSmooth ? GL_SMOOTH : GL_FLAT);
// Draw object
object->setModelViewMatrix (final);
object->setRenderFlags (renderFlags);
//object->animate (bAnimate ? timer.deltaTime () : 0.0f);
object->animate (anim);
object->computeBoundingBox ();
object->prepare (false);
object->render ();
if (bBounds)
drawObb (object->boundingBox ());
glDisable (GL_LIGHTING);
glDisable (GL_TEXTURE_2D);
drawAxes (final);
}
}}} //end namespace