Merge branch 'GarageGames/development' into ueberengine-dev-3.10

Conflicts:
	Engine/source/app/version.h
	Engine/source/terrain/terrData.cpp
This commit is contained in:
Duion 2016-12-13 17:28:36 +01:00
commit 186604eb76
974 changed files with 121718 additions and 233088 deletions

View file

@ -92,7 +92,7 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
}
U32 mipLevels = faces->getPointer()->getMipLevels();
if (mipLevels > 1)
if (mipLevels > 1 && !compressed)
mAutoGenMips = true;
D3D11_TEXTURE2D_DESC desc;
@ -115,12 +115,15 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
{
AssertFatal(false, "GFXD3D11Cubemap:initStatic(GFXTexhandle *faces) - failed to create texcube texture");
}
for (U32 i = 0; i < CubeFaces; i++)
{
GFXD3D11TextureObject *texObj = static_cast<GFXD3D11TextureObject*>((GFXTextureObject*)faces[i]);
U32 subResource = D3D11CalcSubresource(0, i, mipLevels);
D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, subResource, 0, 0, 0, texObj->get2DTex(), 0, NULL);
for (U32 currentMip = 0; currentMip < mipLevels; currentMip++)
{
U32 subResource = D3D11CalcSubresource(currentMip, i, mipLevels);
D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, subResource, 0, 0, 0, texObj->get2DTex(), currentMip, NULL);
}
}
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;

File diff suppressed because it is too large Load diff

View file

@ -42,6 +42,8 @@
class PlatformWindow;
class GFXD3D11ShaderConstBuffer;
class OculusVRHMDDevice;
class D3D11OculusTexture;
//------------------------------------------------------------------------------
@ -53,6 +55,8 @@ class GFXD3D11Device : public GFXDevice
friend class GFXD3D11TextureObject;
friend class GFXD3D11TextureTarget;
friend class GFXD3D11WindowTarget;
friend class OculusVRHMDDevice;
friend class D3D11OculusTexture;
virtual GFXFormat selectSupportedFormat(GFXTextureProfile *profile,
const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter);

View file

@ -73,6 +73,7 @@ void GFXD3D11EnumTranslate::init()
GFXD3D11TextureFormat[GFXFormatD24FS8] = DXGI_FORMAT_UNKNOWN;
GFXD3D11TextureFormat[GFXFormatD16] = DXGI_FORMAT_D16_UNORM;
GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB] = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
GFXD3D11TextureFormat[GFXFormatR8G8B8A8_LINEAR_FORCE] = DXGI_FORMAT_R8G8B8A8_UNORM;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11TextureFilter[GFXTextureFilterNone] = D3D11_FILTER_MIN_MAG_MIP_POINT;
@ -152,5 +153,6 @@ void GFXD3D11EnumTranslate::init()
GFXD3D11DeclType[GFXDeclType_Float3] = DXGI_FORMAT_R32G32B32_FLOAT;
GFXD3D11DeclType[GFXDeclType_Float4] = DXGI_FORMAT_R32G32B32A32_FLOAT;
GFXD3D11DeclType[GFXDeclType_Color] = DXGI_FORMAT_B8G8R8A8_UNORM; // DXGI_FORMAT_R8G8B8A8_UNORM;
GFXD3D11DeclType[GFXDeclType_UByte4] = DXGI_FORMAT_R8G8B8A8_UINT;
}

View file

@ -150,9 +150,11 @@ bool GFXD3D11ConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstTyp
(
(pd.constType == GFXSCT_Float2x2 ||
pd.constType == GFXSCT_Float3x3 ||
pd.constType == GFXSCT_Float4x3 ||
pd.constType == GFXSCT_Float4x4) &&
(constType == GFXSCT_Float2x2 ||
constType == GFXSCT_Float3x3 ||
constType == GFXSCT_Float4x3 ||
constType == GFXSCT_Float4x4)
), "Mismatched const type!");
@ -161,6 +163,7 @@ bool GFXD3D11ConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstTyp
{
case GFXSCT_Float2x2:
case GFXSCT_Float3x3:
case GFXSCT_Float4x3:
case GFXSCT_Float4x4:
return setMatrix(pd, constType, size, data, basePointer);
break;
@ -201,6 +204,40 @@ bool GFXD3D11ConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
return false;
}
else if (pd.constType == GFXSCT_Float4x3)
{
F32 buffer[4 * 4];
const U32 csize = 48;
// Loop through and copy
bool ret = false;
U8* currDestPointer = basePointer + pd.offset;
const U8* currSourcePointer = static_cast<const U8*>(data);
const U8* endData = currSourcePointer + size;
while (currSourcePointer < endData)
{
#ifdef TORQUE_DOUBLE_CHECK_43MATS
Point4F col;
((MatrixF*)currSourcePointer)->getRow(3, &col);
AssertFatal(col.x == 0.0f && col.y == 0.0f && col.z == 0.0f && col.w == 1.0f, "3rd row used");
#endif
if (dMemcmp(currDestPointer, currSourcePointer, csize) != 0)
{
dMemcpy(currDestPointer, currSourcePointer, csize);
ret = true;
}
else if (pd.constType == GFXSCT_Float4x3)
{
ret = true;
}
currDestPointer += csize;
currSourcePointer += sizeof(MatrixF);
}
return ret;
}
else
{
PROFILE_SCOPE(GFXD3D11ConstBufferLayout_setMatrix_not4x4);
@ -480,8 +517,15 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF&
AssertFatal(!h->isSampler(), "Handle is sampler constant!" );
AssertFatal(h->mShader == mShader, "Mismatched shaders!");
MatrixF transposed;
mat.transposeTo(transposed);
MatrixF transposed;
if (matrixType == GFXSCT_Float4x3)
{
transposed = mat;
}
else
{
mat.transposeTo(transposed);
}
if (h->mInstancingConstant)
{
@ -510,9 +554,17 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF*
static Vector<MatrixF> transposed;
if (arraySize > transposed.size())
transposed.setSize(arraySize);
for (U32 i = 0; i < arraySize; i++)
mat[i].transposeTo(transposed[i]);
transposed.setSize(arraySize);
if (matrixType == GFXSCT_Float4x3)
{
dMemcpy(transposed.address(), mat, arraySize * sizeof(MatrixF));
}
else
{
for (U32 i = 0; i < arraySize; i++)
mat[i].transposeTo(transposed[i]);
}
// TODO: Maybe support this in the future?
if (h->mInstancingConstant)
@ -609,7 +661,6 @@ void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderB
ZeroMemory(&pConstData, sizeof(D3D11_MAPPED_SUBRESOURCE));
const U8* buf;
HRESULT hr;
U32 nbBuffers = 0;
if(mVertexConstBuffer->isDirty())
{
@ -1191,19 +1242,13 @@ bool GFXD3D11Shader::_convertShaderVariable(const D3D11_SHADER_TYPE_DESC &typeDe
case D3D_SVC_MATRIX_ROWS:
case D3D_SVC_MATRIX_COLUMNS:
{
switch (typeDesc.Columns)
switch (typeDesc.Rows)
{
case 3:
if (typeDesc.Rows == 3)
{
desc.constType = GFXSCT_Float3x3;
}
desc.constType = typeDesc.Columns == 4 ? GFXSCT_Float3x4 : GFXSCT_Float3x3;
break;
case 4:
if (typeDesc.Rows == 4)
{
desc.constType = GFXSCT_Float4x4;
}
desc.constType = typeDesc.Columns == 3 ? GFXSCT_Float4x3 : GFXSCT_Float4x4;
break;
}
}
@ -1514,6 +1559,9 @@ U32 GFXD3D11Shader::getAlignmentValue(const GFXShaderConstType constType) const
case GFXSCT_Float3x3 :
return mRowSizeF * 3;
break;
case GFXSCT_Float4x3:
return mRowSizeF * 3;
break;
case GFXSCT_Float4x4 :
return mRowSizeF * 4;
break;

View file

@ -97,9 +97,9 @@ void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *te
if( tex == GFXTextureTarget::sDefaultDepthStencil )
{
mTargets[slot] = D3D11->mDeviceDepthStencil;
mTargetViews[slot] = D3D11->mDeviceDepthStencilView;
mTargets[slot]->AddRef();
mTargetViews[slot]->AddRef();
mTargetViews[slot] = D3D11->mDeviceDepthStencilView;
mTargets[slot]->AddRef();
mTargetViews[slot]->AddRef();
}
else
{
@ -110,14 +110,14 @@ void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *te
// Grab the surface level.
if( slot == DepthStencil )
{
{
mTargets[slot] = d3dto->getSurface();
if ( mTargets[slot] )
mTargets[slot]->AddRef();
mTargetViews[slot] = d3dto->getDSView();
if( mTargetViews[slot])
mTargetViews[slot]->AddRef();
mTargetViews[slot] = d3dto->getDSView();
if( mTargetViews[slot])
mTargetViews[slot]->AddRef();
}
else
@ -126,12 +126,12 @@ void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *te
// if the surface that it needs to render to is different than the mip level
// in the actual texture. This will happen with MSAA.
if( d3dto->getSurface() == NULL )
{
{
mTargets[slot] = d3dto->get2DTex();
mTargets[slot]->AddRef();
mTargetViews[slot] = d3dto->getRTView();
mTargetViews[slot]->AddRef();
mTargets[slot] = d3dto->get2DTex();
mTargets[slot]->AddRef();
mTargetViews[slot] = d3dto->getRTView();
mTargetViews[slot]->AddRef();
}
else
{
@ -163,6 +163,13 @@ void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *te
mTargetSize = Point2I(sd.Width, sd.Height);
S32 format = sd.Format;
if (format == DXGI_FORMAT_R8G8B8A8_TYPELESS || format == DXGI_FORMAT_B8G8R8A8_TYPELESS)
{
mTargetFormat = GFXFormatR8G8B8A8;
return;
}
GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format );
mTargetFormat = (GFXFormat)format;
}
@ -276,7 +283,7 @@ void GFXD3D11TextureTarget::resolve()
if (mResolveTargets[i])
{
D3D11_TEXTURE2D_DESC desc;
mTargets[i]->GetDesc(&desc);
mTargets[i]->GetDesc(&desc);
D3D11DEVICECONTEXT->CopySubresourceRegion(mResolveTargets[i]->get2DTex(), 0, 0, 0, 0, mTargets[i], 0, NULL);
}
}
@ -400,10 +407,10 @@ void GFXD3D11WindowTarget::activate()
void GFXD3D11WindowTarget::resolveTo(GFXTextureObject *tex)
{
GFXDEBUGEVENT_SCOPE(GFXPCD3D11WindowTarget_resolveTo, ColorI::RED);
GFXDEBUGEVENT_SCOPE(GFXPCD3D11WindowTarget_resolveTo, ColorI::RED);
D3D11_TEXTURE2D_DESC desc;
ID3D11Texture2D* surf = ((GFXD3D11TextureObject*)(tex))->get2DTex();
surf->GetDesc(&desc);
D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, D3D11->mDeviceBackbuffer, 0, desc.Format);
D3D11_TEXTURE2D_DESC desc;
ID3D11Texture2D* surf = ((GFXD3D11TextureObject*)(tex))->get2DTex();
surf->GetDesc(&desc);
D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, D3D11->mDeviceBackbuffer, 0, desc.Format);
}

View file

@ -180,8 +180,8 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp)
// check format limitations
// at the moment we only support RGBA for the source (other 4 byte formats should
// be easy to add though)
AssertFatal(mFormat == GFXFormatR8G8B8A8, "copyToBmp: invalid format");
if (mFormat != GFXFormatR8G8B8A8)
AssertFatal(mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE, "copyToBmp: invalid format");
if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE)
return false;
PROFILE_START(GFXD3D11TextureObject_copyToBmp);
@ -197,7 +197,7 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp)
const U32 sourceBytesPerPixel = 4;
U32 destBytesPerPixel = 0;
if(bmp->getFormat() == GFXFormatR8G8B8A8)
if (bmp->getFormat() == GFXFormatR8G8B8A8 || bmp->getFormat() == GFXFormatR8G8B8A8_LINEAR_FORCE)
destBytesPerPixel = 4;
else if(bmp->getFormat() == GFXFormatR8G8B8)
destBytesPerPixel = 3;

