add sparkle explosions

This commit is contained in:
gmueller
2011-01-05 23:02:10 +01:00
parent b19f44ec32
commit a02ad6bd34
106 changed files with 19753 additions and 88 deletions

View File

@ -0,0 +1,381 @@
//////////////////////////////////////////////////////////////////////////////////
// SPARK particle engine //
// Copyright (C) 2008-2009 - Julien Fryer - julienfryer@gmail.com //
// //
// This software is provided 'as-is', without any express or implied //
// warranty. In no event will the authors be held liable for any damages //
// arising from the use of this software. //
// //
// Permission is granted to anyone to use this software for any purpose, //
// including commercial applications, and to alter it and redistribute it //
// freely, subject to the following restrictions: //
// //
// 1. The origin of this software must not be misrepresented; you must not //
// claim that you wrote the original software. If you use this software //
// in a product, an acknowledgment in the product documentation would be //
// appreciated but is not required. //
// 2. Altered source versions must be plainly marked as such, and must not be //
// misrepresented as being the original software. //
// 3. This notice may not be removed or altered from any source distribution. //
//////////////////////////////////////////////////////////////////////////////////
#ifndef H_SPK_GLEXTHANDLER
#define H_SPK_GLEXTHANDLER
#include "Core/SPK_DEF.h"
#include "RenderingAPIs/OpenGL/SPK_GL_DEF.h"
// OpenGL defines (from glext.h)
#define GL_POINT_SPRITE 0x8861
#define GL_COORD_REPLACE 0x8862
#define GL_POINT_DISTANCE_ATTENUATION 0x8129
#define GL_POINT_SIZE_MIN 0x8126
#define GL_POINT_SIZE_MAX 0x8127
#define GL_TEXTURE_3D 0x806F
namespace SPK
{
namespace GL
{
/**
* @class GLExtHandler
* @brief A class to handle OpenGL extensions
*
* This class presents an interface to handle openGL extensions.<br>
* The interface is static an has a public and a protected side.<br>
* <br>
* A class willing to make use of the openGL extensions must derive from this class to access the protected interface.<br>
* <br>
* If an OpenGL extension is not handle by this class,
* the proper way to implement it within SPARK will be to derive this class to implement it.
* Then the Renderer which will use the extension has to extends the child class.
* <br>
* The opengl extensions implemented are :<ul>
* <li>point sprites : used in SPARK to attach images on points and therfore gain performance</li>
* <li>point parameters : used in SPARK both to allow to have points size function of the distance and
* to overtake the basic point size limitation (usually 64 pix).</li>
* <li>texture 3D : used in SPARK to animate texture</li>
* </ul>
*
* @since 1.01.00
*/
class SPK_GL_PREFIX GLExtHandler
{
public :
///////////////////
// Point Sprites //
///////////////////
/**
* @brief Loads the openGL point sprite extension
*
* Note that this methods is called internally when needed.<br>
* The extension is loaded or not only at the first call to this method,
* the following calls only tell whether the extension was loaded or not.<br>
* In that way, this method is only useful to the user, to check whether the extension is supported or not.
*
* @return true if the extension is loaded (supported by the hardware), false if not
*/
static bool loadGLExtPointSprite();
//////////////////////
// Point Parameters //
//////////////////////
/**
* @brief Loads the openGL extended point parameter extension
*
* Note that this methods is called internally when needed.<br>
* The extension is loaded or not only at the first call to this method,
* the further calls only tell whether the extension was loaded or not.<br>
* In that way, this method is only useful to the user, to check whether the extension is supported or not.
*
* @return true if the extension is loaded (supported by the hardware), false if not
*/
static bool loadGLExtPointParameter();
/**
* @brief Computes a conversion ratio between pixels and universe units
*
* This method must be called when using GLPointRenderer with world size enabled.<br>
* It allows to well transpose world size to pixel size by setting the right openGL parameters.<br>
* <br>
* Note that fovy can be replaced by fovx if screenHeight is replaced by screenWidth.
*
* @param fovy : the field of view in the y axis in radians
* @param screenHeight : the height of the viewport in pixels
*/
static void setPixelPerUnit(float fovy,int screenHeight);
////////////////
// Texture 3D //
////////////////
/**
* @brief Loads the OpenGL texture 3D extension
*
* Note that this methods is called internally when needed.<br>
* The extension is loaded or not only at the first call to this method,
* the further calls only tell whether the extension was loaded or not.<br>
* In that way, this method is only useful to the user, to check whether the extension is supported or not.
*
* @return true if the extension is loaded (supported by the hardware), false if not
* @since 1.02.00
*/
static bool loadGLExtTexture3D();
/**
* @brief Specifies a three-dimensional texture image
*
* This method is exactly like calling the glTexImage3D method of OpenGL
* excepts it is already defined.<br>
* If the OpenGL texture 3D extension is not supported, this method does nothing.<br>
* <br>
* For more information, check the OpenGL documentation of glTexImage3D.
*
* @param target : check the OpenGL documentation of glTexImage3D
* @param level : check the OpenGL documentation of glTexImage3D
* @param internalFormat : check the OpenGL documentation of glTexImage3D
* @param width : check the OpenGL documentation of glTexImage3D
* @param height : check the OpenGL documentation of glTexImage3D
* @param depth : check the OpenGL documentation of glTexImage3D
* @param border : check the OpenGL documentation of glTexImage3D
* @param format : check the OpenGL documentation of glTexImage3D
* @param type : check the OpenGL documentation of glTexImage3D
* @param pixels : check the OpenGL documentation of glTexImage3D
* @since 1.02.00
*/
static void glTexImage3D(GLenum target,
GLint level,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border,
GLenum format,
GLenum type,
const GLvoid* pixels);
/////////////
// Shaders //
/////////////
/**
* @brief Loads the shader extension
*
* Note that this methods is called internally when needed.<br>
* The extension is loaded or not only at the first call to this method,
* the further calls only tell whether the extension was loaded or not.<br>
* In that way, this method is only useful to the user, to check whether the extension is supported or not.<br>
* <br>
* NOTE THAT FOR THE MOMENT, EVEN IF SHADER EXTENSIONS CAN BE LOADED, THEY ARE NOT USED WITHIN SPARK
*
* @return true if the extension is loaded (supported by the hardware), false if not
* @since 1.04.00
*/
static bool loadGLExtShader();
protected :
/**
* @enum GLExtension
* @brief Constants for openGL extension loading
*/
enum GLExtension
{
UNCHECKED, /**< Constant meaning the openGL extension was not tested */
SUPPORTED, /**< Constant meaning the openGL extension is supported by the hardware */
UNSUPPORTED, /**< Constant meaning the openGL extension is not supported by the hardware */
};
/**
* @brief Gets the address of an OpenGL function in a portable way
* @param name : the name of the OpenGL function
* @return a pointer to the OpenGL function, or NULL if the function is not found
*/
static inline void* glGetProcAddress(const char* name);
///////////////////
// Point Sprites //
///////////////////
/**
* @brief Gets the state of the point sprite extension
* @return the state of the point sprite extension
*/
static GLExtension getPointSpriteGLExt();
/**
* @brief Enables the use of point sprites
*
* Note that before calling this method, the user must ensure that the point sprite extension is loaded.
*/
inline static void enablePointSpriteGLExt();
/**
* @brief Disables the use of point sprites
*
* Note that before calling this method, the user must ensure that the point sprite extension is loaded.
*/
inline static void disablePointSpriteGLExt();
//////////////////////
// Point Parameters //
//////////////////////
/**
* @brief Gets the state of the point parameters extension
* @return the state of the point parameters extension
*/
static GLExtension getPointParameterGLExt();
/**
* @brief Enables the use of point parameters
*
* This method will set the right point parameters to get the desired point size.<br>
* <br>
* It can either be used to have points size function of the distance to the camera (is distance is true)
* or only to allow bigger range for point sizes (if distance is false).
* <br>
* Note that if distance is set to true setPixelPerUnit(float,int) must be call once before.
* <br>
* Note that before calling this method, the user must ensure that the point parameters extension is loaded.
*
* @param size : the size of the point
* @param distance : true to enable the modification of the size function of the distance, false not to.
*/
static void enablePointParameterGLExt(float size,bool distance);
/**
* @brief Disables the use of point parameters
*
* Note that before calling this method, the user must ensure that the point parameters extension is loaded.
*/
static void disablePointParameterGLExt();
////////////////
// Texture 3D //
////////////////
/**
* @brief Gets the state of the texture 3D extension
* @return the state of the texture 3D extension
* @since 1.02.00
*/
static GLExtension getTexture3DGLExt();
/////////////
// Shaders //
/////////////
/**
* @brief Gets the state of the shader support
* @return the state of the vertex shader support
* @since 1.04.00
*/
static GLExtension getShaderGLExt();
private :
// GLchar definition
typedef char GLchar;
// typedefs for OpenGL pointers of functions (glext.h is however needed)
typedef void (APIENTRY *SPK_PFNGLPOINTPARAMETERFPROC)(GLenum,GLfloat);
typedef void (APIENTRY *SPK_PFNGLPOINTPARAMETERFVPROC)(GLenum,const GLfloat*);
typedef void (APIENTRY *SPK_PFNGLTEXIMAGE3DPROC)(GLenum,GLint,GLint,GLsizei,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*);
typedef void (APIENTRY *SPK_PFNGLCREATESHADERPROC)(GLenum);
typedef void (APIENTRY *SPK_PFNGLDELETESHADERPROC)(GLuint);
typedef void (APIENTRY *SPK_PFNGLSHADERSOURCEPROC)(GLuint,GLsizei,const GLchar**,const GLint*);
typedef void (APIENTRY *SPK_PFNGLCOMPILESHADERPROC)(GLuint);
typedef void (APIENTRY *SPK_PFNGLCREATEPROGRAMPROC)(void);
typedef void (APIENTRY *SPK_PFNGLDELETEPROGRAMPROC)(GLuint);
typedef void (APIENTRY *SPK_PFNGLATTACHSHADERPROC)(GLuint,GLuint);
typedef void (APIENTRY *SPK_PFNGLDETACHSHADERPROC)(GLuint,GLuint);
typedef void (APIENTRY *SPK_PFNGLLINKPROGRAMPROC)(GLuint);
typedef void (APIENTRY *SPK_PFNGLUSEPROGRAMPROC)(GLuint);
// Gets the GL function address on MAC
#if defined(__APPLE__) || defined(macintosh)
static void* SPK_NSGLGetProcAddress(const char* name);
#endif
///////////////////
// Point Sprites //
///////////////////
static GLExtension pointSpriteGLExt;
//////////////////////
// Point Parameters //
//////////////////////
static GLExtension pointParameterGLExt;
static SPK_PFNGLPOINTPARAMETERFPROC SPK_glPointParameterf;
static SPK_PFNGLPOINTPARAMETERFVPROC SPK_glPointParameterfv;
static const float POINT_SIZE_CURRENT;
static const float POINT_SIZE_MIN;
static const float POINT_SIZE_MAX;
static float pixelPerUnit;
static const float QUADRATIC_SCREEN[3];
////////////////
// Texture 3D //
////////////////
static GLExtension texture3DGLExt;
static SPK_PFNGLTEXIMAGE3DPROC SPK_glTexImage3D;
//////////////
// Shaders //
//////////////
static GLExtension shaderGLExt;
static SPK_PFNGLCREATESHADERPROC SPK_glCreateShader;
static SPK_PFNGLDELETESHADERPROC SPK_glDeleteShader;
static SPK_PFNGLSHADERSOURCEPROC SPK_glShaderSource;
static SPK_PFNGLCOMPILESHADERPROC SPK_glCompileShader;
static SPK_PFNGLCREATEPROGRAMPROC SPK_glCreateProgram;
static SPK_PFNGLDELETEPROGRAMPROC SPK_glDeleteProgram;
static SPK_PFNGLATTACHSHADERPROC SPK_glAttachShader;
static SPK_PFNGLDETACHSHADERPROC SPK_glDetachShader;
static SPK_PFNGLLINKPROGRAMPROC SPK_glLinkProgram;
static SPK_PFNGLUSEPROGRAMPROC SPK_glUseProgram;
};
inline void* GLExtHandler::glGetProcAddress(const char* name)
{
#if defined(WIN32) || defined(_WIN32)
return (void*)wglGetProcAddress(name); // Windows
#elif defined(__APPLE__) || defined(macintosh)
return (void*)SPK_NSGLGetProcAddress(name); // MAC
#elif defined(linux) || defined(__linux)
return (void*)glXGetProcAddressARB((const GLubyte*)name); // Linux
#else
return (void*)NULL;
#endif
}
inline void GLExtHandler::enablePointSpriteGLExt()
{
glTexEnvf(GL_POINT_SPRITE,GL_COORD_REPLACE,GL_TRUE);
glEnable(GL_POINT_SPRITE);
}
inline void GLExtHandler::disablePointSpriteGLExt()
{
glDisable(GL_POINT_SPRITE);
}
}}
#endif

