#include "xywindow.h"
-
#define DEBUG_RENDER 0
inline void debug_string( const char* string ){
// create shader
{
StringOutputStream filename( 256 );
- filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.glsl";
+ filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_vp.glsl";
createShader( m_program, filename.c_str(), GL_VERTEX_SHADER_ARB );
filename.clear();
- filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.glsl";
+ filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_fp.glsl";
createShader( m_program, filename.c_str(), GL_FRAGMENT_SHADER_ARB );
}
// create shader
{
StringOutputStream filename( 256 );
- filename << GlobalRadiant().getAppPath() << "gl/zfill_vp.glsl";
+ filename << GlobalRadiant().getDataPath() << "gl/zfill_vp.glsl";
createShader( m_program, filename.c_str(), GL_VERTEX_SHADER_ARB );
filename.clear();
- filename << GlobalRadiant().getAppPath() << "gl/zfill_fp.glsl";
+ filename << GlobalRadiant().getDataPath() << "gl/zfill_fp.glsl";
createShader( m_program, filename.c_str(), GL_FRAGMENT_SHADER_ARB );
}
glDeleteObjectARB( m_program );
m_program = 0;
}
+
void enable(){
glUseProgramObjectARB( m_program );
GlobalOpenGL_debugAssertNoErrors();
debug_string( "enable depthfill" );
g_depthfillPass_enabled = true;
}
+
void disable(){
glUseProgramObjectARB( 0 );
GlobalOpenGL_debugAssertNoErrors();
glGenProgramsARB( 1, &m_vertex_program );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, m_vertex_program );
StringOutputStream filename( 256 );
- filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.glp";
+ filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_vp.glp";
createProgram( filename.c_str(), GL_VERTEX_PROGRAM_ARB );
glGenProgramsARB( 1, &m_fragment_program );
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, m_fragment_program );
filename.clear();
- filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.glp";
+ filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_fp.glp";
createProgram( filename.c_str(), GL_FRAGMENT_PROGRAM_ARB );
}
glGenProgramsARB( 1, &m_vertex_program );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, m_vertex_program );
StringOutputStream filename( 256 );
- filename << GlobalRadiant().getAppPath() << "gl/zfill_vp.glp";
+ filename << GlobalRadiant().getDataPath() << "gl/zfill_vp.glp";
createProgram( filename.c_str(), GL_VERTEX_PROGRAM_ARB );
glGenProgramsARB( 1, &m_fragment_program );
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, m_fragment_program );
filename.clear();
- filename << GlobalRadiant().getAppPath() << "gl/zfill_fp.glp";
+ filename << GlobalRadiant().getDataPath() << "gl/zfill_fp.glp";
createProgram( filename.c_str(), GL_FRAGMENT_PROGRAM_ARB );
}
glGenProgramsNV( 1, &m_vertex_program );
glBindProgramNV( GL_VERTEX_PROGRAM_NV, m_vertex_program );
StringOutputStream filename( 256 );
- filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_vp.nv30";
+ filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_vp.nv30";
createProgram( m_vertex_program, filename.c_str(), GL_VERTEX_PROGRAM_NV );
glGenProgramsNV( 1, &m_fragment_program );
glBindProgramNV( GL_FRAGMENT_PROGRAM_NV, m_fragment_program );
filename.clear();
- filename << GlobalRadiant().getAppPath() << "gl/lighting_DBS_omni_fp.nv30";
+ filename << GlobalRadiant().getDataPath() << "gl/lighting_DBS_omni_fp.nv30";
createProgram( m_fragment_program, filename.c_str(), GL_FRAGMENT_PROGRAM_NV );
}
}
-
-
/// \brief A container of Renderable references.
/// May contain the same Renderable multiple times, with different transforms.
class OpenGLStateBucket
public:
OpenGLStateBucket(){
}
+
void addRenderable( const OpenGLRenderable& renderable, const Matrix4& modelview, const RendererLight* light = 0 ){
m_renderables.push_back( RenderTransform( renderable, modelview, light ) );
}
const OpenGLRenderable& m_renderable;
const Matrix4& m_modelview;
public:
-typedef const RendererLight& first_argument_type;
+using func = void(const RendererLight&);
OpenGLStateBucketAdd( OpenGLStateBucket& bucket, const OpenGLRenderable& renderable, const Matrix4& modelview ) :
m_bucket( bucket ), m_renderable( renderable ), m_modelview( modelview ){
}
+
void operator()( const RendererLight& light ){
m_bucket.addRenderable( m_renderable, m_modelview, &light );
}
{
std::size_t m_count;
public:
-typedef RendererLight& first_argument_type;
+using func = void(RendererLight&);
CountLights() : m_count( 0 ){
}
+
void operator()( const RendererLight& light ){
++m_count;
}
+
std::size_t count() const {
return m_count;
}
public:
OpenGLShader() : m_shader( 0 ), m_used( 0 ){
}
+
~OpenGLShader(){
}
+
void construct( const char* name );
+
void destroy(){
if ( m_shader ) {
m_shader->DecRef();
}
m_passes.clear();
}
+
void addRenderable( const OpenGLRenderable& renderable, const Matrix4& modelview, const LightList* lights ){
for ( Passes::iterator i = m_passes.begin(); i != m_passes.end(); ++i )
{
if ( ( ( *i )->state().m_state & RENDER_BUMP ) != 0 ) {
if ( lights != 0 ) {
OpenGLStateBucketAdd add( *( *i ), renderable, modelview );
- lights->forEachLight( makeCallback1( add ) );
+ lights->forEachLight(makeCallback( add ) );
}
}
else
}
}
}
+
void incrementUsed(){
if ( ++m_used == 1 && m_shader != 0 ) {
m_shader->SetInUse( true );
}
}
+
void decrementUsed(){
if ( --m_used == 0 && m_shader != 0 ) {
m_shader->SetInUse( false );
}
}
+
bool realised() const {
return m_shader != 0;
}
+
void attach( ModuleObserver& observer ){
if ( realised() ) {
observer.realise();
}
m_observers.attach( observer );
}
+
void detach( ModuleObserver& observer ){
if ( realised() ) {
observer.unrealise();
}
m_observers.detach( observer );
}
+
void realise( const CopiedString& name ){
construct( name.c_str() );
m_observers.realise();
}
+
void unrealise(){
m_observers.unrealise();
destroy();
}
+
qtexture_t& getTexture() const {
ASSERT_NOTNULL( m_shader );
return *m_shader->getTexture();
}
+
unsigned int getFlags() const {
ASSERT_NOTNULL( m_shader );
return m_shader->getFlags();
}
+
IShader& getShader() const {
ASSERT_NOTNULL( m_shader );
return *m_shader;
}
+
OpenGLState& appendDefaultPass(){
m_passes.push_back( new OpenGLStateBucket );
OpenGLState& state = m_passes.back()->state();
{
LightCullable& m_cullable;
RendererLights& m_allLights;
-Callback m_evaluateChanged;
+Callback<void()> m_evaluateChanged;
typedef std::list<RendererLight*> Lights;
mutable Lights m_lights;
mutable bool m_lightsChanged;
public:
-LinearLightList( LightCullable& cullable, RendererLights& lights, const Callback& evaluateChanged ) :
+LinearLightList( LightCullable& cullable, RendererLights& lights, const Callback<void()>& evaluateChanged ) :
m_cullable( cullable ), m_allLights( lights ), m_evaluateChanged( evaluateChanged ){
m_lightsChanged = true;
}
+
void evaluateLights() const {
m_evaluateChanged();
if ( m_lightsChanged ) {
}
#endif
}
+
void forEachLight( const RendererLightCallback& callback ) const {
evaluateLights();
callback( *( *i ) );
}
}
+
void lightsChanged() const {
m_lightsChanged = true;
}
explicit CreateOpenGLShader( OpenGLShaderCache* cache = 0 )
: m_cache( cache ){
}
+
OpenGLShader* construct( const CopiedString& name ){
OpenGLShader* shader = new OpenGLShader;
if ( m_cache->realised() ) {
}
return shader;
}
+
void destroy( OpenGLShader* shader ){
if ( m_cache->realised() ) {
shader->unrealise();
m_lightsChanged( true ),
m_traverseRenderablesMutex( false ){
}
+
~OpenGLShaderCache(){
for ( Shaders::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i )
{
globalOutputStream() << "leaked shader: " << makeQuoted( ( *i ).key.c_str() ) << "\n";
}
}
+
Shader* capture( const char* name ){
ASSERT_MESSAGE( name[0] == '$'
|| *name == '['
#endif
return m_shaders.capture( name ).get();
}
+
void release( const char *name ){
#if DEBUG_SHADERS
globalOutputStream() << "shaders release: " << makeQuoted( name ) << '\n';
}
debug_string( "end rendering" );
}
+
void realise(){
if ( --m_unrealised == 0 ) {
if ( lightingSupported() && lightingEnabled() ) {
}
}
}
+
void unrealise(){
if ( ++m_unrealised == 1 ) {
for ( Shaders::iterator i = m_shaders.begin(); i != m_shaders.end(); ++i )
}
}
}
+
bool realised(){
return m_unrealised == 0;
}
bool lightingEnabled() const {
return m_lightingEnabled;
}
+
bool lightingSupported() const {
return m_lightingSupported;
}
+
bool useShaderLanguage() const {
return m_useShaderLanguage;
}
+
void setLighting( bool supported, bool enabled ){
bool refresh = ( m_lightingSupported && m_lightingEnabled ) != ( supported && enabled );
realise();
}
}
+
void extensionsInitialised(){
setLighting( GlobalOpenGL().GL_1_3()
&& GlobalOpenGL().ARB_vertex_program()
}
}
}
+
void setLightingEnabled( bool enabled ){
setLighting( m_lightingSupported, enabled );
}
const LightList& attach( LightCullable& cullable ){
return ( *m_lightLists.insert( LightLists::value_type( &cullable, LinearLightList( cullable, m_lights, EvaluateChangedCaller( *this ) ) ) ).first ).second;
}
+
void detach( LightCullable& cullable ){
m_lightLists.erase( &cullable );
}
+
void changed( LightCullable& cullable ){
LightLists::iterator i = m_lightLists.find( &cullable );
ASSERT_MESSAGE( i != m_lightLists.end(), "cullable not attached" );
( *i ).second.lightsChanged();
}
+
void attach( RendererLight& light ){
ASSERT_MESSAGE( m_lights.find( &light ) == m_lights.end(), "light could not be attached" );
m_lights.insert( &light );
changed( light );
}
+
void detach( RendererLight& light ){
ASSERT_MESSAGE( m_lights.find( &light ) != m_lights.end(), "light could not be detached" );
m_lights.erase( &light );
changed( light );
}
+
void changed( RendererLight& light ){
m_lightsChanged = true;
}
+
void evaluateChanged(){
if ( m_lightsChanged ) {
m_lightsChanged = false;
}
}
}
-typedef MemberCaller<OpenGLShaderCache, &OpenGLShaderCache::evaluateChanged> EvaluateChangedCaller;
+
+typedef MemberCaller<OpenGLShaderCache, void(), &OpenGLShaderCache::evaluateChanged> EvaluateChangedCaller;
typedef std::set<const Renderable*> Renderables;
Renderables m_renderables;
ASSERT_MESSAGE( m_renderables.find( &renderable ) == m_renderables.end(), "renderable could not be attached" );
m_renderables.insert( &renderable );
}
+
void detachRenderable( const Renderable& renderable ){
ASSERT_MESSAGE( !m_traverseRenderablesMutex, "detaching renderable during traversal" );
ASSERT_MESSAGE( m_renderables.find( &renderable ) != m_renderables.end(), "renderable could not be detached" );
m_renderables.erase( &renderable );
}
+
void forEachRenderable( const RenderableCallback& callback ) const {
ASSERT_MESSAGE( !m_traverseRenderablesMutex, "for-each during traversal" );
m_traverseRenderablesMutex = true;
}
typedef States::iterator iterator;
+
iterator begin(){
return m_states.begin();
}
+
iterator end(){
return m_states.end();
}
bool inserted = m_states.insert( States::value_type( name, state ) ).second;
ASSERT_MESSAGE( inserted, "OpenGLStateMap::insert: " << name << " already exists" );
}
+
void erase( const char* name ){
std::size_t count = m_states.erase( name );
ASSERT_MESSAGE( count == 1, "OpenGLStateMap::erase: " << name << " does not exist" );
{
case IShader::eAlways:
state.m_alphafunc = GL_ALWAYS;
+ break;
case IShader::eEqual:
state.m_alphafunc = GL_EQUAL;
+ break;
case IShader::eLess:
state.m_alphafunc = GL_LESS;
+ break;
case IShader::eGreater:
state.m_alphafunc = GL_GREATER;
+ break;
case IShader::eLEqual:
state.m_alphafunc = GL_LEQUAL;
+ break;
case IShader::eGEqual:
state.m_alphafunc = GL_GEQUAL;
+ break;
}
}
reinterpret_cast<Vector3&>( state.m_colour ) = m_shader->getTexture()->color;
OpenGLStateMap m_stateMap;
public:
typedef OpenGLStateLibrary Type;
+
STRING_CONSTANT( Name, "*" );
OpenGLStateLibraryAPI(){
g_openglStates = &m_stateMap;
}
+
~OpenGLStateLibraryAPI(){
g_openglStates = 0;
}
+
OpenGLStateLibrary* getTable(){
return &m_stateMap;
}
ShaderCache* m_shaderCache;
public:
typedef ShaderCache Type;
+
STRING_CONSTANT( Name, "*" );
ShaderCacheAPI(){
m_shaderCache = GetShaderCache();
}
+
~ShaderCacheAPI(){
ShaderCache_Destroy();
}
+
ShaderCache* getTable(){
return m_shaderCache;
}