View file

@ -166,6 +166,7 @@ inline void GFXD3D9Device::setupGenericShaders( GenericShaderType type /* = GSCo
shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/modColorTextureV.hlsl");
shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/modColorTextureP.hlsl");
shaderData->setSamplerName("$diffuseMap", 0);
shaderData->setField("pixVersion", "3.0");
shaderData->registerObject();
mGenericShader[GSModColorTexture] = shaderData->getShader();
@ -176,6 +177,7 @@ inline void GFXD3D9Device::setupGenericShaders( GenericShaderType type /* = GSCo
shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/addColorTextureV.hlsl");
shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/addColorTextureP.hlsl");
shaderData->setSamplerName("$diffuseMap", 0);
shaderData->setField("pixVersion", "3.0");
shaderData->registerObject();
mGenericShader[GSAddColorTexture] = shaderData->getShader();
@ -186,6 +188,7 @@ inline void GFXD3D9Device::setupGenericShaders( GenericShaderType type /* = GSCo
shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", "shaders/common/fixedFunction/textureV.hlsl");
shaderData->setField("DXPixelShaderFile", "shaders/common/fixedFunction/textureP.hlsl");
shaderData->setSamplerName("$diffuseMap", 0);
shaderData->setField("pixVersion", "3.0");
shaderData->registerObject();
mGenericShader[GSTexture] = shaderData->getShader();
@ -626,6 +629,8 @@ void GFXD3D9Device::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
mVolatileVB = NULL;
}
U32 offset = d3dBuffer && stream != 0 ? d3dBuffer->mVolatileStart * d3dBuffer->mVertexSize : 0;
// NOTE: We do not use the stream offset here for stream 0
// as that feature is *supposedly* not as well supported as
// using the start index in drawPrimitive.
@ -635,7 +640,7 @@ void GFXD3D9Device::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
D3D9Assert( mD3DDevice->SetStreamSource( stream,
d3dBuffer ? d3dBuffer->vb : NULL,
d3dBuffer && stream != 0 ? d3dBuffer->mVolatileStart * d3dBuffer->mVertexSize : 0,
offset,
d3dBuffer ? d3dBuffer->mVertexSize : 0 ),
"GFXD3D9Device::setVertexStream - Failed to set stream source." );
}
@ -926,10 +931,12 @@ GFXVertexDecl* GFXD3D9Device::allocVertexDecl( const GFXVertexFormat *vertexForm
U32 elemCount = vertexFormat->getElementCount();
U32 offsets[4] = { 0 };
U32 stream;
S32 i = 0;
S32 elemIdx = 0;
D3DVERTEXELEMENT9 *vd = new D3DVERTEXELEMENT9[ elemCount + 1 ];
for ( U32 i=0; i < elemCount; i++ )
for ( i=0; elemIdx < elemCount; i++, elemIdx++ )
{
const GFXVertexElement &element = vertexFormat->getElement( i );
const GFXVertexElement &element = vertexFormat->getElement( elemIdx );
stream = element.getStreamIndex();
@ -952,6 +959,18 @@ GFXVertexDecl* GFXD3D9Device::allocVertexDecl( const GFXVertexFormat *vertexForm
vd[i].Usage = D3DDECLUSAGE_TANGENT;
else if ( element.isSemantic( GFXSemantic::BINORMAL ) )
vd[i].Usage = D3DDECLUSAGE_BINORMAL;
else if ( element.isSemantic( GFXSemantic::BLENDINDICES ) )
{
vd[i].Usage = D3DDECLUSAGE_BLENDINDICES;
vd[i].UsageIndex = element.getSemanticIndex();
}
else if ( element.isSemantic( GFXSemantic::BLENDWEIGHT ) )
{
vd[i].Usage = D3DDECLUSAGE_BLENDWEIGHT;
vd[i].UsageIndex = element.getSemanticIndex();
}
else if ( element.isSemantic( GFXSemantic::PADDING ) )
i--;
else
{
// Anything that falls thru to here will be a texture coord.
@ -963,7 +982,7 @@ GFXVertexDecl* GFXD3D9Device::allocVertexDecl( const GFXVertexFormat *vertexForm
}
D3DVERTEXELEMENT9 declEnd = D3DDECL_END();
vd[elemCount] = declEnd;
vd[i] = declEnd;
decl = new D3D9VertexDecl();
D3D9Assert( mD3DDevice->CreateVertexDeclaration( vd, &decl->decl ),

View file

@ -112,3 +112,4 @@ void GFXD3D9PrimitiveBuffer::resurrect()
usage , GFXD3D9IndexFormat[GFXIndexFormat16], pool, &ib, 0),
"GFXD3D9PrimitiveBuffer::resurrect - Failed to allocate an index buffer.");
}

View file

@ -35,7 +35,6 @@ class GFXD3D9PrimitiveBuffer : public GFXPrimitiveBuffer
public:
IDirect3DIndexBuffer9 *ib;
StrongRefPtr<GFXD3D9PrimitiveBuffer> mVolatileBuffer;
U32 mVolatileStart;
#ifdef TORQUE_DEBUG
#define _PBGuardString "GFX_PRIMTIVE_BUFFER_GUARD_STRING"

View file

@ -35,6 +35,8 @@
#include "core/stream/fileStream.h"
#include "core/util/safeDelete.h"
#include "console/console.h"
#include "math/mMathFn.h"
using namespace Torque;
@ -172,6 +174,39 @@ bool GFXD3D9ShaderBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
return false;
}
else if (pd.constType == GFXSCT_Float4x3)
{
const U32 csize = 48;
// Loop through and copy
bool ret = false;
U8* currDestPointer = basePointer + pd.offset;
const U8* currSourcePointer = static_cast<const U8*>(data);
const U8* endData = currSourcePointer + size;
while (currSourcePointer < endData)
{
#ifdef TORQUE_DOUBLE_CHECK_43MATS
Point4F col;
((MatrixF*)currSourcePointer)->getRow(3, &col);
AssertFatal(col.x == 0.0f && col.y == 0.0f && col.z == 0.0f && col.w == 1.0f, "3rd row used");
#endif
if (dMemcmp(currDestPointer, currSourcePointer, csize) != 0)
{
dMemcpy(currDestPointer, currSourcePointer, csize);
ret = true;
}
else if (pd.constType == GFXSCT_Float4x3)
{
ret = true;
}
currDestPointer += csize;
currSourcePointer += sizeof(MatrixF);
}
return ret;
}
else
{
PROFILE_SCOPE(GFXD3D9ShaderBufferLayout_setMatrix_not4x4);
@ -186,6 +221,9 @@ bool GFXD3D9ShaderBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
case GFXSCT_Float3x3 :
csize = 48;
break;
case GFXSCT_Float3x4 :
csize = 64;
break;
default:
AssertFatal(false, "Unhandled case!");
return false;
@ -204,6 +242,10 @@ bool GFXD3D9ShaderBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
dMemcpy(currDestPointer, currSourcePointer, csize);
ret = true;
}
else if (pd.constType == GFXSCT_Float4x3)
{
ret = true;
}
currDestPointer += csize;
currSourcePointer += sizeof(MatrixF);
@ -390,8 +432,15 @@ void GFXD3D9ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF&
AssertFatal(!h->isSampler(), "Handle is sampler constant!" );
AssertFatal(h->mShader == mShader, "Mismatched shaders!");
MatrixF transposed;
mat.transposeTo(transposed);
MatrixF transposed;
if (matrixType == GFXSCT_Float4x3)
{
transposed = mat;
}
else
{
mat.transposeTo(transposed);
}
if (h->mInstancingConstant)
{
@ -420,9 +469,17 @@ void GFXD3D9ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF*
static Vector<MatrixF> transposed;
if (arraySize > transposed.size())
transposed.setSize(arraySize);
for (U32 i = 0; i < arraySize; i++)
mat[i].transposeTo(transposed[i]);
transposed.setSize(arraySize);
if (matrixType == GFXSCT_Float4x3)
{
dMemcpy(transposed.address(), mat, arraySize * sizeof(MatrixF));
}
else
{
for (U32 i = 0; i < arraySize; i++)
mat[i].transposeTo(transposed[i]);
}
// TODO: Maybe support this in the future?
if (h->mInstancingConstant)
@ -1069,13 +1126,43 @@ void GFXD3D9Shader::_getShaderConstants( ID3DXConstantTable *table,
case D3DXPC_MATRIX_ROWS :
case D3DXPC_MATRIX_COLUMNS :
{
switch (constantDesc.RegisterCount)
S32 fd, sd;
fd = constantDesc.RegisterCount / constantDesc.Elements;
sd = constantDesc.Class == D3DXPC_MATRIX_ROWS ? constantDesc.Columns : constantDesc.Rows;
switch (fd)
{
case 2 :
AssertFatal(sd == 2, "non-square 2x? mats not supported");
desc.constType = GFXSCT_Float2x2;
break;
case 3 :
desc.constType = GFXSCT_Float3x3;
switch (sd)
{
case 3 :
desc.constType = GFXSCT_Float3x3;
break;
case 4 :
desc.constType = GFXSCT_Float4x3;
break;
default:
AssertFatal(false, "Unsupported matrix size");
break;
}
break;
case 4 :
desc.constType = GFXSCT_Float4x4;
switch (sd)
{
case 3:
desc.constType = GFXSCT_Float3x4;
break;
case 4:
desc.constType = GFXSCT_Float4x4;
break;
default:
AssertFatal(false, "Unsupported matrix size");
break;
}
break;
}
}
@ -1436,9 +1523,15 @@ U32 GFXD3D9Shader::getAlignmentValue(const GFXShaderConstType constType) const
case GFXSCT_Float3x3 :
return mRowSizeF * 3;
break;
case GFXSCT_Float3x4 :
return mRowSizeF * 4;
break;
case GFXSCT_Float4x4 :
return mRowSizeF * 4;
break;
case GFXSCT_Float4x3 :
return mRowSizeF * 3;
break;
//// Scalar
case GFXSCT_Int :
case GFXSCT_Int2 :

View file

@ -228,4 +228,3 @@ void GFXD3D9VertexBuffer::resurrect()
"GFXD3D9VertexBuffer::resurrect - Failed to allocate VB" );
}
}

View file

@ -115,6 +115,8 @@ void GFXD3D9EnumTranslate::init()
GFXD3D9TextureFormat[GFXFormatD24FS8] = D3DFMT_D24FS8;
GFXD3D9TextureFormat[GFXFormatD16] = D3DFMT_D16;
GFXD3D9TextureFormat[GFXFormatR8G8B8A8_SRGB] = D3DFMT_UNKNOWN;
GFXD3D9TextureFormat[GFXFormatR8G8B8A8_LINEAR_FORCE] = D3DFMT_A8R8G8B8;
VALIDATE_LOOKUPTABLE( GFXD3D9TextureFormat, GFXFormat);
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
@ -372,6 +374,7 @@ void GFXD3D9EnumTranslate::init()
GFXD3D9DeclType[GFXDeclType_Float3] = D3DDECLTYPE_FLOAT3;
GFXD3D9DeclType[GFXDeclType_Float4] = D3DDECLTYPE_FLOAT4;
GFXD3D9DeclType[GFXDeclType_Color] = D3DDECLTYPE_D3DCOLOR;
GFXD3D9DeclType[GFXDeclType_UByte4] = D3DDECLTYPE_UBYTE4;
VALIDATE_LOOKUPTABLE( GFXD3D9DeclType, GFXDeclType );
}

View file

@ -27,6 +27,7 @@
void GFXD3D9PrimitiveBuffer::lock(U32 indexStart, U32 indexEnd, void **indexPtr)
{
AssertFatal(!mLocked, "GFXD3D9PrimitiveBuffer::lock - Can't lock a primitive buffer more than once!");
mLocked = true;
U32 flags=0;
switch(mBufferType)

View file

@ -293,6 +293,7 @@ void GBitmap::allocateBitmap(const U32 in_width, const U32 in_height, const bool
break;
case GFXFormatR8G8B8: mBytesPerPixel = 3;
break;
case GFXFormatR8G8B8A8_LINEAR_FORCE:
case GFXFormatR8G8B8X8:
case GFXFormatR8G8B8A8: mBytesPerPixel = 4;
break;

View file

@ -328,13 +328,14 @@ static bool _writePNG(GBitmap *bitmap, Stream &stream, U32 compressionLevel, U32
format == GFXFormatR8G8B8A8 ||
format == GFXFormatR8G8B8X8 ||
format == GFXFormatA8 ||
format == GFXFormatR5G6B5, "_writePNG: ONLY RGB bitmap writing supported at this time.");
format == GFXFormatR5G6B5 ||
format == GFXFormatR8G8B8A8_LINEAR_FORCE, "_writePNG: ONLY RGB bitmap writing supported at this time.");
if ( format != GFXFormatR8G8B8 &&
format != GFXFormatR8G8B8A8 &&
format != GFXFormatR8G8B8X8 &&
format != GFXFormatA8 &&
format != GFXFormatR5G6B5 )
format != GFXFormatR5G6B5 && format != GFXFormatR8G8B8A8_LINEAR_FORCE)
return false;
png_structp png_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING,
@ -381,7 +382,7 @@ static bool _writePNG(GBitmap *bitmap, Stream &stream, U32 compressionLevel, U32
NULL, // compression type
NULL); // filter type
}
else if (format == GFXFormatR8G8B8A8 || format == GFXFormatR8G8B8X8)
else if (format == GFXFormatR8G8B8A8 || format == GFXFormatR8G8B8X8 || format == GFXFormatR8G8B8A8_LINEAR_FORCE)
{
png_set_IHDR(png_ptr, info_ptr,
width, height, // the width & height

View file

@ -80,9 +80,13 @@ bool GenericConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstType
(
( pd.constType == GFXSCT_Float2x2 ||
pd.constType == GFXSCT_Float3x3 ||
pd.constType == GFXSCT_Float3x4 ||
pd.constType == GFXSCT_Float4x3 ||
pd.constType == GFXSCT_Float4x4 ) &&
( constType == GFXSCT_Float2x2 ||
constType == GFXSCT_Float3x3 ||
constType == GFXSCT_Float3x3 ||
constType == GFXSCT_Float3x4 ||
constType == GFXSCT_Float4x3 ||
constType == GFXSCT_Float4x4 )
), "Mismatched const type!" );
@ -91,6 +95,7 @@ bool GenericConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstType
{
case GFXSCT_Float2x2 :
case GFXSCT_Float3x3 :
case GFXSCT_Float4x3 :
case GFXSCT_Float4x4 :
return setMatrix(pd, constType, size, data, basePointer);
break;

View file

@ -190,6 +190,8 @@ public:
{
AssertFatal( matrixType == GFXSCT_Float2x2 ||
matrixType == GFXSCT_Float3x3 ||
matrixType == GFXSCT_Float3x4 ||
matrixType == GFXSCT_Float4x3 ||
matrixType == GFXSCT_Float4x4,
"GenericConstBuffer::set() - Invalid matrix type!" );
@ -200,6 +202,8 @@ public:
{
AssertFatal( matrixType == GFXSCT_Float2x2 ||
matrixType == GFXSCT_Float3x3 ||
matrixType == GFXSCT_Float3x4 ||
matrixType == GFXSCT_Float4x3 ||
matrixType == GFXSCT_Float4x4,
"GenericConstBuffer::set() - Invalid matrix type!" );

View file

@ -35,6 +35,12 @@
#include "core/util/delegate.h"
#endif
struct GFXAdapterLUID
{
unsigned long LowPart;
long HighPart;
};
struct GFXAdapter
{
public:
@ -58,6 +64,9 @@ public:
/// Supported shader model. 0.f means none supported.
F32 mShaderModel;
/// LUID for windows oculus support
GFXAdapterLUID mLUID;
const char * getName() const { return mName; }
const char * getOutputName() const { return mOutputName; }
GFXAdapterType mType;
@ -72,6 +81,7 @@ public:
mOutputName[0] = 0;
mShaderModel = 0.f;
mIndex = 0;
dMemset(&mLUID, '\0', sizeof(mLUID));
}
~GFXAdapter()

View file

@ -232,3 +232,14 @@ DefineEngineStaticMethod( GFXCardProfilerAPI, queryProfile, S32, ( const char *n
{
return (S32)GFX->getCardProfiler()->queryProfile( name, (U32)defaultValue );
}
DefineEngineStaticMethod( GFXCardProfilerAPI, getBestDepthFormat, String, (),,
"Returns the card name." )
{
if (GFX->getCardProfiler()->queryProfile("GL::Workaround::intel_mac_depth", false))
return "GFXFormatD16";
else
return "GFXFormatD24S8";
}

View file

@ -160,7 +160,8 @@ GFXDevice::GFXDevice()
// misc
mAllowRender = true;
mCurrentRenderStyle = RS_Standard;
mCurrentProjectionOffset = Point2F::Zero;
mCurrentStereoTarget = -1;
mStereoHeadTransform = MatrixF(1);
mCanCurrentlyRender = false;
mInitialized = false;
@ -1320,7 +1321,7 @@ DefineEngineFunction( getBestHDRFormat, GFXFormat, (),,
// Figure out the best HDR format. This is the smallest
// format which supports blending and filtering.
Vector<GFXFormat> formats;
formats.push_back( GFXFormatR10G10B10A2 );
//formats.push_back( GFXFormatR10G10B10A2 ); TODO: replace with SRGB format once DX9 is gone - BJR
formats.push_back( GFXFormatR16G16B16A16F );
formats.push_back( GFXFormatR16G16B16A16 );
GFXFormat format = GFX->selectSupportedFormat( &GFXDefaultRenderTargetProfile,

View file

@ -219,6 +219,12 @@ public:
/// The device has started rendering a frame's field (such as for side-by-side rendering)
deStartOfField,
/// left stereo frame has been rendered
deLeftStereoFrameRendered,
/// right stereo frame has been rendered
deRightStereoFrameRendered,
/// The device is about to finish rendering a frame's field
deEndOfField,
};
@ -248,6 +254,7 @@ public:
{
RS_Standard = 0,
RS_StereoSideBySide = (1<<0), // Render into current Render Target side-by-side
RS_StereoSeparate = (1<<1) // Render in two separate passes (then combined by vr compositor)
};
enum GFXDeviceLimits
@ -281,13 +288,19 @@ protected:
/// The style of rendering that is to be performed, based on GFXDeviceRenderStyles
U32 mCurrentRenderStyle;
/// The current projection offset. May be used during side-by-side rendering, for example.
Point2F mCurrentProjectionOffset;
/// Current stereo target being rendered to
S32 mCurrentStereoTarget;
/// Eye offset used when using a stereo rendering style
Point3F mStereoEyeOffset[NumStereoPorts];
/// Center matrix for head
MatrixF mStereoHeadTransform;
/// Left and right matrix for eyes
MatrixF mStereoEyeTransforms[NumStereoPorts];
/// Inverse of mStereoEyeTransforms
MatrixF mInverseStereoEyeTransforms[NumStereoPorts];
/// Fov port settings
@ -338,21 +351,25 @@ public:
/// Retrieve the current rendering style based on GFXDeviceRenderStyles
U32 getCurrentRenderStyle() const { return mCurrentRenderStyle; }
/// Retrieve the current stereo target being rendered to
S32 getCurrentStereoTarget() const { return mCurrentStereoTarget; }
/// Set the current rendering style, based on GFXDeviceRenderStyles
void setCurrentRenderStyle(U32 style) { mCurrentRenderStyle = style; }
/// Set the current projection offset used during stereo rendering
const Point2F& getCurrentProjectionOffset() { return mCurrentProjectionOffset; }
/// Get the current projection offset used during stereo rendering
void setCurrentProjectionOffset(const Point2F& offset) { mCurrentProjectionOffset = offset; }
/// Set the current stereo target being rendered to (in case we're doing anything with postfx)
void setCurrentStereoTarget(const F32 targetId) { mCurrentStereoTarget = targetId; }
/// Get the current eye offset used during stereo rendering
const Point3F* getStereoEyeOffsets() { return mStereoEyeOffset; }
const MatrixF& getStereoHeadTransform() { return mStereoHeadTransform; }
const MatrixF* getStereoEyeTransforms() { return mStereoEyeTransforms; }
const MatrixF* getInverseStereoEyeTransforms() { return mInverseStereoEyeTransforms; }
/// Sets the head matrix for stereo rendering
void setStereoHeadTransform(const MatrixF &mat) { mStereoHeadTransform = mat; }
/// Set the current eye offset used during stereo rendering
void setStereoEyeOffsets(Point3F *offsets) { dMemcpy(mStereoEyeOffset, offsets, sizeof(Point3F) * NumStereoPorts); }
@ -391,6 +408,8 @@ public:
}
setViewport(mStereoViewports[eyeId]);
}
mCurrentStereoTarget = eyeId;
}
GFXCardProfiler* getCardProfiler() const { return mCardProfiler; }
@ -462,7 +481,7 @@ public:
/// Returns the first format from the list which meets all
/// the criteria of the texture profile and query options.
virtual GFXFormat selectSupportedFormat(GFXTextureProfile *profile,
const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter) = 0;
const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter) = 0;
/// @}

View file

@ -61,6 +61,7 @@ void GFXDrawUtil::_setupStateBlocks()
bitmapStretchSR.setZReadWrite(false);
bitmapStretchSR.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
bitmapStretchSR.samplersDefined = true;
bitmapStretchSR.setColorWrites(true, true, true, false); // NOTE: comment this out if alpha write is needed
// Linear: Create wrap SB
bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getWrapLinear();

View file

@ -48,6 +48,7 @@ enum GFXBufferType
///< allowed.
GFXBufferTypeVolatile, ///< Volatile vertex or index buffers are meant for vertices or indices that are essentially
///< only used once. They can be resized without any performance penalty.
GFXBufferTypeImmutable, ///< Immutable buffers must specify the data when creating the buffer. Cannot be modified.
GFXBufferType_COUNT ///< Number of buffer types.
@ -191,6 +192,12 @@ enum GFXFormat
GFXFormatD24S8,
GFXFormatD24FS8,
// sRGB formats
GFXFormatR8G8B8A8_SRGB,
// Guaranteed RGBA8 (for apis which really dont like bgr)
GFXFormatR8G8B8A8_LINEAR_FORCE,
// 64 bit texture formats...
GFXFormatR16G16B16A16,// first in group...
GFXFormatR16G16B16A16F,
@ -205,9 +212,6 @@ enum GFXFormat
GFXFormatDXT4,
GFXFormatDXT5,
// sRGB formats
GFXFormatR8G8B8A8_SRGB,
GFXFormat_COUNT,
GFXFormat_8BIT = GFXFormatA8,
@ -581,7 +585,9 @@ enum GFXShaderConstType
GFXSCT_Float4,
// Matrices
GFXSCT_Float2x2,
GFXSCT_Float3x3,
GFXSCT_Float3x3,
GFXSCT_Float3x4,
GFXSCT_Float4x3,
GFXSCT_Float4x4,
// Scalar
GFXSCT_Int,
@ -621,6 +627,9 @@ enum GFXDeclType
/// @see GFXVertexColor
GFXDeclType_Color,
/// Four-component, packed, unsigned bytes ranged 0-255
GFXDeclType_UByte4,
/// The count of total GFXDeclTypes.
GFXDeclType_COUNT,
};

View file

@ -50,6 +50,8 @@ FontRenderBatcher::FontRenderBatcher() : mStorage(8096)
// result in the text always being black. This may not be the case in OpenGL
// so it may have to change. -bramage
f.samplers[0].textureColorOp = GFXTOPAdd;
f.setColorWrites(true, true, true, false); // NOTE: comment this out if alpha write is needed
mFontSB = GFX->createStateBlock(f);
}
}

View file

@ -198,6 +198,22 @@ GFXAdapter* GFXInit::getAdapterOfType( GFXAdapterType type, const char* outputDe
return NULL;
}
GFXAdapter* GFXInit::getAdapterOfType(GFXAdapterType type, S32 outputDeviceIndex)
{
for (U32 i = 0; i < smAdapters.size(); i++)
{
if (smAdapters[i]->mType == type)
{
if (smAdapters[i]->mIndex == outputDeviceIndex)
{
return smAdapters[i];
}
}
}
return NULL;
}
GFXAdapter* GFXInit::chooseAdapter( GFXAdapterType type, const char* outputDevice)
{
GFXAdapter* adapter = GFXInit::getAdapterOfType(type, outputDevice);
@ -219,6 +235,27 @@ GFXAdapter* GFXInit::chooseAdapter( GFXAdapterType type, const char* outputDevic
return adapter;
}
GFXAdapter* GFXInit::chooseAdapter(GFXAdapterType type, S32 outputDeviceIndex)
{
GFXAdapter* adapter = GFXInit::getAdapterOfType(type, outputDeviceIndex);
if (!adapter && type != OpenGL)
{
Con::errorf("The requested renderer, %s, doesn't seem to be available."
" Trying the default, OpenGL.", getAdapterNameFromType(type));
adapter = GFXInit::getAdapterOfType(OpenGL, outputDeviceIndex);
}
if (!adapter)
{
Con::errorf("The OpenGL renderer doesn't seem to be available. Trying the GFXNulDevice.");
adapter = GFXInit::getAdapterOfType(NullDevice, 0);
}
AssertFatal(adapter, "There is no rendering device available whatsoever.");
return adapter;
}
const char* GFXInit::getAdapterNameFromType(GFXAdapterType type)
{
// must match GFXAdapterType order
@ -256,8 +293,23 @@ GFXAdapter *GFXInit::getBestAdapterChoice()
// Get the user's preference for device...
const String renderer = Con::getVariable("$pref::Video::displayDevice");
const String outputDevice = Con::getVariable("$pref::Video::displayOutputDevice");
GFXAdapterType adapterType = getAdapterTypeFromName(renderer.c_str());
GFXAdapter *adapter = chooseAdapter(adapterType, outputDevice.c_str());
const String adapterDevice = Con::getVariable("$Video::forceDisplayAdapter");
GFXAdapterType adapterType = getAdapterTypeFromName(renderer.c_str());;
GFXAdapter *adapter = NULL;
if (adapterDevice.isEmpty())
{
adapter = chooseAdapter(adapterType, outputDevice.c_str());
}
else
{
S32 adapterIdx = dAtoi(adapterDevice.c_str());
if (adapterIdx == -1)
adapter = chooseAdapter(adapterType, outputDevice.c_str());
else
adapter = chooseAdapter(adapterType, adapterIdx);
}
// Did they have one? Return it.
if(adapter)

View file

@ -74,10 +74,16 @@ public:
/// This method never returns NULL.
static GFXAdapter *chooseAdapter( GFXAdapterType type, const char* outputDevice);
/// Override which chooses an adapter based on an index instead
static GFXAdapter *chooseAdapter( GFXAdapterType type, S32 outputDeviceIndex );
/// Gets the first adapter of the requested type (and on the requested output device)
/// from the list of enumerated adapters. Should only call this after a call to
/// enumerateAdapters.
static GFXAdapter *getAdapterOfType( GFXAdapterType type, const char* outputDevice );
/// Override which gets an adapter based on an index instead
static GFXAdapter *getAdapterOfType( GFXAdapterType type, S32 outputDeviceIndex );
/// Converts a GFXAdapterType to a string name. Useful for writing out prefs
static const char *getAdapterNameFromType( GFXAdapterType type );

View file

@ -88,7 +88,7 @@ class GFXOcclusionQueryHandle
public:
GFXOcclusionQueryHandle()
: mLastStatus(GFXOcclusionQuery::Unset), mLastData(0), mQuery(NULL), mWaiting(false)
: mLastStatus(GFXOcclusionQuery::Unset), mLastData(0), mWaiting(false) , mQuery(NULL)
{}
~GFXOcclusionQueryHandle()

View file

@ -43,7 +43,9 @@ public: //protected:
U32 mPrimitiveCount;
GFXBufferType mBufferType;
GFXPrimitive *mPrimitiveArray;
GFXDevice *mDevice;
GFXDevice *mDevice;
U32 mVolatileStart;
#ifdef TORQUE_DEBUG
// In debug builds we provide a TOC leak tracking system.
@ -59,7 +61,8 @@ public: //protected:
GFXPrimitiveBuffer( GFXDevice *device,
U32 indexCount,
U32 primitiveCount,
GFXBufferType bufferType )
GFXBufferType bufferType ) :
mVolatileStart(0)
{
mDevice = device;
mIndexCount = indexCount;
@ -122,7 +125,7 @@ public: //protected:
// GFXResource interface
/// The resource should put a description of itself (number of vertices, size/width of texture, etc.) in buffer
virtual const String describeSelf() const;
virtual const String describeSelf() const;
};
class GFXPrimitiveBufferHandle : public StrongRefPtr<GFXPrimitiveBuffer>

View file

@ -100,7 +100,10 @@ public:
/// of a target texture after presentation or deactivated.
///
/// This is mainly a depth buffer optimization.
NoDiscard = BIT(10)
NoDiscard = BIT(10),
/// Texture is managed by another process, thus should not be modified
NoModify = BIT(11)
};
@ -164,6 +167,7 @@ public:
inline bool noMip() const { return testFlag(NoMipmap); }
inline bool isPooled() const { return testFlag(Pooled); }
inline bool canDiscard() const { return !testFlag(NoDiscard); }
inline bool canModify() const { return !testFlag(NoModify); }
private:
/// These constants control the packing for the profile; if you add flags, types, or

View file

@ -37,6 +37,9 @@ namespace GFXSemantic
const String TANGENTW = String( "TANGENTW" ).intern();
const String COLOR = String( "COLOR" ).intern();
const String TEXCOORD = String( "TEXCOORD" ).intern();
const String BLENDINDICES = String( "BLENDINDICES" ).intern();
const String BLENDWEIGHT = String( "BLENDWEIGHT" ).intern();
const String PADDING = String( "PADDING" ).intern();
}
@ -59,6 +62,9 @@ U32 GFXVertexElement::getSizeInBytes() const
case GFXDeclType_Color:
return 4;
case GFXDeclType_UByte4:
return 4;
default:
return 0;
};
@ -85,6 +91,7 @@ void GFXVertexFormat::copy( const GFXVertexFormat &format )
mHasTangent = format.mHasTangent;
mHasColor = format.mHasColor;
mHasInstancing = format.mHasInstancing;
mHasBlendIndices = format.mHasBlendIndices;
mTexCoordCount = format.mTexCoordCount;
mSizeInBytes = format.mSizeInBytes;
mDescription = format.mDescription;
@ -171,6 +178,35 @@ bool GFXVertexFormat::hasInstancing() const
return mHasInstancing;
}
bool GFXVertexFormat::hasBlendIndices() const
{
if ( mDirty )
const_cast<GFXVertexFormat*>(this)->_updateDirty();
return mHasBlendIndices;
}
U32 GFXVertexFormat::getNumBlendIndices() const
{
if ( mDirty )
const_cast<GFXVertexFormat*>(this)->_updateDirty();
if ( !mHasBlendIndices )
return 0;
U32 numIndices = 0;
for ( U32 i=0; i < mElements.size(); i++ )
{
const GFXVertexElement &element = mElements[i];
if ( element.isSemantic( GFXSemantic::BLENDINDICES ) )
numIndices++;
}
return numIndices;
}
U32 GFXVertexFormat::getTexCoordCount() const
{
if ( mDirty )
@ -199,6 +235,7 @@ void GFXVertexFormat::_updateDirty()
mTexCoordCount = 0;
mHasColor = false;
mHasBlendIndices = false;
mHasNormal = false;
mHasTangent = false;
mSizeInBytes = 0;
@ -222,6 +259,8 @@ void GFXVertexFormat::_updateDirty()
mHasColor = true;
else if ( element.isSemantic( GFXSemantic::TEXCOORD ) )
++mTexCoordCount;
else if ( element.isSemantic( GFXSemantic::BLENDINDICES ) )
mHasBlendIndices = true;
mSizeInBytes += element.getSizeInBytes();
}

View file

@ -45,6 +45,9 @@ namespace GFXSemantic
extern const String TANGENTW;
extern const String COLOR;
extern const String TEXCOORD;
extern const String BLENDWEIGHT;
extern const String BLENDINDICES;
extern const String PADDING;
}
@ -184,10 +187,16 @@ public:
/// Returns true if there is a COLOR semantic in this vertex format.
bool hasColor() const;
/// Returns true if there is a BLENDWEIGHT or BLENDINDICES semantic in this vertex format.
bool hasBlendIndices() const;
/// Return true if instancing is used with this vertex format.
bool hasInstancing() const;
/// Returns number of blend indices
U32 getNumBlendIndices() const;
/// Returns the texture coordinate count by
/// counting the number of TEXCOORD semantics.
U32 getTexCoordCount() const;
@ -230,6 +239,9 @@ protected:
/// Is true if there is a COLOR semantic in this vertex format.
bool mHasColor;
/// Is true if there is a BLENDWEIGHT or BLENDINDICES semantic in this vertex format.
bool mHasBlendIndices;
/// Is instaning used with this vertex format.
bool mHasInstancing;

View file

@ -29,6 +29,11 @@ GFXImplementVertexFormat( GFXVertexP )
addElement( "POSITION", GFXDeclType_Float3 );
}
GFXImplementVertexFormat( GFXVertexPad )
{
addElement("PADDING", GFXDeclType_UByte4);
}
GFXImplementVertexFormat( GFXVertexPT )
{
addElement( "POSITION", GFXDeclType_Float3 );

View file

@ -36,6 +36,10 @@
#include "math/mPoint3.h"
#endif
GFXDeclareVertexFormat( GFXVertexPad )
{
U32 data;
};
GFXDeclareVertexFormat( GFXVertexP )
{

View file

@ -27,26 +27,9 @@
void GFXGLCardProfiler::init()
{
mChipSet = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
// get the major and minor parts of the GL version. These are defined to be
// in the order "[major].[minor] [other]|[major].[minor].[release] [other] in the spec
const char *versionStart = reinterpret_cast<const char*>(glGetString(GL_VERSION));
const char *versionEnd = versionStart;
// get the text for the version "x.x.xxxx "
for( S32 tok = 0; tok < 2; ++tok )
{
char *text = dStrdup( versionEnd );
dStrtok(text, ". ");
versionEnd += dStrlen( text ) + 1;
dFree( text );
}
mRendererString = "GL";
mRendererString += String::SpanToString(versionStart, versionEnd - 1);
mRendererString = "OpenGL";
mCardDescription = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
mVersionString = reinterpret_cast<const char*>(glGetString(GL_VERSION));
mVersionString = reinterpret_cast<const char*>(glGetString(GL_VERSION));
mVideoMemory = static_cast<GFXGLDevice*>(GFX)->getTotalVideoMemory();
Parent::init();
@ -85,7 +68,8 @@ void GFXGLCardProfiler::setupCardCapabilities()
setCapability("GL_ARB_copy_image", gglHasExtension(ARB_copy_image));
// Check for vertex attrib binding
setCapability("GL_ARB_vertex_attrib_binding", gglHasExtension(ARB_vertex_attrib_binding));
setCapability("GL_ARB_vertex_attrib_binding", gglHasExtension(ARB_vertex_attrib_binding));
}
bool GFXGLCardProfiler::_queryCardCap(const String& query, U32& foundResult)

View file

@ -84,6 +84,10 @@ void loadGLExtensions(void *context)
void STDCALL glDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar *message, const void *userParam)
{
// JTH [11/24/2016]: This is a temporary fix so that we do not get spammed for redundant fbo changes.
// This only happens on Intel cards. This should be looked into sometime in the near future.
if (dStrStartsWith(message, "API_ID_REDUNDANT_FBO"))
return;
if (severity == GL_DEBUG_SEVERITY_HIGH)
Con::errorf("OPENGL: %s", message);
else if (severity == GL_DEBUG_SEVERITY_MEDIUM)
@ -103,27 +107,6 @@ void STDCALL glAmdDebugCallback(GLuint id, GLenum category, GLenum severity, GLs
Con::printf("AMDOPENGL: %s", message);
}
// >>>> OPENGL INTEL WORKAROUND @todo OPENGL INTEL remove
PFNGLBINDFRAMEBUFFERPROC __openglBindFramebuffer = NULL;
void STDCALL _t3d_glBindFramebuffer(GLenum target, GLuint framebuffer)
{
if( target == GL_FRAMEBUFFER )
{
if( GFXGL->getOpenglCache()->getCacheBinded( GL_DRAW_FRAMEBUFFER ) == framebuffer
&& GFXGL->getOpenglCache()->getCacheBinded( GL_READ_FRAMEBUFFER ) == framebuffer )
return;
}
else if( GFXGL->getOpenglCache()->getCacheBinded( target ) == framebuffer )
return;
__openglBindFramebuffer(target, framebuffer);
GFXGL->getOpenglCache()->setCacheBinded( target, framebuffer);
}
// <<<< OPENGL INTEL WORKAROUND
void GFXGLDevice::initGLState()
{
// We don't currently need to sync device state with a known good place because we are
@ -134,7 +117,8 @@ void GFXGLDevice::initGLState()
mCardProfiler = new GFXGLCardProfiler();
mCardProfiler->init();
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (GLint*)&mMaxShaderTextures);
glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&mMaxFFTextures);
// JTH: Needs removed, ffp
//glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&mMaxFFTextures);
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, (GLint*)&mMaxTRColors);
mMaxTRColors = getMin( mMaxTRColors, (U32)(GFXTextureTarget::MaxRenderSlotId-1) );
@ -156,14 +140,11 @@ void GFXGLDevice::initGLState()
String vendorStr = (const char*)glGetString( GL_VENDOR );
if( vendorStr.find("NVIDIA", 0, String::NoCase | String::Left) != String::NPos)
mUseGlMap = false;
if( vendorStr.find("INTEL", 0, String::NoCase | String::Left ) != String::NPos)
{
// @todo OPENGL INTEL - This is a workaround for a warning spam or even crashes with actual framebuffer code, remove when implemented TGL layer.
__openglBindFramebuffer = glBindFramebuffer;
glBindFramebuffer = &_t3d_glBindFramebuffer;
}
// Workaround for all Mac's, has a problem using glMap* with volatile buffers
#ifdef TORQUE_OS_MAC
mUseGlMap = false;
#endif
#if TORQUE_DEBUG
if( gglHasExtension(ARB_debug_output) )
@ -199,8 +180,10 @@ void GFXGLDevice::initGLState()
GFXGLDevice::GFXGLDevice(U32 adapterIndex) :
mAdapterIndex(adapterIndex),
mNeedUpdateVertexAttrib(false),
mCurrentPB(NULL),
mDrawInstancesCount(0),
mCurrentShader( NULL ),
m_mCurrentWorld(true),
m_mCurrentView(true),
mContext(NULL),
@ -210,8 +193,6 @@ GFXGLDevice::GFXGLDevice(U32 adapterIndex) :
mMaxFFTextures(2),
mMaxTRColors(1),
mClip(0, 0, 0, 0),
mCurrentShader( NULL ),
mNeedUpdateVertexAttrib(false),
mWindowRT(NULL),
mUseGlMap(true)
{
@ -608,13 +589,11 @@ void GFXGLDevice::drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startIndex,
U32 primitiveCount )
{
AssertFatal( startVertex == 0, "GFXGLDevice::drawIndexedPrimitive() - Non-zero startVertex unsupported!" );
preDrawPrimitive();
U16* buf = (U16*)static_cast<GFXGLPrimitiveBuffer*>(mCurrentPrimitiveBuffer.getPointer())->getBuffer() + startIndex;
U16* buf = (U16*)static_cast<GFXGLPrimitiveBuffer*>(mCurrentPrimitiveBuffer.getPointer())->getBuffer() + startIndex + mCurrentPrimitiveBuffer->mVolatileStart;
const U32 baseVertex = mCurrentVB[0]->mBufferVertexOffset;
const U32 baseVertex = mCurrentVB[0]->mBufferVertexOffset + startVertex;
if(mDrawInstancesCount)
glDrawElementsInstancedBaseVertex(GFXGLPrimType[primType], primCountToIndexCount(primType, primitiveCount), GL_UNSIGNED_SHORT, buf, mDrawInstancesCount, baseVertex);
@ -643,7 +622,7 @@ void GFXGLDevice::setLightMaterialInternal(const GFXLightMaterial mat)
void GFXGLDevice::setGlobalAmbientInternal(ColorF color)
{
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (GLfloat*)&color);
// ONLY NEEDED ON FFP
}
void GFXGLDevice::setTextureInternal(U32 textureUnit, const GFXTextureObject*texture)
@ -699,12 +678,12 @@ void GFXGLDevice::setClipRect( const RectI &inRect )
const F32 right = mClip.point.x + mClip.extent.x;
const F32 bottom = mClip.extent.y;
const F32 top = 0.0f;
const F32 near = 0.0f;
const F32 far = 1.0f;
const F32 nearPlane = 0.0f;
const F32 farPlane = 1.0f;
const F32 tx = -(right + left)/(right - left);
const F32 ty = -(top + bottom)/(top - bottom);
const F32 tz = -(far + near)/(far - near);
const F32 tz = -(farPlane + nearPlane)/(farPlane - nearPlane);
static Point4F pt;
pt.set(2.0f / (right - left), 0.0f, 0.0f, 0.0f);
@ -713,7 +692,7 @@ void GFXGLDevice::setClipRect( const RectI &inRect )
pt.set(0.0f, 2.0f/(top - bottom), 0.0f, 0.0f);
mProjectionMatrix.setColumn(1, pt);
pt.set(0.0f, 0.0f, -2.0f/(far - near), 0.0f);
pt.set(0.0f, 0.0f, -2.0f/(farPlane - nearPlane), 0.0f);
mProjectionMatrix.setColumn(2, pt);
pt.set(tx, ty, tz, 1.0f);

View file

@ -1,343 +0,0 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
// Don't include Apple's GL header
#define __gl_h_
// Include our GL header before Apple headers.
#include "gfx/gl/ggl/ggl.h"
#include "platform/tmm_off.h"
#include <Cocoa/Cocoa.h>
#include <OpenGL/OpenGL.h>
#include "gfx/gl/gfxGLDevice.h"
#include "platform/tmm_on.h"
#include "gfx/gl/gfxGLTextureTarget.h"
#include "gfx/gl/gfxGLCardProfiler.h"
#include "gfx/gl/gfxGLAppleFence.h"
#include "gfx/gl/gfxGLWindowTarget.h"
#include "platformMac/macGLUtils.h"
#include "windowManager/mac/macWindow.h"
extern void loadGLCore();
extern void loadGLExtensions(void* context);
static String _getRendererForDisplay(CGDirectDisplayID display)
{
Vector<NSOpenGLPixelFormatAttribute> attributes = _createStandardPixelFormatAttributesForDisplay(display);
NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes.address()];
AssertFatal(fmt, "_getRendererForDisplay - Unable to create a pixel format object");
NSOpenGLContext* ctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:nil];
AssertFatal(ctx, "_getRendererForDisplay - Unable to create an OpenGL context");
// Save the current context, just in case
NSOpenGLContext* currCtx = [NSOpenGLContext currentContext];
[ctx makeCurrentContext];
// CodeReview [ags 12/19/07] This is a hack. We should call loadGLCore somewhere else, before we reach here.
// On Macs we can safely assume access to the OpenGL framework at anytime, perhaps this should go in main()?
loadGLCore();
// get the renderer string
String ret((const char*)glGetString(GL_RENDERER));
// Restore our old context, release the context and pixel format.
[currCtx makeCurrentContext];
[ctx release];
[fmt release];
return ret;
}
static void _createInitialContextAndFormat(void* &ctx, void* &fmt)
{
AssertFatal(!fmt && !ctx, "_createInitialContextAndFormat - Already created initial context and format");
fmt = _createStandardPixelFormat();
AssertFatal(fmt, "_createInitialContextAndFormat - Unable to create an OpenGL pixel format");
ctx = [[NSOpenGLContext alloc] initWithFormat: (NSOpenGLPixelFormat*)fmt shareContext: nil];
AssertFatal(ctx, "_createInitialContextAndFormat - Unable to create an OpenGL context");
}
static NSOpenGLContext* _createContextForWindow(PlatformWindow *window, void* &context, void* &pixelFormat)
{
NSOpenGLView* view = (NSOpenGLView*)window->getPlatformDrawable();
AssertFatal([view isKindOfClass:[NSOpenGLView class]], avar("_createContextForWindow - Supplied a %s instead of a NSOpenGLView", [[view className] UTF8String]));
NSOpenGLContext* ctx = NULL;
if(!context || !pixelFormat)
{
// Create the initial opengl context that the device and the first window will hold.
_createInitialContextAndFormat(context, pixelFormat);
ctx = (NSOpenGLContext*)context;
}
else
{
// Create a context which shares its resources with the device's initial context
ctx = [[NSOpenGLContext alloc] initWithFormat: (NSOpenGLPixelFormat*)pixelFormat shareContext: (NSOpenGLContext*)context];
AssertFatal(ctx, "Unable to create a shared OpenGL context");
}
[view setPixelFormat: (NSOpenGLPixelFormat*)pixelFormat];
[view setOpenGLContext: ctx];
return ctx;
}
void GFXGLDevice::init( const GFXVideoMode &mode, PlatformWindow *window )
{
if(mInitialized)
return;
NSOpenGLContext* ctx = _createContextForWindow(window, mContext, mPixelFormat);
[ctx makeCurrentContext];
loadGLCore();
loadGLExtensions(ctx);
initGLState();
mInitialized = true;
deviceInited();
}
void GFXGLDevice::enumerateAdapters( Vector<GFXAdapter*> &adapterList )
{
GFXAdapter *toAdd;
Vector<GFXVideoMode> videoModes;
CGDirectDisplayID display = CGMainDisplayID();
// Enumerate all available resolutions:
NSArray* modeArray = (NSArray*)CGDisplayAvailableModes(display);
GFXVideoMode vmAdd;
NSEnumerator* enumerator = [modeArray objectEnumerator];
NSDictionary* mode;
while((mode = [enumerator nextObject]))
{
vmAdd.resolution.x = [[mode valueForKey:@"Width"] intValue];
vmAdd.resolution.y = [[mode valueForKey:@"Height"] intValue];
vmAdd.bitDepth = [[mode valueForKey:@"BitsPerPixel"] intValue];
vmAdd.refreshRate = [[mode valueForKey:@"RefreshRate"] intValue];
vmAdd.fullScreen = false;
// skip if mode claims to be 8bpp
if( vmAdd.bitDepth == 8 )
continue;
// Only add this resolution if it is not already in the list:
bool alreadyInList = false;
for(Vector<GFXVideoMode>::iterator i = videoModes.begin(); i != videoModes.end(); i++)
{
if(vmAdd == *i)
{
alreadyInList = true;
break;
}
}
if( !alreadyInList )
{
videoModes.push_back( vmAdd );
}
}
// Get number of displays
CGDisplayCount dispCnt;
CGGetActiveDisplayList(0, NULL, &dispCnt);
// Take advantage of GNU-C
CGDirectDisplayID displays[dispCnt];
CGGetActiveDisplayList(dispCnt, displays, &dispCnt);
for(U32 i = 0; i < dispCnt; i++)
{
toAdd = new GFXAdapter();
toAdd->mType = OpenGL;
toAdd->mIndex = (U32)displays[i];
toAdd->mCreateDeviceInstanceDelegate = mCreateDeviceInstance;
String renderer = _getRendererForDisplay(displays[i]);
AssertFatal(dStrlen(renderer.c_str()) < GFXAdapter::MaxAdapterNameLen, "GFXGLDevice::enumerateAdapter - renderer name too long, increae the size of GFXAdapter::MaxAdapterNameLen (or use String!)");
dStrncpy(toAdd->mName, renderer.c_str(), GFXAdapter::MaxAdapterNameLen);
adapterList.push_back(toAdd);
for (S32 j = videoModes.size() - 1 ; j >= 0 ; j--)
toAdd->mAvailableModes.push_back(videoModes[j]);
}
}
void GFXGLDevice::enumerateVideoModes()
{
mVideoModes.clear();
CGDirectDisplayID display = CGMainDisplayID();
// Enumerate all available resolutions:
NSArray* modeArray = (NSArray*)CGDisplayAvailableModes(display);
GFXVideoMode toAdd;
NSEnumerator* enumerator = [modeArray objectEnumerator];
NSDictionary* mode;
while((mode = [enumerator nextObject]))
{
toAdd.resolution.x = [[mode valueForKey:@"Width"] intValue];
toAdd.resolution.y = [[mode valueForKey:@"Height"] intValue];
toAdd.bitDepth = [[mode valueForKey:@"BitsPerPixel"] intValue];
toAdd.refreshRate = [[mode valueForKey:@"RefreshRate"] intValue];
toAdd.fullScreen = false;
// skip if mode claims to be 8bpp
if( toAdd.bitDepth == 8 )
continue;
// Only add this resolution if it is not already in the list:
bool alreadyInList = false;
for(Vector<GFXVideoMode>::iterator i = mVideoModes.begin(); i != mVideoModes.end(); i++)
{
if(toAdd == *i)
{
alreadyInList = true;
break;
}
}
if( !alreadyInList )
{
mVideoModes.push_back( toAdd );
}
}
}
bool GFXGLDevice::beginSceneInternal()
{
// Nothing to do here for GL.
mCanCurrentlyRender = true;
return true;
}
U32 GFXGLDevice::getTotalVideoMemory()
{
// Convert our adapterIndex (i.e. our CGDirectDisplayID) into an OpenGL display mask
GLuint display = CGDisplayIDToOpenGLDisplayMask((CGDirectDisplayID)mAdapterIndex);
CGLRendererInfoObj rend;
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
GLint nrend;
#else
long int nrend;
#endif
CGLQueryRendererInfo(display, &rend, &nrend);
if(!nrend)
return 0;
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
GLint vidMem;
#else
long int vidMem;
#endif
CGLDescribeRenderer(rend, 0, kCGLRPVideoMemory, &vidMem);
CGLDestroyRendererInfo(rend);
// convert bytes to MB
vidMem /= (1024 * 1024);
return vidMem;
}
//-----------------------------------------------------------------------------
GFXWindowTarget *GFXGLDevice::allocWindowTarget(PlatformWindow *window)
{
void *ctx = NULL;
// Init if needed, or create a new context
if(!mInitialized)
init(window->getVideoMode(), window);
else
ctx = _createContextForWindow(window, mContext, mPixelFormat);
// Allocate the wintarget and create a new context.
GFXGLWindowTarget *gwt = new GFXGLWindowTarget(window, this);
gwt->mContext = ctx ? ctx : mContext;
// And return...
return gwt;
}
GFXFence* GFXGLDevice::_createPlatformSpecificFence()
{
if(!mCardProfiler->queryProfile("GL::APPLE::suppFence"))
return NULL;
return new GFXGLAppleFence(this);
}
void GFXGLWindowTarget::_WindowPresent()
{
GFX->updateStates();
mFullscreenContext ? [(NSOpenGLContext*)mFullscreenContext flushBuffer] : [(NSOpenGLContext*)mContext flushBuffer];
return true;
}
void GFXGLWindowTarget::_teardownCurrentMode()
{
GFX->setActiveRenderTarget(this);
static_cast<GFXGLDevice*>(mDevice)->zombify();
if(mFullscreenContext)
{
[NSOpenGLContext clearCurrentContext];
[(NSOpenGLContext*)mFullscreenContext clearDrawable];
}
}
void GFXGLWindowTarget::_setupNewMode()
{
if(mWindow->getVideoMode().fullScreen && !mFullscreenContext)
{
// We have to create a fullscreen context.
Vector<NSOpenGLPixelFormatAttribute> attributes = _beginPixelFormatAttributesForDisplay(static_cast<MacWindow*>(mWindow)->getDisplay());
_addColorAlphaDepthStencilAttributes(attributes, 24, 8, 24, 8);
_addFullscreenAttributes(attributes);
_endAttributeList(attributes);
NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes.address()];
mFullscreenContext = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:nil];
[fmt release];
[(NSOpenGLContext*)mFullscreenContext setFullScreen];
[(NSOpenGLContext*)mFullscreenContext makeCurrentContext];
// Restore resources in new context
static_cast<GFXGLDevice*>(mDevice)->resurrect();
GFX->updateStates(true);
}
else if(!mWindow->getVideoMode().fullScreen && mFullscreenContext)
{
[(NSOpenGLContext*)mFullscreenContext release];
mFullscreenContext = NULL;
[(NSOpenGLContext*)mContext makeCurrentContext];
GFX->clear(GFXClearTarget | GFXClearZBuffer | GFXClearStencil, ColorI(0, 0, 0), 1.0f, 0);
static_cast<GFXGLDevice*>(mDevice)->resurrect();
GFX->updateStates(true);
}
}

View file

@ -58,7 +58,7 @@ public:
glGenQueries(1, &mQueryId);
}
GLTimer() : mName(NULL), mQueryId(0), mData(NULL)
GLTimer() : mName(NULL), mData(NULL), mQueryId(0)
{
}

View file

@ -32,6 +32,8 @@
#include "gfx/gfxStructs.h"
#include "console/console.h"
#define CHECK_AARG(pos, name) static StringTableEntry attr_##name = StringTable->insert(#name); if (argName == attr_##name) { glBindAttribLocation(mProgram, pos, attr_##name); continue; }
class GFXGLShaderConstHandle : public GFXShaderConstHandle
{
@ -92,6 +94,8 @@ static U32 shaderConstTypeSize(GFXShaderConstType type)
return 16;
case GFXSCT_Float3x3:
return 36;
case GFXSCT_Float4x3:
return 48;
case GFXSCT_Float4x4:
return 64;
default:
@ -305,6 +309,9 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& ma
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[7] = mat[9];
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[8] = mat[10];
break;
case GFXSCT_Float4x3:
dMemcpy(mBuffer + _glHandle->mOffset, (const F32*)mat, (sizeof(F32) * 12));// matrix with end row chopped off
break;
case GFXSCT_Float4x4:
{
if(_glHandle->mInstancingConstant)
@ -334,6 +341,13 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF* ma
AssertFatal(!_glHandle->mInstancingConstant, "GFXGLShaderConstBuffer::set - Instancing not supported for matrix arrays");
switch (matrixType) {
case GFXSCT_Float4x3:
// Copy each item with the last row chopped off
for (int i = 0; i<arraySize; i++)
{
dMemcpy(mBuffer + _glHandle->mOffset + (i*(sizeof(F32) * 12)), (F32*)(mat + i), sizeof(F32) * 12);
}
break;
case GFXSCT_Float4x4:
dMemcpy(mBuffer + _glHandle->mOffset, (F32*)mat, _glHandle->getSize());
break;
@ -435,34 +449,62 @@ bool GFXGLShader::_init()
// If either shader was present and failed to compile, bail.
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");
//bind fragment out color
glBindFragDataLocation(mProgram, 0, "OUT_col");
glBindFragDataLocation(mProgram, 1, "OUT_col1");
glBindFragDataLocation(mProgram, 2, "OUT_col2");
glBindFragDataLocation(mProgram, 3, "OUT_col3");
// Link it!
glLinkProgram( mProgram );
GLint activeAttribs = 0;
glGetProgramiv(mProgram, GL_ACTIVE_ATTRIBUTES, &activeAttribs );
GLint maxLength;
glGetProgramiv(mProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength);
FrameTemp<GLchar> tempData(maxLength+1);
*tempData.address() = '\0';
// Check atributes
for (U32 i=0; i<activeAttribs; i++)
{
GLint size;
GLenum type;
glGetActiveAttrib(mProgram, i, maxLength + 1, NULL, &size, &type, tempData.address());
StringTableEntry argName = StringTable->insert(tempData.address());
CHECK_AARG(Torque::GL_VertexAttrib_Position, vPosition);
CHECK_AARG(Torque::GL_VertexAttrib_Normal, vNormal);
CHECK_AARG(Torque::GL_VertexAttrib_Color, vColor);
CHECK_AARG(Torque::GL_VertexAttrib_Tangent, vTangent);
CHECK_AARG(Torque::GL_VertexAttrib_TangentW, vTangentW);
CHECK_AARG(Torque::GL_VertexAttrib_Binormal, vBinormal);
CHECK_AARG(Torque::GL_VertexAttrib_TexCoord0, vTexCoord0);
CHECK_AARG(Torque::GL_VertexAttrib_TexCoord1, vTexCoord1);
CHECK_AARG(Torque::GL_VertexAttrib_TexCoord2, vTexCoord2);
CHECK_AARG(Torque::GL_VertexAttrib_TexCoord3, vTexCoord3);
CHECK_AARG(Torque::GL_VertexAttrib_TexCoord4, vTexCoord4);
CHECK_AARG(Torque::GL_VertexAttrib_TexCoord5, vTexCoord5);
CHECK_AARG(Torque::GL_VertexAttrib_TexCoord6, vTexCoord6);
CHECK_AARG(Torque::GL_VertexAttrib_TexCoord7, vTexCoord7);
CHECK_AARG(Torque::GL_VertexAttrib_TexCoord8, vTexCoord8);
CHECK_AARG(Torque::GL_VertexAttrib_TexCoord9, vTexCoord9);
}
//always have OUT_col
glBindFragDataLocation(mProgram, 0, "OUT_col");
// Check OUT_colN
for(U32 i=1;i<4;i++)
{
char buffer[10];
dSprintf(buffer, sizeof(buffer), "OUT_col%u",i);
GLint location = glGetFragDataLocation(mProgram, buffer);
if(location>0)
glBindFragDataLocation(mProgram, i, buffer);
}
// Link it again!
glLinkProgram( mProgram );
GLint linkStatus;
glGetProgramiv( mProgram, GL_LINK_STATUS, &linkStatus );
@ -474,23 +516,24 @@ bool GFXGLShader::_init()
FrameAllocatorMarker fam;
char* log = (char*)fam.alloc( logLength );
glGetProgramInfoLog( mProgram, logLength, NULL, log );
if ( linkStatus == GL_FALSE )
{
if ( smLogErrors )
{
Con::errorf( "GFXGLShader::init - Error linking shader!" );
Con::errorf( "Program %s / %s: %s",
mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log);
Con::errorf( "Program %s / %s: %s",
mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log);
}
}
else if ( smLogWarnings )
{
Con::warnf( "Program %s / %s: %s",
mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log);
Con::warnf( "Program %s / %s: %s",
mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log);
}
}
// If we failed to link, bail.
if ( linkStatus == GL_FALSE )
return false;
@ -572,6 +615,9 @@ void GFXGLShader::initConstantDescs()
case GL_FLOAT_MAT4:
desc.constType = GFXSCT_Float4x4;
break;
case GL_FLOAT_MAT4x3: // jamesu - columns, rows
desc.constType = GFXSCT_Float4x3;
break;
case GL_SAMPLER_1D:
case GL_SAMPLER_2D:
case GL_SAMPLER_3D:
@ -805,6 +851,11 @@ void GFXGLShader::setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer)
case GFXSCT_Float3x3:
glUniformMatrix3fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
break;
case GFXSCT_Float4x3:
// NOTE: To save a transpose here we could store the matrix transposed (i.e. column major) in the constant buffer.
// See _mesa_uniform_matrix in the mesa source for the correct transpose algorithm for a 4x3 matrix.
glUniformMatrix4x3fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
break;
case GFXSCT_Float4x4:
glUniformMatrix4fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
break;

View file

@ -196,7 +196,7 @@ void _GFXGLTextureTargetFBOImpl::applyState()
{
// Certain drivers have issues with depth only FBOs. That and the next two asserts assume we have a color target.
AssertFatal(hasColor, "GFXGLTextureTarget::applyState() - Cannot set DepthStencil target without Color0 target!");
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthStecil->getBinding(), depthStecil->getHandle(), depthStecil->getMipLevel());
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStecil->getBinding(), depthStecil->getHandle(), depthStecil->getMipLevel());
}
else
{

View file

@ -21,8 +21,11 @@ namespace Torque
GL_VertexAttrib_TexCoord7,
GL_VertexAttrib_TexCoord8,
GL_VertexAttrib_TexCoord9,
GL_VertexAttrib_COUNT,
GL_VertexAttrib_LAST = GL_VertexAttrib_TexCoord9,
GL_VertexAttrib_COUNT
GL_VertexAttrib_BlendWeight0 = GL_VertexAttrib_TexCoord6,
GL_VertexAttrib_BlendIndex0 = GL_VertexAttrib_TexCoord2,
};
}

View file

@ -41,10 +41,11 @@ GFXGLVertexBuffer::GFXGLVertexBuffer( GFXDevice *device,
const GFXVertexFormat *vertexFormat,
U32 vertexSize,
GFXBufferType bufferType )
: GFXVertexBuffer( device, numVerts, vertexFormat, vertexSize, bufferType ),
mZombieCache(NULL),
: GFXVertexBuffer( device, numVerts, vertexFormat, vertexSize, bufferType ),
mBufferOffset(0),
mBufferVertexOffset(0)
mBufferVertexOffset(0),
mZombieCache(NULL)
{
if( mBufferType == GFXBufferTypeVolatile )
{

View file

@ -105,6 +105,8 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
if(element.getStreamIndex() != stream)
continue;
AssertFatal(!mFormat->hasBlendIndices() || !element.isSemantic(GFXSemantic::TEXCOORD) || (mFormat->hasBlendIndices() && element.isSemantic(GFXSemantic::TEXCOORD) && element.getSemanticIndex() < 2), "skinning with more than 2 used texcoords!");
vertexSize += element.getSizeInBytes();
}
@ -187,6 +189,28 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
buffer += element.getSizeInBytes();
}
else if ( element.isSemantic( GFXSemantic::BLENDWEIGHT ) )
{
glElement.attrIndex = Torque::GL_VertexAttrib_BlendWeight0 + element.getSemanticIndex();
glElement.elementCount = 4;
glElement.normalized = false;
glElement.type = GL_FLOAT;
glElement.stride = vertexSize;
glElement.pointerFirst = (void*)buffer;
buffer += element.getSizeInBytes();
}
else if ( element.isSemantic( GFXSemantic::BLENDINDICES ) )
{
glElement.attrIndex = Torque::GL_VertexAttrib_BlendIndex0 + element.getSemanticIndex();
glElement.elementCount = 4;
glElement.normalized = false;
glElement.type = GL_UNSIGNED_BYTE;
glElement.stride = vertexSize;
glElement.pointerFirst = (void*)buffer;
buffer += element.getSizeInBytes();
}
else // Everything else is a texture coordinate.
{
String name = element.getSemantic();

View file

@ -118,11 +118,14 @@ inline void GFXGLWindowTarget::_setupAttachments()
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color->getHandle(), 0);
mBackBufferDepthTex.set(dstSize.x, dstSize.y, GFXFormatD24S8, &BackBufferDepthProfile, "backBuffer");
GFXGLTextureObject *depth = static_cast<GFXGLTextureObject*>(mBackBufferDepthTex.getPointer());
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth->getHandle(), 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depth->getHandle(), 0);
}
void GFXGLWindowTarget::makeActive()
{
//make the rendering context active on this window
_makeContextCurrent();
if(mBackBufferFBO)
{
glBindFramebuffer( GL_FRAMEBUFFER, mBackBufferFBO);

View file

@ -64,6 +64,8 @@ private:
void _setupNewMode();
void _setupAttachments();
void _WindowPresent();
//set this windows context to be current
void _makeContextCurrent();
};
#endif

View file

@ -106,6 +106,10 @@ void GFXGLDevice::enumerateAdapters( Vector<GFXAdapter*> &adapterList )
AssertFatal(0, err );
}
// Init GL
loadGLCore();
loadGLExtensions(tempContext);
//check minimun Opengl 3.2
int major, minor;
glGetIntegerv(GL_MAJOR_VERSION, &major);
@ -114,8 +118,6 @@ void GFXGLDevice::enumerateAdapters( Vector<GFXAdapter*> &adapterList )
{
return;
}
loadGLCore();
GFXAdapter *toAdd = new GFXAdapter;
toAdd->mIndex = 0;
@ -155,15 +157,15 @@ void GFXGLDevice::enumerateVideoModes()
void GFXGLDevice::init( const GFXVideoMode &mode, PlatformWindow *window )
{
AssertFatal(window, "GFXGLDevice::init - no window specified, can't init device without a window!");
PlatformWindowSDL* x11Window = dynamic_cast<PlatformWindowSDL*>(window);
AssertFatal(x11Window, "Window is not a valid PlatformWindowSDL object");
PlatformWindowSDL* sdlWindow = dynamic_cast<PlatformWindowSDL*>(window);
AssertFatal(sdlWindow, "Window is not a valid PlatformWindowSDL object");
// Create OpenGL context
mContext = PlatformGL::CreateContextGL( x11Window );
PlatformGL::MakeCurrentGL( x11Window, mContext );
mContext = PlatformGL::CreateContextGL( sdlWindow );
PlatformGL::MakeCurrentGL( sdlWindow, mContext );
loadGLCore();
loadGLExtensions(0);
loadGLExtensions(mContext);
// It is very important that extensions be loaded before we call initGLState()
initGLState();
@ -226,4 +228,9 @@ void GFXGLWindowTarget::_setupNewMode()
{
}
void GFXGLWindowTarget::_makeContextCurrent()
{
PlatformGL::MakeCurrentGL(mWindow, mContext);
}
#endif

View file

@ -33,11 +33,10 @@ namespace GL
{
void gglPerformBinds()
{
// JTH: epoxy has one oddity with windows. You need to bind the context
// after creating the context to udpate the internals of epoxy.
#ifdef TORQUE_OS_WIN
epoxy_handle_external_wglMakeCurrent();
#endif
if (!gladLoadGL())
{
AssertFatal(false, "Unable to load GLAD. Make sure your OpenGL drivers are up to date!");
}
}
void gglPerformExtensionBinds(void *context)

View file

@ -23,11 +23,10 @@
#ifndef T_GL_H
#define T_GL_H
#include <epoxy/gl.h>
#include <glad/glad.h>
// JTH: This is slow, we should probably check extensions once and cache them
// directly inside of some compatability table.
#define gglHasExtension(EXTENSION) epoxy_has_gl_extension("GL_" #EXTENSION)
// JTH: When we use glad, extensions are chached into simple booleans (ints)
#define gglHasExtension(EXTENSION) GLAD_GL_##EXTENSION
#endif

View file

@ -28,9 +28,9 @@
#ifdef TORQUE_OPENGL
#include "tGL.h"
#include <epoxy/wgl.h>
#include <glad/glad_wgl.h>
#define gglHasWExtension(window, EXTENSION) epoxy_has_wgl_extension(window, "WGL_" # EXTENSION)
#define gglHasWExtension(window, EXTENSION) GLAD_WGL_##EXTENSION
#endif //TORQUE_OPENGL

View file

@ -28,9 +28,9 @@
#ifdef TORQUE_OS_LINUX
#include "tGL.h"
#include <epoxy/glx.h>
#include <glad/glad_glx.h>
#define gglHasXExtension(display, screen, EXTENSION) epoxy_has_glx_extension(display, screen, "GLX_" # EXTENSION)
#define gglHasXExtension(display, screen, EXTENSION) GLAD_GLX_##EXTENSION
#endif //TORQUE_OS_LINUX

View file

@ -363,3 +363,16 @@ void GFXGLWindowTarget::_teardownCurrentMode()
void GFXGLWindowTarget::_setupNewMode()
{
}
void GFXGLWindowTarget::_makeContextCurrent()
{
HWND hwnd = GETHWND(getWindow());
HDC hdc = GetDC(hwnd);
if (!wglMakeCurrent(hdc, (HGLRC)mContext))
{
//HRESULT if needed for debug
//HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
AssertFatal(false, "GFXGLWindowTarget::_makeContextCurrent() - cannot make our context current.");
}
}

View file

@ -139,7 +139,78 @@ void DebugDrawer::setupStateBlocks()
mRenderAlpha = GFX->createStateBlock(d);
}
void DebugDrawer::render()
void DebugDrawer::drawBoxOutline(const Point3F &a, const Point3F &b, const ColorF &color)
{
Point3F point0(a.x, a.y, a.z);
Point3F point1(a.x, b.y, a.z);
Point3F point2(b.x, b.y, a.z);
Point3F point3(b.x, a.y, a.z);
Point3F point4(a.x, a.y, b.z);
Point3F point5(a.x, b.y, b.z);
Point3F point6(b.x, b.y, b.z);
Point3F point7(b.x, a.y, b.z);
// Draw one plane
drawLine(point0, point1, color);
drawLine(point1, point2, color);
drawLine(point2, point3, color);
drawLine(point3, point0, color);
// Draw the other plane
drawLine(point4, point5, color);
drawLine(point5, point6, color);
drawLine(point6, point7, color);
drawLine(point7, point4, color);
// Draw the connecting corners
drawLine(point0, point4, color);
drawLine(point1, point5, color);
drawLine(point2, point6, color);
drawLine(point3, point7, color);
}
void DebugDrawer::drawTransformedBoxOutline(const Point3F &a, const Point3F &b, const ColorF &color, const MatrixF& transform)
{
Point3F point0(a.x, a.y, a.z);
Point3F point1(a.x, b.y, a.z);
Point3F point2(b.x, b.y, a.z);
Point3F point3(b.x, a.y, a.z);
Point3F point4(a.x, a.y, b.z);
Point3F point5(a.x, b.y, b.z);
Point3F point6(b.x, b.y, b.z);
Point3F point7(b.x, a.y, b.z);
transform.mulP(point0);
transform.mulP(point1);
transform.mulP(point2);
transform.mulP(point3);
transform.mulP(point4);
transform.mulP(point5);
transform.mulP(point6);
transform.mulP(point7);
// Draw one plane
drawLine(point0, point1, color);
drawLine(point1, point2, color);
drawLine(point2, point3, color);
drawLine(point3, point0, color);
// Draw the other plane
drawLine(point4, point5, color);
drawLine(point5, point6, color);
drawLine(point6, point7, color);
drawLine(point7, point4, color);
// Draw the connecting corners
drawLine(point0, point4, color);
drawLine(point1, point5, color);
drawLine(point2, point6, color);
drawLine(point3, point7, color);
}
void DebugDrawer::render(bool clear)
{
#ifdef ENABLE_DEBUGDRAW
if(!isDrawing)
@ -264,7 +335,7 @@ void DebugDrawer::render()
shouldToggleFreeze = false;
}
if(p->dieTime <= curTime && !isFrozen && p->dieTime != U32_MAX)
if(clear && p->dieTime <= curTime && !isFrozen && p->dieTime != U32_MAX)
{
*walk = p->next;
mPrimChunker.free(p);

View file

@ -105,7 +105,9 @@ public:
static void init();
/// Called globally to render debug draw state. Also does state updates.
void render();
void render(bool clear=true);
bool willDraw() { return isDrawing && mHead; }
void toggleFreeze() { shouldToggleFreeze = true; };
void toggleDrawing()
@ -120,8 +122,11 @@ public:
///
/// @{
void drawBoxOutline(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f, 1.0f, 1.0f));
void drawTransformedBoxOutline(const Point3F &a, const Point3F &b, const ColorF &color, const MatrixF& transform);
void drawBox(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawLine(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawLine(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawTri(const Point3F &a, const Point3F &b, const Point3F &c, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawText(const Point3F& pos, const String& text, const ColorF &color = ColorF(1.0f,1.0f,1.0f));
void drawCapsule(const Point3F &a, const F32 &radius, const F32 &height, const ColorF &color = ColorF(1.0f, 1.0f, 1.0f));
@ -143,7 +148,8 @@ public:
/// Set the TTL for the last item we entered...
///
/// Primitives default to lasting one frame (ie, ttl=0)
enum {
enum : U32
{
DD_INFINITE = U32_MAX
};
// How long should this primitive be draw for, 0 = one frame, DD_INFINITE = draw forever
@ -176,7 +182,7 @@ private:
DirectionLine,
OutlinedText,
Capsule,
} type; ///< Type of the primitive. The meanings of a,b,c are determined by this.
} type; ///< Type of the primitive. The meanings of a,b,c are determined by this.
SimTime dieTime; ///< Time at which we should remove this from the list.
bool useZ; ///< If true, do z-checks for this primitive.