View File

@ -0,0 +1,106 @@
//////////////////////////////////////////////////////////////////////////////////
// SPARK particle engine //
// Copyright (C) 2008-2009 - Julien Fryer - julienfryer@gmail.com //
// //
// This software is provided 'as-is', without any express or implied //
// warranty. In no event will the authors be held liable for any damages //
// arising from the use of this software. //
// //
// Permission is granted to anyone to use this software for any purpose, //
// including commercial applications, and to alter it and redistribute it //
// freely, subject to the following restrictions: //
// //
// 1. The origin of this software must not be misrepresented; you must not //
// claim that you wrote the original software. If you use this software //
// in a product, an acknowledgment in the product documentation would be //
// appreciated but is not required. //
// 2. Altered source versions must be plainly marked as such, and must not be //
// misrepresented as being the original software. //
// 3. This notice may not be removed or altered from any source distribution. //
//////////////////////////////////////////////////////////////////////////////////
#ifndef H_SPK_GLLINERENDERER
#define H_SPK_GLLINERENDERER
#include "RenderingAPIs/OpenGL/SPK_GLRenderer.h"
#include "Extensions/Renderers/SPK_LineRendererInterface.h"
namespace SPK
{
namespace GL
{
/**
* @class GLLineRenderer
* @brief A Renderer drawing particles as OpenGL lines
*
* The length of the lines is function of the Particle velocity and is defined in the universe space
* while the width is fixed and defines in the screen space (in pixels).<br>
* <br>
* Below are the parameters of Particle that are used in this Renderer (others have no effects) :
* <ul>
* <li>SPK::PARAM_RED</li>
* <li>SPK::PARAM_GREEN</li>
* <li>SPK::PARAM_BLUE</li>
* <li>SPK::PARAM_ALPHA (only if blending is enabled)</li>
* </ul>
*/
class SPK_GL_PREFIX GLLineRenderer : public GLRenderer, public LineRendererInterface
{
SPK_IMPLEMENT_REGISTERABLE(GLLineRenderer)
public :
//////////////////
// Constructors //
//////////////////
/**
* @brief Constructor of GLLineRenderer
* @param length : the length multiplier of this GLLineRenderer
* @param width : the width of this GLLineRenderer in pixels
*/
GLLineRenderer(float length = 1.0f,float width = 1.0f);
/**
* @brief Creates and registers a new GLLineRenderer
* @param length : the length multiplier of this GLLineRenderer
* @param width : the width of this GLLineRenderer in pixels
* @return A new registered GLLineRenderer
* @since 1.04.00
*/
static inline GLLineRenderer* create(float length = 1.0f,float width = 1.0f);
///////////////
// Interface //
///////////////
virtual void createBuffers(const Group& group);
virtual void destroyBuffers(const Group& group);
virtual void render(const Group& group);
protected :
virtual bool checkBuffers(const Group& group);
private :
// vertex buffers and iterators
static float* gpuBuffer;
static float* gpuIterator;
// buffers names
static const std::string GPU_BUFFER_NAME;
};
inline GLLineRenderer* GLLineRenderer::create(float length,float width)
{
GLLineRenderer* obj = new GLLineRenderer(length,width);
registerObject(obj);
return obj;
}
}}
#endif

