Show execute.cpp syntax highlighted
/***************************************************************************
execute.cpp - Execute ops in render queue
-------------------
begin : Thu May 22 2003
copyright : (C) 2003 by Reality Rift Studios
email : mattias@realityrift.com
***************************************************************************
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the NeoEngine, NeoDevOpenGL, execute.cpp
The Initial Developer of the Original Code is Mattias Jansson.
Portions created by Mattias Jansson are Copyright (C) 2003
Reality Rift Studios. All Rights Reserved.
***************************************************************************/
#include "renderqueue.h"
#include "device.h"
#include "shader.h"
#include "op.h"
#include "rendertarget.h"
#include "textureunit.h"
#include "vertexbuffermanager.h"
#include "pixelbuffer.h"
//#include <GL/glu.h>
#include <neoengine/light.h>
#include <neoengine/scenenode.h>
#include <neoengine/vertex.h>
using namespace std;
using namespace NeoEngine;
namespace NeoOGL
{
//TEMPORARY TEST: Disable destalpha blends
// 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf
GLenum aeSrcBlendTable[16] = { GL_ONE, GL_ZERO, GL_ZERO, GL_ZERO, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO, GL_SRC_ALPHA_SATURATE, GL_ONE, GL_ONE };
GLenum aeDestBlendTable[16] = { GL_ZERO, GL_ONE , GL_ZERO, GL_ZERO, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ZERO, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE, GL_ZERO, GL_ZERO, GL_ZERO, GL_ZERO };
#ifdef NEOGL_ENABLE_STATISTICS
#define RENDERPASS( bUnique ) \
{ \
if( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLESTRIP ) \
glDrawElements( GL_TRIANGLE_STRIP, pkOp->m_uiNumPrimitives + 2, GL_UNSIGNED_SHORT, pkOp->m_pkPolygonStripBuffer->GetRenderData() ); \
else \
glDrawElements( GL_TRIANGLES, pkOp->m_uiNumPrimitives * 3, GL_UNSIGNED_SHORT, pkOp->m_pkPolygonBuffer->GetRenderData() ); \
\
m_pkDevice->m_pkStats->m_uiTotalPolygons += pkOp->m_uiNumPrimitives; \
if( bUnique ) m_pkDevice->m_pkStats->m_uiUniquePolygons += pkOp->m_uiNumPrimitives; \
}
#else
#define RENDERPASS( bUnique ) \
{ \
if( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLESTRIP ) \
glDrawElements( GL_TRIANGLE_STRIP, pkOp->m_uiNumPrimitives + 2, GL_UNSIGNED_SHORT, pkOp->m_pkPolygonStripBuffer->GetRenderData() ); \
else \
glDrawElements( GL_TRIANGLES, pkOp->m_uiNumPrimitives * 3, GL_UNSIGNED_SHORT, pkOp->m_pkPolygonBuffer->GetRenderData() ); \
}
#endif
//static Matrix lightProjectionMatrix,lightViewMatrix;
void RenderQueue::RenderZBuffer(){
if( m_bIsSky )
return;
glDepthRange( 0.0f, 1.0f );
int iOp = 0;
bool bLighting = false;
static Matrix kNativeView;
static Matrix kNativeModel;
//m_pkDevice->SetShadowMapLightProjectionMatrix( m_pkDevice->GetViewMatrix());
//m_pkDevice->SetShadowMapLightViewMatrix ( m_pkDevice->GetViewMatrix() );
m_pkDevice->lightViewMatrix = m_pkDevice->GetViewMatrix();
m_pkDevice->lightProjectionMatrix = m_pkDevice->GetProjectionMatrix();
kNativeView = m_pkDevice->GetViewMatrix();
glMatrixMode( GL_MODELVIEW );
//glLoadIdentity();
/*
if( m_pkDevice->m_bIsRenderingTexture )
{
Matrix kMirrorXZ;
kMirrorXZ.m_aafMatrix[1][1]=-1.0f;
neoglLoadMatrixf( (float*)kMirrorXZ );
neoglMultMatrixf( (float*)kNativeView );
}
else
neoglLoadMatrixf( (float*)kNativeView );
*/
neoglLoadMatrixf( (float*)kNativeView );
glDisable( GL_LIGHTING );
glAlphaFunc ( GL_GREATER, 0.95f ) ;
glEnable ( GL_ALPHA_TEST ) ;
glColorMask(0, 0, 0, 1);
// glColorMask(1, 1, 1, 1);
glPolygonOffset( 2.0f, 4.0f );
glEnable( GL_POLYGON_OFFSET_FILL );
//Set base blend state
glBlendFunc( GL_ONE, GL_ZERO );
//glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
//Disable color writes, and use flat shading for speed
//glShadeModel(GL_FLAT);
glEnable(GL_TEXTURE_2D);
bool bUseSort = !( m_bIsSky || ( m_pkDevice->m_pkCurTarget->m_uiFrameFlags & RenderDevice::NOSORT ) );
bool bPolygons = true;
unsigned int *puiOpIndex = m_kSorter.GetIndices();
for( iOp = 0; iOp < m_iNumOps; ++iOp )
{
int iIndex = !bUseSort ? iOp : puiOpIndex[ iOp ];
RenderPrimitive *pkOp = &m_ppkOpArray[ iIndex >> OpArray::ARRAYSHIFT ]->m_akOps[ iIndex & OpArray::ARRAYMASK ];
bPolygons = ( ( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLES ) || ( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLESTRIP ) );
VertexBufferGL *pkVertexBuffer = static_cast< VertexBufferGL* >( (NeoEngine::VertexBuffer*)pkOp->m_pkVertexBuffer );
PolygonBuffer *pkPolygonBuffer = pkOp->m_pkPolygonBuffer;
MaterialPass *pkMat = !pkOp->m_uiPass ? pkOp->m_pkMaterial : pkOp->m_pkMaterial->m_vpkPasses[ pkOp->m_uiPass - 1 ];
if( pkVertexBuffer->IsDirty() )
pkVertexBuffer->Upload();
if( pkPolygonBuffer && pkPolygonBuffer->IsDirty() )
pkPolygonBuffer->Upload();
//Set new modelview matrix
kNativeModel = pkOp->m_kModelMatrix;
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
neoglMultMatrixf( (float*)kNativeModel );
m_pkDevice->m_pkVertexBufferManager->SetBasePointers( pkVertexBuffer, pkMat->m_uiUVLayer );
m_pkDevice->m_kZBufferState.SetMode( pkMat->m_kZBufferMode.Get() & ZBufferMode::FUNCBITS, pkMat->m_kZBufferMode.Get() & ZBufferMode::MODEBITS );
//----------------------------------------------------------------------------
NeoOGL::Texture *pkTexture;
unsigned int uiLayer = 1;
//Render all layers for polygons
if( bPolygons )//&& m_pkDevice->m_bDrawPolygons )
{
vector< TextureLayer* >::iterator ppkLayer = pkMat->m_vpkTextureLayers.begin();
vector< TextureLayer* >::iterator ppkLayerEnd = pkMat->m_vpkTextureLayers.end();
for( uiLayer = 1; ppkLayer != ppkLayerEnd; ++uiLayer, ++ppkLayer )
{
TextureLayer *pkLayer = *ppkLayer;
if( ( uiLayer >= m_pkDevice->m_uiNumTMUs ) || !m_pkDevice->m_ppkTMU[ uiLayer ]->SetBlendMode( pkLayer->m_kBlendMode.Get() & BlendMode::SRCBITS, pkLayer->m_kBlendMode.Get() & BlendMode::DESTBITS, pkLayer->m_kBlendMode.m_fFactor ) )
{
for( ; uiLayer < m_pkDevice->m_uiNumTMUs; ++uiLayer )
{
m_pkDevice->m_ppkTMU[ uiLayer ]->Disable();
m_pkDevice->m_pkVertexBufferManager->SetTexLayerPointer( pkVertexBuffer, uiLayer, 0, true );
}
//Render up to this layer
RENDERPASS( false )
//Set new base layer
glBlendFunc( aeSrcBlendTable[ pkLayer->m_kBlendMode.Get() & BlendMode::SRCBITS ], aeDestBlendTable[ ( pkLayer->m_kBlendMode.Get() & BlendMode::DESTBITS ) >> 4 ] );
uiLayer = 0;
}
pkTexture = (NeoOGL::Texture*)(NeoEngine::Texture*)pkLayer->GetTexture();
m_pkDevice->m_ppkTMU[ uiLayer ]->SetTexture( pkTexture );
m_pkDevice->m_ppkTMU[ uiLayer ]->SetTexGen( pkLayer->m_eTexCoordGen );
if( pkTexture )
pkTexture->SetAddressMode( pkLayer->m_uiUVAddress );
m_pkDevice->m_pkVertexBufferManager->SetTexLayerPointer( pkVertexBuffer, uiLayer, pkLayer->m_uiUVLayer, false );
if( pkLayer->m_vpkTexMatrixGen.size() )
{
Matrix kMat;
vector< TextureMatrixGen* >::iterator ppkGen = pkLayer->m_vpkTexMatrixGen.begin();
vector< TextureMatrixGen* >::iterator ppkGenEnd = pkLayer->m_vpkTexMatrixGen.end();
for( ; ppkGen != ppkGenEnd; ++ppkGen )
(*ppkGen)->GenerateMatrix( &kMat );
m_pkDevice->m_ppkTMU[ uiLayer ]->SetTransform( &kMat );
}
else
m_pkDevice->m_ppkTMU[ uiLayer ]->SetTransform( 0 );
}
}
//glBlendFunc( GL_ONE, GL_ZERO );
//glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
m_pkDevice->m_ppkTMU[ 0 ]->SetTexture( (NeoOGL::Texture*)(NeoEngine::Texture*)pkMat->GetTexture() );
// m_pkDevice->m_ppkTMU[ 0 ]->SetTexture((NeoOGL::Texture*)(NeoEngine::Texture*)pkMat->GetTexture());
if( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLESTRIP )
glDrawElements( GL_TRIANGLE_STRIP, pkOp->m_uiNumPrimitives + 2, GL_UNSIGNED_SHORT, pkOp->m_pkPolygonStripBuffer->GetRenderData() );
else if( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLES )
glDrawElements( GL_TRIANGLES, pkOp->m_uiNumPrimitives * 3, GL_UNSIGNED_SHORT, pkOp->m_pkPolygonBuffer->GetRenderData() );
for( ; uiLayer < m_pkDevice->m_uiNumTMUs; ++uiLayer )
{
m_pkDevice->m_ppkTMU[ uiLayer ]->Disable();
m_pkDevice->m_pkVertexBufferManager->SetTexLayerPointer( pkVertexBuffer, uiLayer, 0, true );
}
glPopMatrix();
}
if( bLighting )
{
glEnable( GL_LIGHTING );
}
glMatrixMode( GL_MODELVIEW );
//Reset depth range
glDisable ( GL_ALPHA_TEST );
glDisable( GL_POLYGON_OFFSET_FILL );
glColorMask(1, 1, 1, 1);
}
void RenderQueue::RenderShadowGLSL(){
if ( !m_pkDevice->SMshaderGLSL )
return;
NeoEngine::PixelBuffer *m_pkShadowMap;
m_pkShadowMap=m_pkDevice->getShadowMapTxt();
if ( m_pkShadowMap == 0 || m_bIsSky )
return;
glPolygonOffset( 0.0f, 0.0f );
glEnable( GL_POLYGON_OFFSET_FILL );
glDepthRange( 0.0f, 1.0f );
glEnable(GL_TEXTURE_2D);
//------------------------------------
glEnable(GL_BLEND);
neoglActiveTextureARB(GL_TEXTURE0_ARB);
// neoglActiveTextureARB(GL_TEXTURE1_ARB);
//------------------------------------
float x[] = { 1.0f, 0.0f, 0.0f, 0.0f };
float y[] = { 0.0f, 1.0f, 0.0f, 0.0f };
float z[] = { 0.0f, 0.0f, 1.0f, 0.0f };
float w[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGenfv( GL_S, GL_EYE_PLANE, x );
glTexGenfv( GL_T, GL_EYE_PLANE, y );
glTexGenfv( GL_R, GL_EYE_PLANE, z );
glTexGenfv( GL_Q, GL_EYE_PLANE, w );
glEnable( GL_TEXTURE_GEN_S );
glEnable( GL_TEXTURE_GEN_T );
glEnable( GL_TEXTURE_GEN_R );
glEnable( GL_TEXTURE_GEN_Q );
// Set up the depth texture projection
Matrix modelViewInv=m_pkDevice->GetViewMatrix();
modelViewInv.Inverse();
glMatrixMode( GL_TEXTURE );
glLoadIdentity();
glTranslatef( 0.5f, 0.5f, 0.5f ); // Offset
glScalef( 0.5f, 0.5f, 0.5f ); // Bias
neoglMultMatrixf( (float*) m_pkDevice->lightProjectionMatrix );
neoglMultMatrixf( (float*) m_pkDevice->lightViewMatrix );
neoglMultMatrixf( (float*) modelViewInv);
NeoEngine::TexturePtr pnt;
pnt=(NeoEngine::TexturePtr) m_pkShadowMap->GetTexture();
NeoOGL::Texture *pkTexture = (NeoOGL::Texture*)(NeoEngine::Texture*)(pnt);
m_pkDevice->m_ppkTMU[0]->SetTexture( pkTexture );
glEnable(GL_NORMALIZE);
//Enable shadow comparison
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
//Shadow comparison should be true (ie not in shadow) if r<=texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_GEQUAL);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
//Shadow comparison should generate an INTENSITY result
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
//Set alpha test to discard false comparisons
glAlphaFunc(GL_GEQUAL, 0.99f);
//glAlphaFunc(GL_GEQUAL, 0.10f);
glEnable(GL_ALPHA_TEST);
int iOp = 0;
bool bLighting = false;
static Matrix kNativeView;
static Matrix kNativeModel;
kNativeView = m_pkDevice->GetViewMatrix();
glMatrixMode( GL_MODELVIEW );
/*
if( m_pkDevice->m_bIsRenderingTexture )
{
Matrix kMirrorXZ;
kMirrorXZ.m_aafMatrix[1][1] = -1.0f;
neoglLoadMatrixf( (float*)kMirrorXZ );
neoglMultMatrixf( (float*)kNativeView );
}
else
neoglLoadMatrixf( (float*)kNativeView );
*/
neoglLoadMatrixf( (float*)kNativeView );
glDisable( GL_LIGHTING );
bool bUseSort = !( m_bIsSky || ( m_pkDevice->m_pkCurTarget->m_uiFrameFlags & RenderDevice::NOSORT ) );
bool bPolygons = true;
unsigned int *puiOpIndex = m_kSorter.GetIndices();
for( iOp = 0; iOp < m_iNumOps; ++iOp )
{
int iIndex = !bUseSort ? iOp : puiOpIndex[ iOp ];
RenderPrimitive *pkOp = &m_ppkOpArray[ iIndex >> OpArray::ARRAYSHIFT ]->m_akOps[ iIndex & OpArray::ARRAYMASK ];
bPolygons = ( ( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLES ) || ( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLESTRIP ) );
//Make sure unit 0 is active
TextureUnit::SetActiveTextureUnit( 0 );
VertexBufferGL *pkVertexBuffer = static_cast< VertexBufferGL* >( (NeoEngine::VertexBuffer*)pkOp->m_pkVertexBuffer );
PolygonBuffer *pkPolygonBuffer = pkOp->m_pkPolygonBuffer;
MaterialPass *pkMat = !pkOp->m_uiPass ? pkOp->m_pkMaterial : pkOp->m_pkMaterial->m_vpkPasses[ pkOp->m_uiPass - 1 ];
if( pkVertexBuffer->IsDirty() )
pkVertexBuffer->Upload();
if( pkPolygonBuffer && pkPolygonBuffer->IsDirty() )
pkPolygonBuffer->Upload();
//Set new modelview matrix
kNativeModel = pkOp->m_kModelMatrix;
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
neoglMultMatrixf( (float*)kNativeModel );
m_pkDevice->m_pkVertexBufferManager->SetBasePointers( pkVertexBuffer, pkMat->m_uiUVLayer );
m_pkDevice->m_kZBufferState.SetMode( pkMat->m_kZBufferMode.Get() & ZBufferMode::FUNCBITS, pkMat->m_kZBufferMode.Get() & ZBufferMode::MODEBITS );
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_DST_ALPHA);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
// GLSL binding for all primitive
Shader *pkShader = static_cast< Shader* >( (NeoEngine::Shader*) m_pkDevice->SMshaderGLSL );
pkShader->Bind( pkOp );
m_pkDevice->m_pkProgramShader = pkShader;
NeoEngine::TexturePtr pnt;
pnt=(NeoEngine::TexturePtr) m_pkShadowMap->GetTexture();
NeoOGL::Texture *pkTexture = (NeoOGL::Texture*)(NeoEngine::Texture*)(pnt);
m_pkDevice->m_ppkTMU[0]->SetTexture( pkTexture );
//Draw back faces into the shadow map
glCullFace(GL_BACK);
//glShadeModel(GL_BLEND);
glShadeModel(GL_FLAT);
//Render up to this layer
if(bPolygons){
if( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLESTRIP )
glDrawElements( GL_TRIANGLE_STRIP, pkOp->m_uiNumPrimitives + 2, GL_UNSIGNED_SHORT, pkOp->m_pkPolygonStripBuffer->GetRenderData() );
else
glDrawElements( GL_TRIANGLES, pkOp->m_uiNumPrimitives * 3, GL_UNSIGNED_SHORT, pkOp->m_pkPolygonBuffer->GetRenderData() );
}else{
if( pkOp->m_ePrimitive == RenderPrimitive::LINES )
{
glLineWidth( pkOp->m_fSize );
glDrawArrays( GL_LINES, 0, pkOp->m_uiNumPrimitives * 2 );
}
else if( pkOp->m_ePrimitive == RenderPrimitive::LINESTRIP )
{
glLineWidth( pkOp->m_fSize );
glDrawArrays( GL_LINE_STRIP, 0, pkOp->m_uiNumPrimitives + 1 );
}
else if( pkOp->m_ePrimitive == RenderPrimitive::POINTS )
{
glPointSize( pkOp->m_fSize );
glDrawArrays( GL_POINTS, 0, pkOp->m_uiNumPrimitives );
}
else if( pkOp->m_ePrimitive == RenderPrimitive::POINTSPRITES )
{
glEnable( GL_POINT_SPRITE_ARB );
glPointSize( pkOp->m_fSize );
glDrawArrays( GL_POINTS, 0, pkOp->m_uiNumPrimitives );
glDisable( GL_POINT_SPRITE_ARB );
}
}
glPopMatrix();
}
if( bLighting )
{
glEnable( GL_LIGHTING );
}
m_pkDevice->m_pkProgramShader->Unbind();
m_pkDevice->m_pkProgramShader = 0;
glDisable( GL_POLYGON_OFFSET_FILL );
glMatrixMode( GL_TEXTURE );
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
//Disable textures and texgen
//glDisable(GL_TEXTURE_2D);
//------------------------------------
//glDisable(GL_BLEND);
neoglActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);
neoglActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);
neoglActiveTextureARB(GL_TEXTURE0_ARB);
//------------------------------------
//Restore other states
//glDisable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
glDisable( GL_POLYGON_OFFSET_FILL );
glDisable(GL_NORMALIZE);
}
void RenderQueue::RenderShadow()
{
NeoEngine::PixelBuffer *m_pkShadowMap;
m_pkShadowMap=m_pkDevice->getShadowMapTxt();
if ( m_pkShadowMap == 0 || m_bIsSky )
return;
glPolygonOffset( 0.0f, 0.0f );
glEnable( GL_POLYGON_OFFSET_FILL );
glDepthRange( 0.0f, 1.0f );
glEnable(GL_TEXTURE_2D);
//------------------------------------
glEnable(GL_BLEND);
neoglActiveTextureARB(GL_TEXTURE0_ARB);
// neoglActiveTextureARB(GL_TEXTURE1_ARB);
//------------------------------------
float x[] = { 1.0f, 0.0f, 0.0f, 0.0f };
float y[] = { 0.0f, 1.0f, 0.0f, 0.0f };
float z[] = { 0.0f, 0.0f, 1.0f, 0.0f };
float w[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glTexGenfv( GL_S, GL_EYE_PLANE, x );
glTexGenfv( GL_T, GL_EYE_PLANE, y );
glTexGenfv( GL_R, GL_EYE_PLANE, z );
glTexGenfv( GL_Q, GL_EYE_PLANE, w );
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glEnable( GL_TEXTURE_GEN_S );
glEnable( GL_TEXTURE_GEN_T );
glEnable( GL_TEXTURE_GEN_R );
glEnable( GL_TEXTURE_GEN_Q );
// Set up the depth texture projection
glMatrixMode( GL_TEXTURE );
glLoadIdentity();
glTranslatef( 0.5f, 0.5f, 0.5f ); // Offset
glScalef( 0.5f, 0.5f, 0.5f ); // Bias
neoglMultMatrixf( (float*) m_pkDevice->lightProjectionMatrix );
neoglMultMatrixf( (float*) m_pkDevice->lightViewMatrix );
/* float comp[]={ 0.5f, 0.0f, 0.0f, 0.5f,
0.0f, 0.5f, 0.0f, 0.5f,
0.0f, 0.0f, 0.5f, 0.5f,
0.0f, 0.0f, 0.0f, 1.0f };
Matrix bias(comp);
//biasMatrix*lightProjectionMatrix*lightViewMatrix;
bias = bias * lightProjectionMatrix * lightViewMatrix;
float x[4] = { bias.m_aafMatrix[0][0], bias.m_aafMatrix[0][1], bias.m_aafMatrix[0][2], bias.m_aafMatrix[0][3]};
float y[4] = { bias.m_aafMatrix[1][0], bias.m_aafMatrix[1][1], bias.m_aafMatrix[1][2], bias.m_aafMatrix[1][3]};
float z[4] = { bias.m_aafMatrix[2][0], bias.m_aafMatrix[2][1], bias.m_aafMatrix[2][2], bias.m_aafMatrix[2][3]};
float w[4] = { bias.m_aafMatrix[3][0], bias.m_aafMatrix[3][1], bias.m_aafMatrix[3][2], bias.m_aafMatrix[3][3]};
glMatrixMode( GL_TEXTURE );
glTexGenfv( GL_S, GL_EYE_PLANE, x );
glTexGenfv( GL_T, GL_EYE_PLANE, y );
glTexGenfv( GL_R, GL_EYE_PLANE, z );
glTexGenfv( GL_Q, GL_EYE_PLANE, w );
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR );
glEnable( GL_TEXTURE_GEN_S );
glEnable( GL_TEXTURE_GEN_T );
glEnable( GL_TEXTURE_GEN_R );
glEnable( GL_TEXTURE_GEN_Q );
*/
NeoEngine::TexturePtr pnt;
pnt=(NeoEngine::TexturePtr) m_pkShadowMap->GetTexture();
NeoOGL::Texture *pkTexture = (NeoOGL::Texture*)(NeoEngine::Texture*)(pnt);
m_pkDevice->m_ppkTMU[0]->SetTexture( pkTexture );
glEnable(GL_NORMALIZE);
//Enable shadow comparison
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
//Shadow comparison should be true (ie not in shadow) if r<=texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_GEQUAL);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
//Shadow comparison should generate an INTENSITY result
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
//Set alpha test to discard false comparisons
//glAlphaFunc(GL_GEQUAL, 0.99f);
glAlphaFunc(GL_GEQUAL, 0.10f);
glEnable(GL_ALPHA_TEST);
int iOp = 0;
bool bLighting = false;
static Matrix kNativeView;
static Matrix kNativeModel;
kNativeView = m_pkDevice->GetViewMatrix();
glMatrixMode( GL_MODELVIEW );
/*
if( m_pkDevice->m_bIsRenderingTexture )
{
Matrix kMirrorXZ;
kMirrorXZ.m_aafMatrix[1][1] = -1.0f;
neoglLoadMatrixf( (float*)kMirrorXZ );
neoglMultMatrixf( (float*)kNativeView );
}
else
{
neoglLoadMatrixf( (float*)kNativeView );
}
*/
neoglLoadMatrixf( (float*)kNativeView );
glDisable( GL_LIGHTING );
bool bUseSort = !( m_bIsSky || ( m_pkDevice->m_pkCurTarget->m_uiFrameFlags & RenderDevice::NOSORT ) );
bool bPolygons = true;
unsigned int *puiOpIndex = m_kSorter.GetIndices();
for( iOp = 0; iOp < m_iNumOps; ++iOp )
{
int iIndex = !bUseSort ? iOp : puiOpIndex[ iOp ];
RenderPrimitive *pkOp = &m_ppkOpArray[ iIndex >> OpArray::ARRAYSHIFT ]->m_akOps[ iIndex & OpArray::ARRAYMASK ];
bPolygons = ( ( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLES ) || ( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLESTRIP ) );
VertexBufferGL *pkVertexBuffer = static_cast< VertexBufferGL* >( (NeoEngine::VertexBuffer*)pkOp->m_pkVertexBuffer );
PolygonBuffer *pkPolygonBuffer = pkOp->m_pkPolygonBuffer;
MaterialPass *pkMat = !pkOp->m_uiPass ? pkOp->m_pkMaterial : pkOp->m_pkMaterial->m_vpkPasses[ pkOp->m_uiPass - 1 ];
if( pkVertexBuffer->IsDirty() )
pkVertexBuffer->Upload();
if( pkPolygonBuffer && pkPolygonBuffer->IsDirty() )
pkPolygonBuffer->Upload();
//Set new modelview matrix
kNativeModel = pkOp->m_kModelMatrix;
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
neoglMultMatrixf( (float*)kNativeModel );
m_pkDevice->m_pkVertexBufferManager->SetBasePointers( pkVertexBuffer, pkMat->m_uiUVLayer );
m_pkDevice->m_kZBufferState.SetMode( pkMat->m_kZBufferMode.Get() & ZBufferMode::FUNCBITS, pkMat->m_kZBufferMode.Get() & ZBufferMode::MODEBITS );
//Set base blend state
//glBlendFunc( GL_ONE, GL_ZERO );
// glBlendFunc( GL_DST_COLOR, GL_ZERO);
//dario
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_DST_ALPHA);
//glBlendFunc( GL_ONE, GL_ONE);
//glColor4fv( (const float*)Color::BLUE );
glColor4f( 0.5f, 0.5f, 0.5f, 1.0f );
//Draw back faces into the shadow map
glCullFace(GL_BACK);
//Disable color writes, and use flat shading for speed
glShadeModel(GL_FLAT);
//Render up to this layer
if(bPolygons){
if( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLESTRIP )
glDrawElements( GL_TRIANGLE_STRIP, pkOp->m_uiNumPrimitives + 2, GL_UNSIGNED_SHORT, pkOp->m_pkPolygonStripBuffer->GetRenderData() );
else
glDrawElements( GL_TRIANGLES, pkOp->m_uiNumPrimitives * 3, GL_UNSIGNED_SHORT, pkOp->m_pkPolygonBuffer->GetRenderData() );
}else{
if( pkOp->m_ePrimitive == RenderPrimitive::LINES )
{
glLineWidth( pkOp->m_fSize );
glDrawArrays( GL_LINES, 0, pkOp->m_uiNumPrimitives * 2 );
}
else if( pkOp->m_ePrimitive == RenderPrimitive::LINESTRIP )
{
glLineWidth( pkOp->m_fSize );
glDrawArrays( GL_LINE_STRIP, 0, pkOp->m_uiNumPrimitives + 1 );
}
else if( pkOp->m_ePrimitive == RenderPrimitive::POINTS )
{
glPointSize( pkOp->m_fSize );
glDrawArrays( GL_POINTS, 0, pkOp->m_uiNumPrimitives );
}
else if( pkOp->m_ePrimitive == RenderPrimitive::POINTSPRITES )
{
glEnable( GL_POINT_SPRITE_ARB );
glPointSize( pkOp->m_fSize );
glDrawArrays( GL_POINTS, 0, pkOp->m_uiNumPrimitives );
glDisable( GL_POINT_SPRITE_ARB );
}
}
glPopMatrix();
}
if( bLighting )
{
glEnable( GL_LIGHTING );
}
glDisable( GL_POLYGON_OFFSET_FILL );
glMatrixMode( GL_TEXTURE );
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
//Disable textures and texgen
//glDisable(GL_TEXTURE_2D);
//------------------------------------
//glDisable(GL_BLEND);
neoglActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);
neoglActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);
neoglActiveTextureARB(GL_TEXTURE0_ARB);
//------------------------------------
//Restore other states
//glDisable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
glDisable( GL_POLYGON_OFFSET_FILL );
glDisable(GL_NORMALIZE);
}
void RenderQueue::ExecuteOps()
{
if (m_pkDevice->GetRenderShadowMap())
return RenderShadow();
if (m_pkDevice->GetZbufferRender())
return RenderZBuffer();
if (m_pkDevice->GetRenderShadowMapGLSL())
return RenderShadowGLSL();
int iOp = 0;
bool bLighting = false;
static Matrix kNativeView;
static Matrix kNativeModel;
/* If the render device has fog set for the scene, deal with that now */
if( m_pkDevice->m_kFogMode.m_iMode != FogMode::NONE )
{
GLint iMode;
int iMaterialFogMode = m_pkDevice->m_kFogMode.m_iMode;
m_pkDevice->m_kCurrentFogMode = m_pkDevice->m_kFogMode;
switch( iMaterialFogMode )
{
case FogMode::EXP:
iMode = GL_EXP;
break;
case FogMode::EXP2:
iMode = GL_EXP2;
break;
case FogMode::LINEAR:
iMode = GL_LINEAR;
break;
default:
glDisable( GL_FOG );
break;
}
if( iMaterialFogMode != FogMode::NONE )
{
glEnable( GL_FOG );
glFogi( GL_FOG_MODE, iMode );
int iMaterialFogHint = m_pkDevice->m_kFogMode.m_iHint;
int iHint;
switch( iMaterialFogHint )
{
case FogMode::DONTCARE:
iHint = GL_DONT_CARE;
break;
case FogMode::PERPIXEL:
iHint = GL_NICEST;
break;
case FogMode::PERVERTEX:
iHint = GL_FASTEST;
break;
}
glHint( GL_FOG_HINT, iHint );
glFogf( GL_FOG_DENSITY, m_pkDevice->m_kFogMode.m_fDensity );
glFogf( GL_FOG_START, m_pkDevice->m_kFogMode.m_fStart );
glFogf( GL_FOG_END, m_pkDevice->m_kFogMode.m_fEnd );
GLfloat afColor[ 4 ] =
{
m_pkDevice->m_kFogMode.m_kColor.r,
m_pkDevice->m_kFogMode.m_kColor.g,
m_pkDevice->m_kFogMode.m_kColor.b,
m_pkDevice->m_kFogMode.m_kColor.a
};
glFogfv( GL_FOG_COLOR, afColor );
}
}
kNativeView = m_pkDevice->GetViewMatrix();
if( m_bIsSky )
{
kNativeView[0][3] = kNativeView[1][3] = kNativeView[2][3] = 0.0f;
//Set sky zbuffer mode
m_pkDevice->m_kZBufferState.SetMode( ZBufferMode::LEQUAL, ZBufferMode::DISABLED );
glDepthRange( 1.0f, 1.0f );
}
glMatrixMode( GL_MODELVIEW );
/*
if( m_pkDevice->m_bIsRenderingTexture )
{
Matrix kMirrorXZ;
kMirrorXZ.m_aafMatrix[1][1] = -1.0f;
neoglLoadMatrixf( (float*)kMirrorXZ );
neoglMultMatrixf( (float*)kNativeView );
}
else
//*/
neoglLoadMatrixf( (float*)kNativeView );
if( !m_bIsSky && ( bLighting = ( m_pkDevice->m_uiNumLights != 0 ) ) )
{
unsigned int uiLight = 0;
unsigned int uiMax = MIN< unsigned int >( m_pkDevice->m_uiNumLights, m_pkDevice->m_uiMaxLights );
for( uiLight = 0; uiLight < uiMax; ++uiLight )
{
GLenum eLight = GLenum( GL_LIGHT0 + uiLight );
Light *pkLight = m_pkDevice->m_ppkLights[ uiLight ];
glLightfv( eLight, GL_AMBIENT, (float*)pkLight->m_kAmbient );
glLightfv( eLight, GL_DIFFUSE, (float*)pkLight->m_kDiffuse );
glLightfv( eLight, GL_SPECULAR, (float*)pkLight->m_kSpecular );
glLightf( eLight, GL_CONSTANT_ATTENUATION, pkLight->m_fConstantAttenuation );
glLightf( eLight, GL_LINEAR_ATTENUATION, pkLight->m_fLinearAttenuation );
glLightf( eLight, GL_QUADRATIC_ATTENUATION, pkLight->m_fQuadraticAttenuation );
if( pkLight->GetType() == Light::DIRECTIONAL )
{
Vector3d kDir = pkLight->GetSceneNode() ? -pkLight->GetSceneNode()->GetWorldTransform().GetColumn(2) : Vector3d( 0.0f, 0.0f, -1.0f );
float fDir[4]; fDir[0] = -kDir[0]; fDir[1] = -kDir[1]; fDir[2] = -kDir[2]; fDir[3] = 0.0f;
glLightfv( eLight, GL_POSITION, fDir );
}
else if( pkLight->GetType() == Light::POINT )
{
Vector3d kPos = pkLight->GetSceneNode() ? pkLight->GetSceneNode()->GetWorldTranslation() : Vector3d::ORIGO;
float fPos[4]; fPos[0] = kPos[0]; fPos[1] = kPos[1]; fPos[2] = kPos[2]; fPos[3] = 1.0f;
glLightfv( eLight, GL_POSITION, fPos );
}
glEnable( eLight );
}
for( ; uiLight < uiMax; ++uiLight )
glDisable( GLenum( GL_LIGHT0 + uiLight ) );
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, (const float*)&m_pkDevice->m_kAmbientLight );
glEnable( GL_LIGHTING );
}
else
glDisable( GL_LIGHTING );
bool bUseSort = !( m_bIsSky || ( m_pkDevice->m_pkCurTarget->m_uiFrameFlags & RenderDevice::NOSORT ) );
bool bPolygons = true;
unsigned int *puiOpIndex = m_kSorter.GetIndices();
glAlphaFunc ( GL_GREATER, 0.0f ) ;
glEnable ( GL_ALPHA_TEST ) ;
for( iOp = 0; iOp < m_iNumOps; ++iOp )
{
int iIndex = !bUseSort ? iOp : puiOpIndex[ iOp ];
RenderPrimitive *pkOp = &m_ppkOpArray[ iIndex >> OpArray::ARRAYSHIFT ]->m_akOps[ iIndex & OpArray::ARRAYMASK ];
bPolygons = ( ( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLES ) || ( pkOp->m_ePrimitive == RenderPrimitive::TRIANGLESTRIP ) );
//Make sure unit 0 is active
TextureUnit::SetActiveTextureUnit( 0 );
VertexBufferGL *pkVertexBuffer = static_cast< VertexBufferGL* >( (NeoEngine::VertexBuffer*)pkOp->m_pkVertexBuffer );
PolygonBuffer *pkPolygonBuffer = pkOp->m_pkPolygonBuffer;
MaterialPass *pkMat = !pkOp->m_uiPass ? pkOp->m_pkMaterial : pkOp->m_pkMaterial->m_vpkPasses[ pkOp->m_uiPass - 1 ];
/* If the material has fog information, let's deal with that now. */
if( !( pkMat->m_kFogMode == m_pkDevice->m_kCurrentFogMode ) && m_pkDevice->m_kFogMode.m_iMode == FogMode::NONE )
{
GLint iMode;
int iMaterialFogMode = pkMat->m_kFogMode.m_iMode;
m_pkDevice->m_kCurrentFogMode = pkMat->m_kFogMode;
switch( iMaterialFogMode )
{
case FogMode::EXP:
iMode = GL_EXP;
break;
case FogMode::EXP2:
iMode = GL_EXP2;
break;
case FogMode::LINEAR:
iMode = GL_LINEAR;
break;
default:
glDisable( GL_FOG );
break;
}
if( iMaterialFogMode != FogMode::NONE )
{
glEnable( GL_FOG );
glFogi( GL_FOG_MODE, iMode );
int iMaterialFogHint = pkMat->m_kFogMode.m_iHint;
int iHint;
switch( iMaterialFogHint )
{
case FogMode::DONTCARE:
iHint = GL_DONT_CARE;
break;
case FogMode::PERPIXEL:
iHint = GL_NICEST;
break;
case FogMode::PERVERTEX:
iHint = GL_FASTEST;
break;
}
glHint( GL_FOG_HINT, iHint );
glFogf( GL_FOG_DENSITY, pkMat->m_kFogMode.m_fDensity );
glFogf( GL_FOG_START, pkMat->m_kFogMode.m_fStart );
glFogf( GL_FOG_END, pkMat->m_kFogMode.m_fEnd );
GLfloat afColor[ 4 ] =
{
pkMat->m_kFogMode.m_kColor.r,
pkMat->m_kFogMode.m_kColor.g,
pkMat->m_kFogMode.m_kColor.b,
pkMat->m_kFogMode.m_kColor.a
};
glFogfv( GL_FOG_COLOR, afColor );
}
}
if( pkVertexBuffer->IsDirty() )
pkVertexBuffer->Upload();
if( pkPolygonBuffer && pkPolygonBuffer->IsDirty() )
pkPolygonBuffer->Upload();
//Set new modelview matrix
kNativeModel = pkOp->m_kModelMatrix;
if( m_bIsSky )
kNativeModel[0][3] = kNativeModel[1][3] = kNativeModel[2][3] = 0.0f;
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
neoglMultMatrixf( (float*)kNativeModel );
m_pkDevice->m_pkVertexBufferManager->SetBasePointers( pkVertexBuffer, pkMat->m_uiUVLayer );
//Set z buffer state if not sky (if sky, zbuffer state already set)
if( !m_bIsSky )
m_pkDevice->m_kZBufferState.SetMode( pkMat->m_kZBufferMode.Get() & ZBufferMode::FUNCBITS, pkMat->m_kZBufferMode.Get() & ZBufferMode::MODEBITS );
//Set base blend state
glBlendFunc( aeSrcBlendTable[ pkMat->m_kBlendMode.Get() & BlendMode::SRCBITS ], aeDestBlendTable[ ( pkMat->m_kBlendMode.Get() & BlendMode::DESTBITS ) >> 4 ] );
if( pkMat->m_pkProgramShader )
{
Shader *pkShader = static_cast< Shader* >( (NeoEngine::Shader*)pkMat->m_pkProgramShader );
pkShader->Bind( pkOp );
m_pkDevice->m_pkProgramShader = pkShader;
NeoOGL::Texture *pkTexture = (NeoOGL::Texture*)(NeoEngine::Texture*)pkMat->GetTexture();
m_pkDevice->m_ppkTMU[0]->SetTexture( pkTexture );
int iLayer = 1;
vector< TextureLayer* >::iterator ppkLayer = pkMat->m_vpkTextureLayers.begin();
vector< TextureLayer* >::iterator ppkLayerEnd = pkMat->m_vpkTextureLayers.end();
//We assume there are enough texture units!
for( ; ppkLayer != ppkLayerEnd; ++iLayer, ++ppkLayer )
{
pkTexture = (NeoOGL::Texture*)(NeoEngine::Texture*)(*ppkLayer)->GetTexture();
m_pkDevice->m_pkVertexBufferManager->SetTexLayerPointer(pkVertexBuffer,iLayer,(*ppkLayer)->m_uiUVLayer,false);
m_pkDevice->m_ppkTMU[ iLayer ]->SetTexture( pkTexture );
}
}
else
{
if( m_pkDevice->m_pkProgramShader )
{
m_pkDevice->m_pkProgramShader->Unbind();
m_pkDevice->m_pkProgramShader = 0;
}
if( !pkVertexBuffer->m_pkDiffuseElement )
{
if( bLighting && !pkOp->m_pkMaterial->m_bNoLighting )
{
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, (const float*)pkMat->m_kAmbient );
glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, (const float*)pkMat->m_kDiffuse );
glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, (const float*)pkMat->m_kSpecular );
glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, (const float*)pkMat->m_kEmission );
glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, pkMat->m_fShininess * 128.0f );
}
else
{
glColor4fv( (const float*)Color::WHITE );
}
}
if( pkMat->m_vpkTexMatrixGen.size() )
{
Matrix kMat;
vector<TextureMatrixGen*>::iterator ppkGen = pkMat->m_vpkTexMatrixGen.begin();
vector<TextureMatrixGen*>::iterator ppkEnd = pkMat->m_vpkTexMatrixGen.end();
for( ; ppkGen < ppkEnd; ++ppkGen )
(*ppkGen)->GenerateMatrix( &kMat );
m_pkDevice->m_ppkTMU[0]->SetTransform( &kMat );
}
else
m_pkDevice->m_ppkTMU[0]->SetTransform( 0 );
//Set base layer texture
NeoOGL::Texture *pkTexture = (NeoOGL::Texture*)(NeoEngine::Texture*)pkMat->GetTexture();
m_pkDevice->m_ppkTMU[0]->SetTexture( pkTexture );
m_pkDevice->m_ppkTMU[0]->SetTexGen( pkMat->m_eTexCoordGen );
if( pkTexture )
pkTexture->SetAddressMode( pkMat->m_uiUVAddress );
unsigned int uiLayer = 1;
//Render all layers for polygons
if( bPolygons )//&& m_pkDevice->m_bDrawPolygons )
{
vector< TextureLayer* >::iterator ppkLayer = pkMat->m_vpkTextureLayers.begin();
vector< TextureLayer* >::iterator ppkLayerEnd = pkMat->m_vpkTextureLayers.end();
for( uiLayer = 1; ppkLayer != ppkLayerEnd; ++uiLayer, ++ppkLayer )
{
TextureLayer *pkLayer = *ppkLayer;
if( ( uiLayer >= m_pkDevice->m_uiNumTMUs ) || !m_pkDevice->m_ppkTMU[ uiLayer ]->SetBlendMode( pkLayer->m_kBlendMode.Get() & BlendMode::SRCBITS, pkLayer->m_kBlendMode.Get() & BlendMode::DESTBITS, pkLayer->m_kBlendMode.m_fFactor ) )
{
for( ; uiLayer < m_pkDevice->m_uiNumTMUs; ++uiLayer )
{
m_pkDevice->m_ppkTMU[ uiLayer ]->Disable();
m_pkDevice->m_pkVertexBufferManager->SetTexLayerPointer( pkVertexBuffer, uiLayer, 0, true );
}
//Render up to this layer
RENDERPASS( false )
//Set new base layer
glBlendFunc( aeSrcBlendTable[ pkLayer->m_kBlendMode.Get() & BlendMode::SRCBITS ], aeDestBlendTable[ ( pkLayer->m_kBlendMode.Get() & BlendMode::DESTBITS ) >> 4 ] );
if( !m_bIsSky )
m_pkDevice->m_kZBufferState.SetMode( ZBufferMode::EQUAL, ZBufferMode::DISABLED );
uiLayer = 0;
}
pkTexture = (NeoOGL::Texture*)(NeoEngine::Texture*)pkLayer->GetTexture();
m_pkDevice->m_ppkTMU[ uiLayer ]->SetTexture( pkTexture );
m_pkDevice->m_ppkTMU[ uiLayer ]->SetTexGen( pkLayer->m_eTexCoordGen );
if( pkTexture )
pkTexture->SetAddressMode( pkLayer->m_uiUVAddress );
m_pkDevice->m_pkVertexBufferManager->SetTexLayerPointer( pkVertexBuffer, uiLayer, pkLayer->m_uiUVLayer, false );
if( pkLayer->m_vpkTexMatrixGen.size() )
{
Matrix kMat;
vector< TextureMatrixGen* >::iterator ppkGen = pkLayer->m_vpkTexMatrixGen.begin();
vector< TextureMatrixGen* >::iterator ppkGenEnd = pkLayer->m_vpkTexMatrixGen.end();
for( ; ppkGen != ppkGenEnd; ++ppkGen )
(*ppkGen)->GenerateMatrix( &kMat );
m_pkDevice->m_ppkTMU[ uiLayer ]->SetTransform( &kMat );
}
else
m_pkDevice->m_ppkTMU[ uiLayer ]->SetTransform( 0 );
}
}
for( ; uiLayer < m_pkDevice->m_uiNumTMUs; ++uiLayer )
{
m_pkDevice->m_ppkTMU[ uiLayer ]->Disable();
m_pkDevice->m_pkVertexBufferManager->SetTexLayerPointer( pkVertexBuffer, uiLayer, 0, true );
}
}
if( bPolygons )
{
if( pkOp->m_pkMaterial->m_bNoLighting && bLighting )
{
glDisable( GL_LIGHTING );
}
//Render final pass
RENDERPASS( true )
}
else
{
if( bLighting )
{
glDisable( GL_LIGHTING );
}
if( pkOp->m_ePrimitive == RenderPrimitive::LINES )
{
glLineWidth( pkOp->m_fSize );
glDrawArrays( GL_LINES, 0, pkOp->m_uiNumPrimitives * 2 );
}
else if( pkOp->m_ePrimitive == RenderPrimitive::LINESTRIP )
{
glLineWidth( pkOp->m_fSize );
glDrawArrays( GL_LINE_STRIP, 0, pkOp->m_uiNumPrimitives + 1 );
}
else if( pkOp->m_ePrimitive == RenderPrimitive::POINTS )
{
glPointSize( pkOp->m_fSize );
glDrawArrays( GL_POINTS, 0, pkOp->m_uiNumPrimitives );
}
else if( pkOp->m_ePrimitive == RenderPrimitive::POINTSPRITES )
{
glEnable( GL_POINT_SPRITE_ARB );
glPointSize( pkOp->m_fSize );
glDrawArrays( GL_POINTS, 0, pkOp->m_uiNumPrimitives );
glDisable( GL_POINT_SPRITE_ARB );
}
if( bLighting )
{
glEnable( GL_LIGHTING );
}
}
#ifdef NEOGL_ENABLE_STATISTICS
m_pkDevice->m_pkStats->m_uiTotalOps++;
#endif
//Cleanup
if( m_pkDevice->m_pkProgramShader )
{
m_pkDevice->m_pkProgramShader->Unbind();
m_pkDevice->m_pkProgramShader = 0;
}
{
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
}
}
//Reset depth range
glDisable ( GL_ALPHA_TEST ) ;
if( m_bIsSky )
glDepthRange( 0.0f, 1.0f );
}
};
See more files for this project here