//////////////////////////////////////////////////////////////////////////////////
// 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.
* The interface is static an has a public and a protected side.
*
* A class willing to make use of the openGL extensions must derive from this class to access the protected interface.
*
* 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.
*
* The opengl extensions implemented are :
* - point sprites : used in SPARK to attach images on points and therfore gain performance
* - 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).
* - texture 3D : used in SPARK to animate texture
*
*
* @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.
* 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.
* 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.
* 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.
* 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.
* It allows to well transpose world size to pixel size by setting the right openGL parameters.
*
* 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.
* 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.
* 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.
* If the OpenGL texture 3D extension is not supported, this method does nothing.
*
* 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.
* 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.
* In that way, this method is only useful to the user, to check whether the extension is supported or not.
*
* 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.
*
* 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).
*
* Note that if distance is set to true setPixelPerUnit(float,int) must be call once before.
*
* 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