View File

@ -0,0 +1,284 @@
//////////////////////////////////////////////////////////////////////////////////
// SPARK particle engine //
// Copyright (C) 2008-2009 - Julien Fryer - julienfryer@gmail.com //
// //
// This software is provided 'as-is', without any express or implied //
// warranty. In no event will the authors be held liable for any damages //
// arising from the use of this software. //
// //
// Permission is granted to anyone to use this software for any purpose, //
// including commercial applications, and to alter it and redistribute it //
// freely, subject to the following restrictions: //
// //
// 1. The origin of this software must not be misrepresented; you must not //
// claim that you wrote the original software. If you use this software //
// in a product, an acknowledgment in the product documentation would be //
// appreciated but is not required. //
// 2. Altered source versions must be plainly marked as such, and must not be //
// misrepresented as being the original software. //
// 3. This notice may not be removed or altered from any source distribution. //
//////////////////////////////////////////////////////////////////////////////////
#ifndef H_SPK_GLLINETRAILRENDERER
#define H_SPK_GLLINETRAILRENDERER
#include "RenderingAPIs/OpenGL/SPK_GLRenderer.h"
#include "Core/SPK_Particle.h"
#include "Core/SPK_Model.h"
namespace SPK
{
namespace GL
{
/**
* @class GLLineTrailRenderer
* @brief A Renderer drawing particles as line trails defined by the positions of particles over time
*
* The trail coordinates are computed in a procedural manner over time.<br>
* A trail i defined by a duration. The faster the particle, the longer the trail. It is defined by a numbers of samples.<br>
* The sampling frequency of the trail is therefore computed by nbSamples / duration and defines its resolution.<br>
* The higher the sampling frequency, the smoother the trail but the bigger the compution time and the memory consumption.<br>
* <br>
* All the particles of a Group are renderered in a single batch of GL_LINE_STRIP,
* which means every trails belong to the same object to reduce overhead on GPU side.<br>
* To allow that, invisible lines link trails together. They are defined as degenerated lines.<br>
* This imposes the alpha value is taken into account and the blending is therefore forced with GLLineTrailRenderer.<br>
* The user has the possibility to set the RGBA values of degenerated lines to keep them invisible function of the blending mode and environment.<br>
* By default it is set to (0.0f,0.0f,0.0f,0.0f).
* <br>
* Below are the parameters of Particle that are used in this Renderer (others have no effects) :
* <ul>
* <li>SPK::PARAM_RED</li>
* <li>SPK::PARAM_GREEN</li>
* <li>SPK::PARAM_BLUE</li>
* <li>SPK::PARAM_ALPHA</li>
* </ul>
* @since 1.03.00
*/
class SPK_GL_PREFIX GLLineTrailRenderer : public GLRenderer
{
SPK_IMPLEMENT_REGISTERABLE(GLLineTrailRenderer)
public :
//////////////////
// Constructors //
//////////////////
/** @brief Default constructor of GLLineTrailRenderer */
GLLineTrailRenderer();
/**
* @brief Creates and registers a new GLLineTrailRenderer
* @return A new registered GLLineTrailRenderer
* @since 1.04.00
*/
static inline GLLineTrailRenderer* create();
/////////////
// Setters //
/////////////
/**
* @brief Sets the number of samples in a trail
*
* The number of samples defines the number of points used to construct the trail.<br>
* The bigger the number of samples, the smoother the trail but the bigger the compution time and the memory consumption.
*
* @param nbSamples : the number of samples to construct the trails
*/
inline void setNbSamples(size_t nbSamples);
/**
* @brief Sets the width of a trail
*
* Like for GLLineRenderer, the width is defined in pixels and is not dependant of the distance of the trail from the camera
*
* @param width : the width of trails in pixels
*/
inline void setWidth(float width);
/**
* @brief Sets the duration of a sample
*
* The duration of a sample is defined by its life time from its creation to its destruction.<br>
* Note that the alpha of a sample will decrease linearly from its initial alpha to 0.
*
* @param duration : the duration of a sample
*/
inline void setDuration(float duration);
/**
* @brief Sets the color components of degenerated lines
* @param r : the red component
* @param g : the green component
* @param b : the blue component
* @param a : the alpha component
*/
void setDegeneratedLines(float r,float g,float b,float a);
virtual inline void enableBlending(bool blendingEnabled);
/////////////
// Getters //
/////////////
/**
* @brief Gets the number of samples per trail
* @return the number of samples per trail
*/
inline size_t getNbSamples() const;
/**
* @brief Gets the width of a trail
* @return the width of a trail (in pixels)
*/
inline float getWidth() const;
/**
* @brief Gets the duration of a sample
* @return the duration of a sample
*/
inline float getDuration() const;
///////////////
// Interface //
///////////////
virtual void createBuffers(const Group& group);
virtual void destroyBuffers(const Group& group);
/**
* @brief Inits all the trails of the particle of the group
*
* All the samples are set to the current position of the particle.<br>
* The trail of each particle has therefore a length of 0 and is ready for update.<br>
* This function allows to clear the buffers for GLLineTrailRenderer of the given group.
*
* @param group : the Group whose buffers need to be initialized
*/
void init(const Group& group);
virtual void render(const Group& group);
protected :
virtual bool checkBuffers(const Group& group);
private :
size_t nbSamples;
float width;
float duration;
float degeneratedR;
float degeneratedG;
float degeneratedB;
float degeneratedA;
// vertex buffers and iterators
static float* vertexBuffer;
static float* vertexIterator;
static float* colorBuffer;
static float* colorIterator;
static float* valueBuffer;
static float* valueIterator;
// buffers names
static const std::string VERTEX_BUFFER_NAME;
static const std::string COLOR_BUFFER_NAME;
static const std::string VALUE_BUFFER_NAME;
inline void init(const Particle& particle,float age) const;
};
inline GLLineTrailRenderer* GLLineTrailRenderer::create()
{
GLLineTrailRenderer* obj = new GLLineTrailRenderer;
registerObject(obj);
return obj;
}
inline void GLLineTrailRenderer::enableBlending(bool blendingEnabled)
{
GLRenderer::enableBlending(true);
}
inline void GLLineTrailRenderer::setNbSamples(size_t nbSamples)
{
this->nbSamples = nbSamples;
}
inline void GLLineTrailRenderer::setWidth(float width)
{
this->width = width;
}
inline void GLLineTrailRenderer::setDuration(float duration)
{
this->duration = duration;
}
inline size_t GLLineTrailRenderer::getNbSamples() const
{
return nbSamples;
}
inline float GLLineTrailRenderer::getWidth() const
{
return width;
}
inline float GLLineTrailRenderer::getDuration() const
{
return duration;
}
inline void GLLineTrailRenderer::init(const Particle& particle,float age) const
{
// Gets the particle's values
const Vector3D& pos = particle.position();
float r = particle.getR();
float g = particle.getG();
float b = particle.getB();
float a = particle.getParamCurrentValue(PARAM_ALPHA);
// Inits position
for (size_t i = 0; i < nbSamples + 2; ++i)
{
*(vertexIterator++) = pos.x;
*(vertexIterator++) = pos.y;
*(vertexIterator++) = pos.z;
}
// Inits color
// degenerate pre vertex
*(colorIterator++) = degeneratedR;
*(colorIterator++) = degeneratedG;
*(colorIterator++) = degeneratedB;
*(colorIterator++) = degeneratedA;
for (size_t i = 0; i < nbSamples; ++i)
{
*(colorIterator++) = r;
*(colorIterator++) = g;
*(colorIterator++) = b;
*(colorIterator++) = a;
}
// degenerate post vertex
*(colorIterator++) = degeneratedR;
*(colorIterator++) = degeneratedG;
*(colorIterator++) = degeneratedB;
*(colorIterator++) = degeneratedA;
// Inits age
for (size_t i = 0; i < nbSamples; ++i)
*(valueIterator++) = age;
}
}}
#endif

