mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-19 06:33:49 +00:00
Add OpenGL support.
This commit is contained in:
parent
c354f59b72
commit
dd08fd2e7d
55 changed files with 2957 additions and 802 deletions
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "platform/platform.h"
|
||||
#include "gfx/gl/gfxGLShader.h"
|
||||
#include "gfx/gl/gfxGLVertexAttribLocation.h"
|
||||
|
||||
#include "core/frameAllocator.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
|
|
@ -59,10 +60,11 @@ public:
|
|||
U32 mOffset;
|
||||
U32 mSize;
|
||||
S32 mSamplerNum;
|
||||
bool mInstancingConstant;
|
||||
};
|
||||
|
||||
GFXGLShaderConstHandle::GFXGLShaderConstHandle( GFXGLShader *shader )
|
||||
: mShader( shader ), mSamplerNum(-1)
|
||||
: mShader( shader ), mSamplerNum(-1), mInstancingConstant(false)
|
||||
{
|
||||
mValid = false;
|
||||
}
|
||||
|
|
@ -98,7 +100,7 @@ static U32 shaderConstTypeSize(GFXShaderConstType type)
|
|||
}
|
||||
|
||||
GFXGLShaderConstHandle::GFXGLShaderConstHandle( GFXGLShader *shader, const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum )
|
||||
: mShader(shader)
|
||||
: mShader(shader), mInstancingConstant(false)
|
||||
{
|
||||
reinit(desc, loc, samplerNum);
|
||||
}
|
||||
|
|
@ -109,6 +111,7 @@ void GFXGLShaderConstHandle::reinit( const GFXShaderConstDesc& desc, GLuint loc,
|
|||
mLocation = loc;
|
||||
mSamplerNum = samplerNum;
|
||||
mOffset = 0;
|
||||
mInstancingConstant = false;
|
||||
|
||||
U32 elemSize = shaderConstTypeSize(mDesc.constType);
|
||||
AssertFatal(elemSize, "GFXGLShaderConst::GFXGLShaderConst - elemSize is 0");
|
||||
|
|
@ -156,8 +159,12 @@ void GFXGLShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const Con
|
|||
|
||||
GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
|
||||
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
||||
|
||||
dMemcpy(mBuffer + _glHandle->mOffset, ¶m, sizeof(ConstType));
|
||||
U8 *buf = mBuffer + _glHandle->mOffset;
|
||||
|
||||
if(_glHandle->mInstancingConstant)
|
||||
buf = mInstPtr + _glHandle->mOffset;
|
||||
|
||||
dMemcpy(buf, ¶m, sizeof(ConstType));
|
||||
}
|
||||
|
||||
void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const F32 fv)
|
||||
|
|
@ -219,6 +226,7 @@ void GFXGLShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const Ali
|
|||
|
||||
GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
|
||||
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
||||
AssertFatal(!_glHandle->mInstancingConstant, "GFXGLShaderConstBuffer::set - Instancing not supported for array");
|
||||
const U8* fvBuffer = static_cast<const U8*>(fv.getBuffer());
|
||||
for(U32 i = 0; i < fv.size(); ++i)
|
||||
{
|
||||
|
|
@ -275,6 +283,7 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& ma
|
|||
|
||||
GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
|
||||
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
||||
AssertFatal(!_glHandle->mInstancingConstant || matType == GFXSCT_Float4x4, "GFXGLShaderConstBuffer::set - Only support GFXSCT_Float4x4 for instancing");
|
||||
|
||||
switch(matType)
|
||||
{
|
||||
|
|
@ -296,8 +305,18 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& ma
|
|||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[8] = mat[10];
|
||||
break;
|
||||
case GFXSCT_Float4x4:
|
||||
{
|
||||
if(_glHandle->mInstancingConstant)
|
||||
{
|
||||
MatrixF transposed;
|
||||
mat.transposeTo(transposed);
|
||||
dMemcpy( mInstPtr + _glHandle->mOffset, (const F32*)transposed, sizeof(MatrixF) );
|
||||
return;
|
||||
}
|
||||
|
||||
dMemcpy(mBuffer + _glHandle->mOffset, (const F32*)mat, sizeof(MatrixF));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
AssertFatal(false, "GFXGLShaderConstBuffer::set - Invalid matrix type");
|
||||
break;
|
||||
|
|
@ -310,8 +329,9 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF* ma
|
|||
AssertFatal(handle->isValid(), "GFXGLShaderConstBuffer::set - Handle is not valid!" );
|
||||
|
||||
GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
|
||||
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
||||
|
||||
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
||||
AssertFatal(!_glHandle->mInstancingConstant, "GFXGLShaderConstBuffer::set - Instancing not supported for matrix arrays");
|
||||
|
||||
switch (matrixType) {
|
||||
case GFXSCT_Float4x4:
|
||||
dMemcpy(mBuffer + _glHandle->mOffset, (F32*)mat, _glHandle->getSize());
|
||||
|
|
@ -393,6 +413,9 @@ bool GFXGLShader::_init()
|
|||
macros.increment();
|
||||
macros.last().name = "TORQUE_SM";
|
||||
macros.last().value = String::ToString( mjVer * 10 + mnVer );
|
||||
macros.increment();
|
||||
macros.last().name = "TORQUE_VERTEX_SHADER";
|
||||
macros.last().value = "";
|
||||
|
||||
// Default to true so we're "successful" if a vertex/pixel shader wasn't specified.
|
||||
bool compiledVertexShader = true;
|
||||
|
|
@ -401,6 +424,8 @@ bool GFXGLShader::_init()
|
|||
// Compile the vertex and pixel shaders if specified.
|
||||
if(!mVertexFile.isEmpty())
|
||||
compiledVertexShader = initShader(mVertexFile, true, macros);
|
||||
|
||||
macros.last().name = "TORQUE_PIXEL_SHADER";
|
||||
if(!mPixelFile.isEmpty())
|
||||
compiledPixelShader = initShader(mPixelFile, false, macros);
|
||||
|
||||
|
|
@ -408,6 +433,24 @@ bool GFXGLShader::_init()
|
|||
if(!compiledVertexShader || !compiledPixelShader)
|
||||
return false;
|
||||
|
||||
//bind vertex attributes
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Position, "vPosition");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Normal, "vNormal");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Color, "vColor");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Tangent, "vTangent");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TangentW, "vTangentW");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Binormal, "vBinormal");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord0, "vTexCoord0");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord1, "vTexCoord1");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord2, "vTexCoord2");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord3, "vTexCoord3");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord4, "vTexCoord4");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord5, "vTexCoord5");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord6, "vTexCoord6");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord7, "vTexCoord7");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord8, "vTexCoord8");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord9, "vTexCoord9");
|
||||
|
||||
// Link it!
|
||||
glLinkProgram( mProgram );
|
||||
|
||||
|
|
@ -463,6 +506,10 @@ void GFXGLShader::initConstantDescs()
|
|||
glGetProgramiv(mProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
|
||||
GLint maxNameLength;
|
||||
glGetProgramiv(mProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
|
||||
|
||||
if(!maxNameLength)
|
||||
return;
|
||||
|
||||
FrameTemp<GLchar> uniformName(maxNameLength);
|
||||
|
||||
for(U32 i = 0; i < numUniforms; i++)
|
||||
|
|
@ -546,17 +593,23 @@ void GFXGLShader::initHandles()
|
|||
|
||||
// Loop through all ConstantDescriptions,
|
||||
// if they aren't in the HandleMap add them, if they are reinitialize them.
|
||||
S32 assignedSamplerNum = 0;
|
||||
for ( U32 i = 0; i < mConstants.size(); i++ )
|
||||
{
|
||||
GFXShaderConstDesc &desc = mConstants[i];
|
||||
|
||||
// Index element 1 of the name to skip the '$' we inserted earier.
|
||||
U32 loc = glGetUniformLocation(mProgram, &desc.name.c_str()[1]);
|
||||
GLint loc = glGetUniformLocation(mProgram, &desc.name.c_str()[1]);
|
||||
|
||||
AssertFatal(loc != -1, "");
|
||||
|
||||
HandleMap::Iterator handle = mHandles.find(desc.name);
|
||||
S32 sampler = (desc.constType == GFXSCT_Sampler || desc.constType == GFXSCT_SamplerCube) ?
|
||||
assignedSamplerNum++ : -1;
|
||||
S32 sampler = -1;
|
||||
if(desc.constType == GFXSCT_Sampler || desc.constType == GFXSCT_SamplerCube)
|
||||
{
|
||||
S32 idx = mSamplerNamesOrdered.find_next(desc.name);
|
||||
AssertFatal(idx != -1, "");
|
||||
sampler = idx; //assignedSamplerNum++;
|
||||
}
|
||||
if ( handle != mHandles.end() )
|
||||
{
|
||||
handle->value->reinit( desc, loc, sampler );
|
||||
|
|
@ -599,10 +652,69 @@ void GFXGLShader::initHandles()
|
|||
// Set sampler number on our program.
|
||||
glUniform1i(handle->mLocation, handle->mSamplerNum);
|
||||
// Set sampler in constant buffer so it does not get unset later.
|
||||
dMemcpy(mConstBuffer + handle->mOffset, &handle->mLocation, handle->getSize());
|
||||
dMemcpy(mConstBuffer + handle->mOffset, &handle->mSamplerNum, handle->getSize());
|
||||
}
|
||||
}
|
||||
glUseProgram(0);
|
||||
|
||||
//instancing
|
||||
U32 offset = 0;
|
||||
for ( U32 i=0; i < mInstancingFormat.getElementCount(); i++ )
|
||||
{
|
||||
const GFXVertexElement &element = mInstancingFormat.getElement( i );
|
||||
|
||||
String constName = String::ToString( "$%s", element.getSemantic().c_str() );
|
||||
|
||||
HandleMap::Iterator handle = mHandles.find(constName);
|
||||
if ( handle != mHandles.end() )
|
||||
{
|
||||
AssertFatal(0, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
GFXShaderConstDesc desc;
|
||||
desc.name = constName;
|
||||
desc.arraySize = 1;
|
||||
switch(element.getType())
|
||||
{
|
||||
case GFXDeclType_Float4:
|
||||
desc.constType = GFXSCT_Float4;
|
||||
break;
|
||||
|
||||
default:
|
||||
desc.constType = GFXSCT_Float;
|
||||
break;
|
||||
}
|
||||
|
||||
GFXGLShaderConstHandle *h = new GFXGLShaderConstHandle( this, desc, -1, -1 );
|
||||
h->mInstancingConstant = true;
|
||||
h->mOffset = offset;
|
||||
mHandles[constName] = h;
|
||||
|
||||
offset += element.getSizeInBytes();
|
||||
++i;
|
||||
|
||||
// If this is a matrix we will have 2 or 3 more of these
|
||||
// semantics with the same name after it.
|
||||
for ( ; i < mInstancingFormat.getElementCount(); i++ )
|
||||
{
|
||||
const GFXVertexElement &nextElement = mInstancingFormat.getElement( i );
|
||||
if ( nextElement.getSemantic() != element.getSemantic() )
|
||||
{
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
++desc.arraySize;
|
||||
if(desc.arraySize == 4 && desc.constType == GFXSCT_Float4)
|
||||
{
|
||||
desc.arraySize = 1;
|
||||
desc.constType = GFXSCT_Float4x4;
|
||||
}
|
||||
offset += nextElement.getSizeInBytes();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
GFXShaderConstHandle* GFXGLShader::getShaderConstHandle(const String& name)
|
||||
|
|
@ -619,12 +731,26 @@ GFXShaderConstHandle* GFXGLShader::getShaderConstHandle(const String& name)
|
|||
}
|
||||
}
|
||||
|
||||
GFXShaderConstHandle* GFXGLShader::findShaderConstHandle(const String& name)
|
||||
{
|
||||
HandleMap::Iterator i = mHandles.find(name);
|
||||
if(i != mHandles.end())
|
||||
return i->value;
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GFXGLShader::setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer)
|
||||
{
|
||||
for(Vector<GFXGLShaderConstHandle*>::iterator i = mValidHandles.begin(); i != mValidHandles.end(); ++i)
|
||||
{
|
||||
GFXGLShaderConstHandle* handle = *i;
|
||||
AssertFatal(handle, "GFXGLShader::setConstantsFromBuffer - Null handle");
|
||||
|
||||
if(handle->mInstancingConstant)
|
||||
continue;
|
||||
|
||||
// Don't set if the value has not be changed.
|
||||
if(dMemcmp(mConstBuffer + handle->mOffset, buffer->mBuffer + handle->mOffset, handle->getSize()) == 0)
|
||||
|
|
@ -669,6 +795,9 @@ void GFXGLShader::setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer)
|
|||
case GFXSCT_Float4x4:
|
||||
glUniformMatrix4fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0,"");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -813,13 +942,34 @@ bool GFXGLShader::_loadShaderFromStream( GLuint shader,
|
|||
Vector<U32> lengths;
|
||||
|
||||
// The GLSL version declaration must go first!
|
||||
const char *versionDecl = "#version 120\r\n\r\n";
|
||||
const char *versionDecl = "#version 150\r\n";
|
||||
buffers.push_back( dStrdup( versionDecl ) );
|
||||
lengths.push_back( dStrlen( versionDecl ) );
|
||||
|
||||
if(gglHasExtension(EXT_gpu_shader4))
|
||||
{
|
||||
const char *extension = "#extension GL_EXT_gpu_shader4 : enable\r\n";
|
||||
buffers.push_back( dStrdup( extension ) );
|
||||
lengths.push_back( dStrlen( extension ) );
|
||||
}
|
||||
|
||||
if(gglHasExtension(ARB_gpu_shader5))
|
||||
{
|
||||
const char *extension = "#extension GL_ARB_gpu_shader5 : enable\r\n";
|
||||
buffers.push_back( dStrdup( extension ) );
|
||||
lengths.push_back( dStrlen( extension ) );
|
||||
}
|
||||
|
||||
const char *newLine = "\r\n";
|
||||
buffers.push_back( dStrdup( newLine ) );
|
||||
lengths.push_back( dStrlen( newLine ) );
|
||||
|
||||
// Now add all the macros.
|
||||
for( U32 i = 0; i < macros.size(); i++ )
|
||||
{
|
||||
if(macros[i].name.isEmpty()) // TODO OPENGL
|
||||
continue;
|
||||
|
||||
String define = String::ToString( "#define %s %s\n", macros[i].name.c_str(), macros[i].value.c_str() );
|
||||
buffers.push_back( dStrdup( define.c_str() ) );
|
||||
lengths.push_back( define.length() );
|
||||
|
|
@ -836,6 +986,17 @@ bool GFXGLShader::_loadShaderFromStream( GLuint shader,
|
|||
|
||||
glShaderSource(shader, buffers.size(), (const GLchar**)const_cast<const char**>(buffers.address()), NULL);
|
||||
|
||||
#if defined(TORQUE_DEBUG) && defined(TORQUE_DEBUG_GFX)
|
||||
FileStream stream;
|
||||
if ( !stream.open( path.getFullPath()+"_DEBUG", Torque::FS::File::Write ) )
|
||||
{
|
||||
AssertISV(false, avar("GFXGLShader::initShader - failed to write debug shader '%s'.", path.getFullPath().c_str()));
|
||||
}
|
||||
|
||||
for(int i = 0; i < buffers.size(); ++i)
|
||||
stream.writeText(buffers[i]);
|
||||
#endif
|
||||
|
||||
// Cleanup the shader source buffer.
|
||||
for ( U32 i=0; i < buffers.size(); i++ )
|
||||
dFree( buffers[i] );
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue