- added md5 code to project (but not actively used, only compiled)

This commit is contained in:
Mark Vejvoda
2011-10-18 04:32:02 +00:00
parent b30fdea0d0
commit a2ae980986
20 changed files with 9871 additions and 26 deletions

View File

@@ -0,0 +1,262 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// 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

@@ -0,0 +1,53 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// OpenGL error management.
//
/////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // _WIN32
#include <GL/gl.h>
#include <GL/glu.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

@@ -0,0 +1,454 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// Implementation of GLSL shader related classes.
//
/////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include "Shader.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

@@ -0,0 +1,516 @@
// ==============================================================
// 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 licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// below is included in the resulting source code.
//
// 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 "Texture.h"
#include "Image.h"
namespace Shared { namespace Graphics { namespace md5 {
using std::cout;
using std::cerr;
using std::endl;
/////////////////////////////////////////////////////////////////////////////
//
// 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 = std::max (mipWidth >> 1, 1);
mipHeight = std::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 = std::max (mipWidth >> 1, 1);
mipHeight = std::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

@@ -0,0 +1,569 @@
// ==============================================================
// This file is part of MegaGlest (www.glest.org)
//
// Copyright (C) 2011- by Mark Vejvoda
//
// You can redistribute this code 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
// ==============================================================
#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 "Shader.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

View File

@@ -1,26 +0,0 @@
Copyright (c) 2005-2008, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.