View File

@ -0,0 +1,163 @@
//////////////////////////////////////////////////////////////////////////////////
// SPARK particle engine //
// Copyright (C) 2008-2009 - Julien Fryer - julienfryer@gmail.com //
// //
// This software is provided 'as-is', without any express or implied //
// warranty. In no event will the authors be held liable for any damages //
// arising from the use of this software. //
// //
// Permission is granted to anyone to use this software for any purpose, //
// including commercial applications, and to alter it and redistribute it //
// freely, subject to the following restrictions: //
// //
// 1. The origin of this software must not be misrepresented; you must not //
// claim that you wrote the original software. If you use this software //
// in a product, an acknowledgment in the product documentation would be //
// appreciated but is not required. //
// 2. Altered source versions must be plainly marked as such, and must not be //
// misrepresented as being the original software. //
// 3. This notice may not be removed or altered from any source distribution. //
//////////////////////////////////////////////////////////////////////////////////
#ifndef H_SPK_GLPOINTRENDERER
#define H_SPK_GLPOINTRENDERER
#include "RenderingAPIs/OpenGL/SPK_GLRenderer.h"
#include "RenderingAPIs/OpenGL/SPK_GLExtHandler.h"
#include "Extensions/Renderers/SPK_PointRendererInterface.h"
namespace SPK
{
namespace GL
{
/**
* @class GLPointRenderer
* @brief A Renderer drawing drawing particles as openGL points
*
* OpenGL points can be configured to render them in 3 different ways :
* <ul>
* <li>SPK::POINT_SQUARE : standard openGL points</li>
* <li>SPK::POINT_CIRCLE : antialiased openGL points</li>
* <li>SPK::POINT_SPRITE : OpenGL point sprites (must be supported by the hardware)</li>
* </ul>
* Moreover, points size can either be defined in screen space (in pixels) or in the universe space (must be supported by the hardware).
* The advantage of the universe space is that points size on the screen will be dependant to their distance to the camera, whereas in screen space
* all points will have the same size on the screen no matter their distance to the camera.
* <br>
* Below are the parameters of Particle that are used in this Renderer (others have no effects) :
* <ul>
* <li>SPK::PARAM_RED</li>
* <li>SPK::PARAM_GREEN</li>
* <li>SPK::PARAM_BLUE</li>
* <li>SPK::PARAM_ALPHA (only if blending is enabled)</li>
* </ul>
*/
class SPK_GL_PREFIX GLPointRenderer : public GLRenderer,
public PointRendererInterface,
public GLExtHandler
{
SPK_IMPLEMENT_REGISTERABLE(GLPointRenderer)
public :
//////////////////
// Constructors //
//////////////////
/**
* @brief Constructor of GLPointRenderer
* @param size : the size of the points
*/
GLPointRenderer(float size = 1.0f);
/**
* @brief Creates and registers a new GLPointRenderer
* @param size : the size of the points
* @return A new registered GLPointRenderer
* @since 1.04.00
*/
static inline GLPointRenderer* create(float size = 1.0f);
/////////////
// Setters //
/////////////
virtual bool setType(PointType type);
/**
* @brief Sets the texture of this GLPointRenderer
*
* Note that the texture is only used if point sprites are used (type is set to SPK::POINT_SPRITE)
*
* @param textureIndex : the index of the openGL texture of this GLPointRenderer
*/
inline void setTexture(GLuint textureIndex);
/**
* @brief Sets the way size of points is computed in this GLPointRenderer
*
* if universe size is used (true), the extension is checked.<br>
* if universe size is not supported by the hardware, false is returned and nothing happens.<br>
* <br>
* If world size is enabled, the static method setPixelPetUnit(float,int) must be called to set the conversion between pixels and world units.
*
* @param worldSizeEnabled : true to enable universe size, false to use screen size
* @return true the type of size can be set, false otherwise
*/
bool enableWorldSize(bool worldSizeEnabled);
/////////////
// Getters //
/////////////
/**
* @brief Gets the texture of this GLPointRenderer
* @return the texture of this GLPointRenderer
*/
inline GLuint getTexture() const;
/**
* @brief Tells whether world size is enabled or not in this GLPointRenderer
* @return true if world size is enabled, false if not
*/
inline bool isWorldSizeEnabled() const;
///////////////
// Interface //
///////////////
virtual void render(const Group& group);
private :
GLuint textureIndex;
bool worldSize;
};
inline GLPointRenderer* GLPointRenderer::create(float size)
{
GLPointRenderer* obj = new GLPointRenderer(size);
registerObject(obj);
return obj;
}
inline void GLPointRenderer::setTexture(GLuint textureIndex)
{
this->textureIndex = textureIndex;
}
inline GLuint GLPointRenderer::getTexture() const
{
return textureIndex;
}
inline bool GLPointRenderer::isWorldSizeEnabled() const
{
return worldSize;
}
}}
#endif

View File

@ -0,0 +1,305 @@
//////////////////////////////////////////////////////////////////////////////////
// SPARK particle engine //
// Copyright (C) 2008-2009 - Julien Fryer - julienfryer@gmail.com //
// //
// This software is provided 'as-is', without any express or implied //
// warranty. In no event will the authors be held liable for any damages //
// arising from the use of this software. //
// //
// Permission is granted to anyone to use this software for any purpose, //
// including commercial applications, and to alter it and redistribute it //
// freely, subject to the following restrictions: //
// //
// 1. The origin of this software must not be misrepresented; you must not //
// claim that you wrote the original software. If you use this software //
// in a product, an acknowledgment in the product documentation would be //
// appreciated but is not required. //
// 2. Altered source versions must be plainly marked as such, and must not be //
// misrepresented as being the original software. //
// 3. This notice may not be removed or altered from any source distribution. //
//////////////////////////////////////////////////////////////////////////////////
#ifndef H_SPK_GLQUADRENDERER
#define H_SPK_GLQUADRENDERER
#include "RenderingAPIs/OpenGL/SPK_GLRenderer.h"
#include "RenderingAPIs/OpenGL/SPK_GLExtHandler.h"
#include "Extensions/Renderers/SPK_QuadRendererInterface.h"
#include "Extensions/Renderers/SPK_Oriented3DRendererInterface.h"
#include "Core/SPK_Vector3D.h"
#include "Core/SPK_Particle.h"
#include "Core/SPK_Model.h"
namespace SPK
{
namespace GL
{
/**
* @class GLQuadRenderer
* @brief A Renderer drawing particles as OpenGL quads
*
* the orientation of the quads depends on the orientation parameters set.
* This orientation is computed during rendering by the CPU (further improvement of SPARK will allow to make the computation on GPU side).<br>
* <br>
* Below are the parameters of Particle that are used in this Renderer (others have no effects) :
* <ul>
* <li>SPK::PARAM_SIZE</li>
* <li>SPK::PARAM_RED</li>
* <li>SPK::PARAM_GREEN</li>
* <li>SPK::PARAM_BLUE</li>
* <li>SPK::PARAM_ALPHA (only if blending is enabled)</li>
* <li>SPK::PARAM_ANGLE</li>
* <li>SPK::PARAM_TEXTURE_INDEX (only if not in TEXTURE_NONE mode)</li>
* </ul>
*/
class SPK_GL_PREFIX GLQuadRenderer : public GLRenderer,
public QuadRendererInterface,
public Oriented3DRendererInterface,
public GLExtHandler
{
SPK_IMPLEMENT_REGISTERABLE(GLQuadRenderer)
public :
//////////////////
// Constructors //
//////////////////
/**
* @brief Constructor of GLQuadRenderer
* @param scaleX the scale of the width of the quad
* @param scaleY the scale of the height of the quad
*/
GLQuadRenderer(float scaleX = 1.0f,float scaleY = 1.0f);
/**
* @brief Creates and registers a new GLQuadRenderer
* @param scaleX the scale of the width of the quad
* @param scaleY the scale of the height of the quad
* @return A new registered GLQuadRenderer
* @since 1.04.00
*/
static inline GLQuadRenderer* create(float scaleX = 1.0f,float scaleY = 1.0f);
/////////////
// Setters //
/////////////
virtual bool setTexturingMode(TexturingMode mode);
inline void setTexture(GLuint textureIndex);
/////////////
// Getters //
/////////////
/**
* @brief Gets the texture of this GLQuadRenderer
* @return the texture of this GLQuadRenderer
*/
inline GLuint getTexture() const;
///////////////
// Interface //
///////////////
virtual void createBuffers(const Group& group);
virtual void destroyBuffers(const Group& group);
virtual void render(const Group& group);
protected :
virtual bool checkBuffers(const Group& group);
private :
mutable float modelView[16];
mutable float invModelView[16];
GLuint textureIndex;
// vertex buffers and iterators
static float* gpuBuffer;
static float* gpuIterator;
static float* textureBuffer;
static float* textureIterator;
// buffers names
static const std::string GPU_BUFFER_NAME;
static const std::string TEXTURE_BUFFER_NAME;
float* createTextureBuffer(const Group& group) const;
inline void invertModelView() const;
inline void GLCallColorAndVertex(const Particle& particle) const; // OpenGL calls for color and position
inline void GLCallTexture2DAtlas(const Particle& particle) const; // OpenGL calls for 2D atlastexturing
inline void GLCallTexture3D(const Particle& particle) const; // OpenGL calls for 3D texturing
static void (GLQuadRenderer::*renderParticle)(const Particle&) const; // pointer to the right render method
void render2D(const Particle& particle) const; // Rendering for particles with texture 2D or no texture
void render2DRot(const Particle& particle) const; // Rendering for particles with texture 2D or no texture and rotation
void render3D(const Particle& particle) const; // Rendering for particles with texture 3D
void render3DRot(const Particle& particle) const; // Rendering for particles with texture 3D and rotation
void render2DAtlas(const Particle& particle) const; // Rendering for particles with texture 2D atlas
void render2DAtlasRot(const Particle& particle) const; // Rendering for particles with texture 2D atlas and rotation
};
inline GLQuadRenderer* GLQuadRenderer::create(float scaleX,float scaleY)
{
GLQuadRenderer* obj = new GLQuadRenderer(scaleX,scaleY);
registerObject(obj);
return obj;
}
inline void GLQuadRenderer::setTexture(GLuint textureIndex)
{
this->textureIndex = textureIndex;
}
inline GLuint GLQuadRenderer::getTexture() const
{
return textureIndex;
}
inline void GLQuadRenderer::GLCallColorAndVertex(const Particle& particle) const
{
float x = particle.position().x;
float y = particle.position().y;
float z = particle.position().z;
// quads are drawn in a counter clockwise order :
// top right vertex
*(gpuIterator++) = x + quadSide().x + quadUp().x;
*(gpuIterator++) = y + quadSide().y + quadUp().y;
*(gpuIterator++) = z + quadSide().z + quadUp().z;
gpuIterator += 4;
// top left vertex
*(gpuIterator++) = x - quadSide().x + quadUp().x;
*(gpuIterator++) = y - quadSide().y + quadUp().y;
*(gpuIterator++) = z - quadSide().z + quadUp().z;
gpuIterator += 4;
// bottom left
*(gpuIterator++) = x - quadSide().x - quadUp().x;
*(gpuIterator++) = y - quadSide().y - quadUp().y;
*(gpuIterator++) = z - quadSide().z - quadUp().z;
gpuIterator += 4;
// bottom right
*(gpuIterator++) = x + quadSide().x - quadUp().x;
*(gpuIterator++) = y + quadSide().y - quadUp().y;
*(gpuIterator++) = z + quadSide().z - quadUp().z;
*(gpuIterator++) = particle.getR();
*(gpuIterator++) = particle.getG();
*(gpuIterator++) = particle.getB();
*(gpuIterator++) = particle.getParamCurrentValue(PARAM_ALPHA);
}
inline void GLQuadRenderer::GLCallTexture2DAtlas(const Particle& particle) const
{
computeAtlasCoordinates(particle);
*(textureIterator++) = textureAtlasU1();
*(textureIterator++) = textureAtlasV0();
*(textureIterator++) = textureAtlasU0();
*(textureIterator++) = textureAtlasV0();
*(textureIterator++) = textureAtlasU0();
*(textureIterator++) = textureAtlasV1();
*(textureIterator++) = textureAtlasU1();
*(textureIterator++) = textureAtlasV1();
}
inline void GLQuadRenderer::GLCallTexture3D(const Particle& particle) const
{
float textureIndex = particle.getParamCurrentValue(PARAM_TEXTURE_INDEX);
*(textureIterator + 2) = textureIndex;
*(textureIterator + 5) = textureIndex;
*(textureIterator + 8) = textureIndex;
*(textureIterator + 11) = textureIndex;
textureIterator += 12;
}
inline void GLQuadRenderer::invertModelView() const
{
float tmp[12];
float src[16];
/* transpose matrix */
for (int i = 0; i < 4; ++i)
{
src[i] = modelView[i << 2];
src[i + 4] = modelView[(i << 2) + 1];
src[i + 8] = modelView[(i << 2) + 2];
src[i + 12] = modelView[(i << 2) + 3];
}
/* calculate pairs for first 8 elements (cofactors) */
tmp[0] = src[10] * src[15];
tmp[1] = src[11] * src[14];
tmp[2] = src[9] * src[15];
tmp[3] = src[11] * src[13];
tmp[4] = src[9] * src[14];
tmp[5] = src[10] * src[13];
tmp[6] = src[8] * src[15];
tmp[7] = src[11] * src[12];
tmp[8] = src[8] * src[14];
tmp[9] = src[10] * src[12];
tmp[10] = src[8] * src[13];
tmp[11] = src[9] * src[12];
/* calculate first 8 elements (cofactors) */
invModelView[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7] - tmp[1] * src[5] - tmp[2] * src[6] - tmp[5] * src[7];
invModelView[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7] - tmp[0] * src[4] - tmp[7] * src[6] - tmp[8] * src[7];
invModelView[2] = tmp[2] * src[4] + tmp[7] * src[5] + tmp[10] * src[7] - tmp[3] * src[4] - tmp[6] * src[5] - tmp[11] * src[7];
invModelView[3] = tmp[5] * src[4] + tmp[8] * src[5] + tmp[11] * src[6] - tmp[4] * src[4] - tmp[9] * src[5] - tmp[10] * src[6];
invModelView[4] = tmp[1] * src[1] + tmp[2] * src[2] + tmp[5] * src[3] - tmp[0] * src[1] - tmp[3] * src[2] - tmp[4] * src[3];
invModelView[5] = tmp[0] * src[0] + tmp[7] * src[2] + tmp[8] * src[3] - tmp[1] * src[0]- tmp[6] * src[2] - tmp[9] * src[3];
invModelView[6] = tmp[3] * src[0] + tmp[6] * src[1] + tmp[11] * src[3] - tmp[2] * src[0] - tmp[7] * src[1] - tmp[10] * src[3];
invModelView[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2] - tmp[5]*src[0] - tmp[8]*src[1] - tmp[11]*src[2];
/* calculate pairs for second 8 elements (cofactors) */
tmp[0] = src[2] * src[7];
tmp[1] = src[3] * src[6];
tmp[2] = src[1] * src[7];
tmp[3] = src[3] * src[5];
tmp[4] = src[1] * src[6];
tmp[5] = src[2] * src[5];
tmp[6] = src[0] * src[7];
tmp[7] = src[3] * src[4];
tmp[8] = src[0] * src[6];
tmp[9] = src[2] * src[4];
tmp[10] = src[0] * src[5];
tmp[11] = src[1] * src[4];
/* calculate second 8 elements (cofactors) */
invModelView[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15] - tmp[1] * src[13] - tmp[2] * src[14] - tmp[5] * src[15];
invModelView[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15] - tmp[0] * src[12] - tmp[7] * src[14] - tmp[8] * src[15];
invModelView[10] = tmp[2] * src[12] + tmp[7] * src[13] + tmp[10] * src[15] - tmp[3] * src[12] - tmp[6] * src[13] - tmp[11] * src[15];
invModelView[11] = tmp[5] * src[12] + tmp[8] * src[13] + tmp[11] * src[14] - tmp[4] * src[12] - tmp[9] * src[13] - tmp[10] * src[14];
invModelView[12] = tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9] - tmp[4] * src[11] - tmp[0] * src[9] - tmp[3] * src[10];
invModelView[13] = tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10] - tmp[6] * src[10] - tmp[9] * src[11] - tmp[1] * src[8];
invModelView[14] = tmp[6] * src[9] + tmp[11] * src[11] + tmp[3] * src[8] - tmp[10] * src[11] - tmp[2] * src[8] - tmp[7] * src[9];
invModelView[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9] - tmp[8] * src[9] - tmp[11] * src[10] - tmp[5] * src[8];
/* calculate determinant */
float det = src[0] * invModelView[0] + src[1] * invModelView[1] + src[2] * invModelView[2] + src[3] * invModelView[3];
/* calculate matrix inverse */
det = 1 / det;
for (int i = 0; i < 16; ++i)
invModelView[i] *= det;
}
}}
#endif

View File

@ -0,0 +1,225 @@
//////////////////////////////////////////////////////////////////////////////////
// SPARK particle engine //
// Copyright (C) 2008-2009 - Julien Fryer - julienfryer@gmail.com //
// //
// This software is provided 'as-is', without any express or implied //
// warranty. In no event will the authors be held liable for any damages //
// arising from the use of this software. //
// //
// Permission is granted to anyone to use this software for any purpose, //
// including commercial applications, and to alter it and redistribute it //
// freely, subject to the following restrictions: //
// //
// 1. The origin of this software must not be misrepresented; you must not //
// claim that you wrote the original software. If you use this software //
// in a product, an acknowledgment in the product documentation would be //
// appreciated but is not required. //
// 2. Altered source versions must be plainly marked as such, and must not be //
// misrepresented as being the original software. //
// 3. This notice may not be removed or altered from any source distribution. //
//////////////////////////////////////////////////////////////////////////////////
#ifndef H_SPK_GLRENDERER
#define H_SPK_GLRENDERER
#include "RenderingAPIs/OpenGL/SPK_GL_DEF.h"
#include "Core/SPK_Renderer.h"
namespace SPK
{
namespace GL
{
/**
* @class GLRenderer
* @brief An abstract Renderer for the openGL renderers
*/
class SPK_GL_PREFIX GLRenderer : public Renderer
{
public :
/////////////////
// Constructor //
/////////////////
/** @brief Constructor of GLRenderer */
GLRenderer();
////////////////
// Destructor //
////////////////
/** @brief Destructor of GLRenderer */
virtual ~GLRenderer();
/////////////
// Setters //
/////////////
/**
* @brief Enables or disables the blending of this GLRenderer
* @param blendingEnabled true to enable the blending, false to disable it
*/
virtual inline void enableBlending(bool blendingEnabled);
/**
* @brief Sets the blending functions of this GLRenderer
*
* the blending functions are one of the openGL blending functions.
*
* @param src : the source blending function of this GLRenderer
* @param dest : the destination blending function of this GLRenderer
*/
inline void setBlendingFunctions(GLuint src,GLuint dest);
virtual void setBlending(BlendingMode blendMode);
/**
* @brief Sets the texture blending function of this GLRenderer
*
* the texture blending function is one of the openGL texture blending functions.
*
* @param textureBlending : the texture blending function of this GLRenderer
*/
inline void setTextureBlending(GLuint textureBlending);
/////////////
// Getters //
/////////////
/**
* @brief Tells whether blending is enabled for this GLRenderer
* @return true if blending is enabled, false if it is disabled
*/
inline bool isBlendingEnabled() const;
/**
* @brief Gets the source blending function of this GLRenderer
* @return the source blending function of this GLRenderer
*/
inline GLuint getSrcBlendingFunction() const;
/**
* @brief Gets the destination blending function of this GLRenderer
* @return the source destination function of this GLRenderer
*/
inline GLuint getDestBlendingFunction() const;
/**
* @brief Gets the texture blending function of this GLRenderer
* @return the texture blending function of this GLRenderer
*/
inline GLuint getTextureBlending() const;
///////////////
// Interface //
///////////////
/**
* @brief Saves the current openGL states
*
* This method saves all the states that are likely to be modified by a GLRenderer.<br>
* Use restoreGLStates() to restore the states.<br>
* <br>
* Note that for one saveGLStates call, a call to restoreGLStates must occur.
* In case of several saveGLStates with no restoreGLStates, the restoreGLStates is called priorly in an implicit way.
*/
static void saveGLStates();
/**
* @brief Restores the openGL states
*
* This method restores the openGL states at the values they were at the last call of saveGLStates().
*/
static void restoreGLStates();
protected :
/** @brief Inits the blending of this GLRenderer */
inline void initBlending() const;
/**
* @brief Inits the rendering hints of this GLRenderer
* @since 1.04.00
*/
inline void initRenderingHints() const;
private :
bool blendingEnabled;
GLuint srcBlending;
GLuint destBlending;
GLuint textureBlending;
};
inline void GLRenderer::enableBlending(bool blendingEnabled)
{
this->blendingEnabled = blendingEnabled;
}
inline void GLRenderer::setBlendingFunctions(GLuint src,GLuint dest)
{
srcBlending = src;
destBlending = dest;
}
inline void GLRenderer::setTextureBlending(GLuint textureBlending)
{
this->textureBlending = textureBlending;
}
inline bool GLRenderer::isBlendingEnabled() const
{
return blendingEnabled;
}
inline GLuint GLRenderer::getSrcBlendingFunction() const
{
return srcBlending;
}
inline GLuint GLRenderer::getDestBlendingFunction() const
{
return destBlending;
}
inline GLuint GLRenderer::getTextureBlending() const
{
return textureBlending;
}
inline void GLRenderer::initBlending() const
{
if (blendingEnabled)
{
glBlendFunc(srcBlending,destBlending);
glEnable(GL_BLEND);
}
else
glDisable(GL_BLEND);
}
inline void GLRenderer::initRenderingHints() const
{
// alpha test
if (isRenderingHintEnabled(ALPHA_TEST))
{
glAlphaFunc(GL_GEQUAL,getAlphaTestThreshold());
glEnable(GL_ALPHA_TEST);
}
else
glDisable(GL_ALPHA_TEST);
// depth test
if (isRenderingHintEnabled(DEPTH_TEST))
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
// depth write
glDepthMask(isRenderingHintEnabled(DEPTH_WRITE));
}
}}
#endif

View File

@ -0,0 +1,74 @@
//////////////////////////////////////////////////////////////////////////////////
// SPARK particle engine //
// Copyright (C) 2008-2009 - Julien Fryer - julienfryer@gmail.com //
// //
// This software is provided 'as-is', without any express or implied //
// warranty. In no event will the authors be held liable for any damages //
// arising from the use of this software. //
// //
// Permission is granted to anyone to use this software for any purpose, //
// including commercial applications, and to alter it and redistribute it //
// freely, subject to the following restrictions: //
// //
// 1. The origin of this software must not be misrepresented; you must not //
// claim that you wrote the original software. If you use this software //
// in a product, an acknowledgment in the product documentation would be //
// appreciated but is not required. //
// 2. Altered source versions must be plainly marked as such, and must not be //
// misrepresented as being the original software. //
// 3. This notice may not be removed or altered from any source distribution. //
//////////////////////////////////////////////////////////////////////////////////
#ifndef H_SPK_GL_DEF
#define H_SPK_GL_DEF
#ifdef _MSC_VER
#pragma warning(disable : 4275) // disables the warning about exporting DLL classes children of non DLL classes
#endif
// 1.02.02 Compatibility with older versions
#ifdef SPK_DLL
#define SPK_GL_IMPORT
#endif
#ifdef SPK_GL_EXPORT
#define SPK_GL_PREFIX __declspec(dllexport)
#elif defined(SPK_IMPORT) || defined(SPK_GL_IMPORT)
#define SPK_GL_PREFIX __declspec(dllimport)
#else
#define SPK_GL_PREFIX
#endif
#ifndef SPK_NO_GL_INC
#if defined(WIN32) || defined(_WIN32)
#include <windows.h>
#endif
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#elif defined(macintosh)
#include <gl.h>
#else
#include <GL/gl.h>
#endif
#if defined(linux) || defined(__linux)
#include <GL/glx.h>
#endif
#endif
// Defines the APIENTRY if not already done
#ifndef APIENTRY
#define APIENTRY
#endif
/**
* @namespace SPK::GL
* @brief the namespace for openGL dependent SPARK code
* @since 1.01.00
*/
#endif