forked from 0ad/0ad
GPU-skinned tangent-space effects for non-instanced units, plus a bit of cleanup.
This was SVN commit r12795.
This commit is contained in:
parent
ae4b3cc9b6
commit
367c67d6ad
@ -73,9 +73,12 @@ renderpath = default
|
||||
; Prefer GLSL shaders over ARB shaders (not recommended). REQUIRES gentangents=true.
|
||||
preferglsl = false
|
||||
|
||||
; Generate tangents for normal and parallax mapping. REQUIRES preferglsl=true. Incompatible with gpuskinning.
|
||||
; Generate tangents for normal and parallax mapping. REQUIRES preferglsl=true.
|
||||
gentangents = false
|
||||
|
||||
; Experimental probably-non-working GPU skinning support; requires preferglsl; use at own risk
|
||||
gpuskinning = false
|
||||
|
||||
; Use smooth LOS interpolation; REQUIRES preferglsl=true.
|
||||
smoothlos = false
|
||||
|
||||
@ -96,9 +99,6 @@ materialmgr.PARALLAX_VHQ_DIST.max = 0
|
||||
; Replace alpha-blending with alpha-testing, for performance experiments
|
||||
forcealphatest = false
|
||||
|
||||
; Experimental probably-non-working GPU skinning support; requires preferglsl; use at own risk
|
||||
gpuskinning = false
|
||||
|
||||
; Opt-in online user reporting system
|
||||
userreport.url = "http://feedback.wildfiregames.com/report/upload/v1/"
|
||||
|
||||
|
@ -38,7 +38,7 @@ varying vec4 v_lighting;
|
||||
varying vec2 v_tex;
|
||||
varying vec2 v_los;
|
||||
|
||||
#if USE_INSTANCING && USE_AO
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && USE_AO
|
||||
varying vec2 v_tex2;
|
||||
#endif
|
||||
|
||||
@ -53,14 +53,14 @@ varying vec2 v_los;
|
||||
|
||||
#if USE_SPECULAR || USE_NORMAL_MAP || USE_SPECULAR_MAP || USE_PARALLAX_MAP
|
||||
varying vec4 v_normal;
|
||||
#if USE_INSTANCING && (USE_NORMAL_MAP || USE_PARALLAX_MAP)
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && (USE_NORMAL_MAP || USE_PARALLAX_MAP)
|
||||
varying vec4 v_tangent;
|
||||
//varying vec3 v_bitangent;
|
||||
#endif
|
||||
#if USE_SPECULAR || USE_SPECULAR_MAP
|
||||
varying vec3 v_half;
|
||||
#endif
|
||||
#if USE_INSTANCING && USE_PARALLAX_MAP
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && USE_PARALLAX_MAP
|
||||
varying vec3 v_eyeVec;
|
||||
#endif
|
||||
#endif
|
||||
@ -112,12 +112,12 @@ void main()
|
||||
{
|
||||
vec2 coord = v_tex;
|
||||
|
||||
#if USE_PARALLAX_MAP || USE_NORMAL_MAP
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && (USE_PARALLAX_MAP || USE_NORMAL_MAP)
|
||||
vec3 bitangent = vec3(v_normal.w, v_tangent.w, v_lighting.w);
|
||||
mat3 tbn = mat3(v_tangent.xyz, bitangent, v_normal.xyz);
|
||||
#endif
|
||||
|
||||
#if USE_PARALLAX_MAP
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && USE_PARALLAX_MAP
|
||||
{
|
||||
float h = texture2D(normTex, coord).a;
|
||||
|
||||
@ -222,7 +222,7 @@ void main()
|
||||
vec3 normal = v_normal.xyz;
|
||||
#endif
|
||||
|
||||
#if USE_INSTANCING && USE_NORMAL_MAP
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && USE_NORMAL_MAP
|
||||
vec3 ntex = texture2D(normTex, coord).rgb * 2.0 - 1.0;
|
||||
ntex.y = -ntex.y;
|
||||
normal = normalize(tbn * ntex);
|
||||
@ -251,7 +251,7 @@ void main()
|
||||
vec3 color = (texdiffuse * sundiffuse + specular.rgb) * get_shadow();
|
||||
vec3 ambColor = texdiffuse * ambient;
|
||||
|
||||
#if USE_INSTANCING && USE_AO
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && USE_AO
|
||||
vec3 ao = texture2D(aoTex, v_tex2).rrr;
|
||||
ao = mix(vec3(1.0), ao * 2.0, effectSettings.w);
|
||||
ambColor *= ao;
|
||||
|
@ -30,27 +30,27 @@ varying vec2 v_los;
|
||||
varying vec4 v_shadow;
|
||||
#endif
|
||||
|
||||
#if USE_INSTANCING && USE_AO
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && USE_AO
|
||||
varying vec2 v_tex2;
|
||||
#endif
|
||||
|
||||
#if USE_SPECULAR || USE_NORMAL_MAP || USE_SPECULAR_MAP || USE_PARALLAX_MAP
|
||||
varying vec4 v_normal;
|
||||
#if USE_INSTANCING && (USE_NORMAL_MAP || USE_PARALLAX_MAP)
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && (USE_NORMAL_MAP || USE_PARALLAX_MAP)
|
||||
varying vec4 v_tangent;
|
||||
//varying vec3 v_bitangent;
|
||||
#endif
|
||||
#if USE_SPECULAR || USE_SPECULAR_MAP
|
||||
varying vec3 v_half;
|
||||
#endif
|
||||
#if USE_INSTANCING && USE_PARALLAX_MAP
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && USE_PARALLAX_MAP
|
||||
varying vec3 v_eyeVec;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
attribute vec3 a_vertex;
|
||||
attribute vec3 a_normal;
|
||||
#if USE_INSTANCING
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING)
|
||||
attribute vec4 a_tangent;
|
||||
#endif
|
||||
attribute vec2 a_uv0;
|
||||
@ -86,9 +86,13 @@ void main()
|
||||
}
|
||||
}
|
||||
vec4 position = instancingTransform * vec4(p, 1.0);
|
||||
vec3 normal = mat3(instancingTransform) * normalize(n);
|
||||
mat3 normalMatrix = mat3(instancingTransform[0].xyz, instancingTransform[1].xyz, instancingTransform[2].xyz);
|
||||
vec3 normal = normalMatrix * normalize(n);
|
||||
#if (USE_NORMAL_MAP || USE_PARALLAX_MAP)
|
||||
vec3 tangent = normalMatrix * a_tangent.xyz;
|
||||
#endif
|
||||
#else
|
||||
#if USE_INSTANCING
|
||||
#if (USE_INSTANCING)
|
||||
vec4 position = instancingTransform * vec4(a_vertex, 1.0);
|
||||
mat3 normalMatrix = mat3(instancingTransform[0].xyz, instancingTransform[1].xyz, instancingTransform[2].xyz);
|
||||
vec3 normal = normalMatrix * a_normal;
|
||||
@ -140,7 +144,7 @@ void main()
|
||||
#if USE_SPECULAR || USE_NORMAL_MAP || USE_SPECULAR_MAP || USE_PARALLAX_MAP
|
||||
v_normal.xyz = normal;
|
||||
|
||||
#if USE_INSTANCING && (USE_NORMAL_MAP || USE_PARALLAX_MAP)
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && (USE_NORMAL_MAP || USE_PARALLAX_MAP)
|
||||
v_tangent.xyz = tangent;
|
||||
vec3 bitangent = cross(v_normal.xyz, v_tangent.xyz) * a_tangent.w;
|
||||
v_normal.w = bitangent.x;
|
||||
@ -154,7 +158,7 @@ void main()
|
||||
vec3 sunVec = -sunDir;
|
||||
v_half = normalize(sunVec + normalize(eyeVec));
|
||||
#endif
|
||||
#if USE_INSTANCING && USE_PARALLAX_MAP
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && USE_PARALLAX_MAP
|
||||
v_eyeVec = eyeVec;
|
||||
#endif
|
||||
#endif
|
||||
@ -164,7 +168,7 @@ void main()
|
||||
|
||||
v_tex = a_uv0;
|
||||
|
||||
#if USE_INSTANCING && USE_AO
|
||||
#if (USE_INSTANCING || USE_GPU_SKINNING) && USE_AO
|
||||
v_tex2 = a_uv1;
|
||||
#endif
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
<attrib name="a_uv1" semantics="gl_MultiTexCoord1" if="USE_AO"/>
|
||||
<attrib name="a_skinJoints" semantics="CustomAttribute0" if="USE_GPU_SKINNING"/>
|
||||
<attrib name="a_skinWeights" semantics="CustomAttribute1" if="USE_GPU_SKINNING"/>
|
||||
<attrib name="a_tangent" semantics="CustomAttribute2" if="USE_INSTANCING"/>
|
||||
<attrib name="a_tangent" semantics="CustomAttribute2" if="USE_INSTANCING || USE_GPU_SKINNING"/>
|
||||
</vertex>
|
||||
|
||||
<fragment file="glsl/model_common.fs"/>
|
||||
|
@ -31,13 +31,14 @@
|
||||
#include "graphics/LightEnv.h"
|
||||
#include "graphics/Model.h"
|
||||
#include "graphics/ModelDef.h"
|
||||
#include "graphics/weldmesh.h"
|
||||
|
||||
#include "renderer/InstancingModelRenderer.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "renderer/RenderModifiers.h"
|
||||
#include "renderer/VertexArray.h"
|
||||
|
||||
#include "third_party/mikktspace/weldmesh.h"
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// InstancingModelRenderer implementation
|
||||
@ -85,6 +86,17 @@ IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning, bool calculateT
|
||||
m_Array.AddAttribute(&m_UVs[i]);
|
||||
}
|
||||
|
||||
if (gpuSkinning)
|
||||
{
|
||||
m_BlendJoints.type = GL_UNSIGNED_BYTE;
|
||||
m_BlendJoints.elems = 4;
|
||||
m_Array.AddAttribute(&m_BlendJoints);
|
||||
|
||||
m_BlendWeights.type = GL_UNSIGNED_BYTE;
|
||||
m_BlendWeights.elems = 4;
|
||||
m_Array.AddAttribute(&m_BlendWeights);
|
||||
}
|
||||
|
||||
if (calculateTangents)
|
||||
{
|
||||
// Generate tangents for the geometry:-
|
||||
@ -93,8 +105,12 @@ IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning, bool calculateT
|
||||
m_Tangent.elems = 4;
|
||||
m_Array.AddAttribute(&m_Tangent);
|
||||
|
||||
// floats per vertex; position + normal + tangent + UV*sets
|
||||
// floats per vertex; position + normal + tangent + UV*sets [+ GPUskinning]
|
||||
int numVertexAttrs = 3 + 3 + 4 + 2 * mdef->GetNumUVsPerVertex();
|
||||
if (gpuSkinning)
|
||||
{
|
||||
numVertexAttrs += 8;
|
||||
}
|
||||
|
||||
// the tangent generation can increase the number of vertices temporarily
|
||||
// so reserve a bit more memory to avoid reallocations in GenTangents (in most cases)
|
||||
@ -102,7 +118,7 @@ IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning, bool calculateT
|
||||
newVertices.reserve(numVertexAttrs * numVertices * 2);
|
||||
|
||||
// Generate the tangents
|
||||
ModelRenderer::GenTangents(mdef, newVertices);
|
||||
ModelRenderer::GenTangents(mdef, newVertices, gpuSkinning);
|
||||
|
||||
// how many vertices do we have after generating tangents?
|
||||
int newNumVert = newVertices.size() / numVertexAttrs;
|
||||
@ -123,23 +139,44 @@ IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning, bool calculateT
|
||||
VertexArrayIterator<CVector3D> Normal = m_Normal.GetIterator<CVector3D>();
|
||||
VertexArrayIterator<CVector4D> Tangent = m_Tangent.GetIterator<CVector4D>();
|
||||
|
||||
VertexArrayIterator<u8[4]> BlendJoints;
|
||||
VertexArrayIterator<u8[4]> BlendWeights;
|
||||
if (gpuSkinning)
|
||||
{
|
||||
BlendJoints = m_BlendJoints.GetIterator<u8[4]>();
|
||||
BlendWeights = m_BlendWeights.GetIterator<u8[4]>();
|
||||
}
|
||||
|
||||
// copy everything into the vertex array
|
||||
for (int i = 0; i < numVertices2; i++)
|
||||
{
|
||||
int q = numVertexAttrs * i;
|
||||
|
||||
Position[i] = CVector3D(vertexDataOut[q + 0], vertexDataOut[q + 1], vertexDataOut[q + 2]);
|
||||
q += 3;
|
||||
|
||||
Normal[i] = CVector3D(vertexDataOut[q + 3], vertexDataOut[q + 4], vertexDataOut[q + 5]);
|
||||
Normal[i] = CVector3D(vertexDataOut[q + 0], vertexDataOut[q + 1], vertexDataOut[q + 2]);
|
||||
q += 3;
|
||||
|
||||
Tangent[i] = CVector4D(vertexDataOut[q + 6], vertexDataOut[q + 7], vertexDataOut[q + 8],
|
||||
vertexDataOut[q + 9]);
|
||||
Tangent[i] = CVector4D(vertexDataOut[q + 0], vertexDataOut[q + 1], vertexDataOut[q + 2],
|
||||
vertexDataOut[q + 3]);
|
||||
q += 4;
|
||||
|
||||
if (gpuSkinning)
|
||||
{
|
||||
for (size_t j = 0; j < 4; ++j)
|
||||
{
|
||||
BlendJoints[i][j] = (u8)vertexDataOut[q + 0 + 2 * j];
|
||||
BlendWeights[i][j] = (u8)vertexDataOut[q + 1 + 2 * j];
|
||||
}
|
||||
q += 8;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < mdef->GetNumUVsPerVertex(); j++)
|
||||
{
|
||||
VertexArrayIterator<float[2]> UVit = m_UVs[j].GetIterator<float[2]>();
|
||||
UVit[i][0] = vertexDataOut[q + 10 + 2 * j];
|
||||
UVit[i][1] = vertexDataOut[q + 11 + 2 * j];
|
||||
UVit[i][0] = vertexDataOut[q + 0 + 2 * j];
|
||||
UVit[i][1] = vertexDataOut[q + 1 + 2 * j];
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,17 +206,6 @@ IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning, bool calculateT
|
||||
{
|
||||
// Upload model without calculating tangents:-
|
||||
|
||||
if (gpuSkinning)
|
||||
{
|
||||
m_BlendJoints.type = GL_UNSIGNED_BYTE;
|
||||
m_BlendJoints.elems = 4;
|
||||
m_Array.AddAttribute(&m_BlendJoints);
|
||||
|
||||
m_BlendWeights.type = GL_UNSIGNED_BYTE;
|
||||
m_BlendWeights.elems = 4;
|
||||
m_Array.AddAttribute(&m_BlendWeights);
|
||||
}
|
||||
|
||||
m_Array.SetNumVertices(numVertices);
|
||||
m_Array.Layout();
|
||||
|
||||
|
@ -25,40 +25,42 @@
|
||||
#include "graphics/ModelDef.h"
|
||||
#include "graphics/ShaderManager.h"
|
||||
#include "graphics/TextureManager.h"
|
||||
#include "graphics/mikktspace.h"
|
||||
|
||||
#include "renderer/MikktspaceWrap.h"
|
||||
|
||||
#include "third_party/mikktspace/mikktspace.h"
|
||||
|
||||
|
||||
MikkTSpace::MikkTSpace(const CModelDefPtr& m, std::vector<float>& v) : model(m), newVertices(v)
|
||||
|
||||
MikkTSpace::MikkTSpace(const CModelDefPtr& m, std::vector<float>& v, bool gpuSkinning) : m_Model(m),
|
||||
m_NewVertices(v), m_GpuSkinning(gpuSkinning)
|
||||
{
|
||||
// ensure that newVertices is empty
|
||||
newVertices.clear();
|
||||
// ensure that m_NewVertices is empty
|
||||
m_NewVertices.clear();
|
||||
|
||||
// set up SMikkTSpaceInterface struct
|
||||
interface.m_getNumFaces = getNumFaces;
|
||||
interface.m_getNumVerticesOfFace = getNumVerticesOfFace;
|
||||
interface.m_getPosition = getPosition;
|
||||
interface.m_getNormal = getNormal;
|
||||
interface.m_getTexCoord = getTexCoord;
|
||||
interface.m_setTSpaceBasic = NULL;
|
||||
interface.m_setTSpace = setTSpace;
|
||||
m_Interface.m_getNumFaces = getNumFaces;
|
||||
m_Interface.m_getNumVerticesOfFace = getNumVerticesOfFace;
|
||||
m_Interface.m_getPosition = getPosition;
|
||||
m_Interface.m_getNormal = getNormal;
|
||||
m_Interface.m_getTexCoord = getTexCoord;
|
||||
m_Interface.m_setTSpaceBasic = NULL;
|
||||
m_Interface.m_setTSpace = setTSpace;
|
||||
|
||||
// set up SMikkTSpaceContext struct
|
||||
context.m_pInterface = &interface;
|
||||
context.m_pUserData = (void*)this;
|
||||
m_Context.m_pInterface = &m_Interface;
|
||||
m_Context.m_pUserData = (void*)this;
|
||||
}
|
||||
|
||||
void MikkTSpace::generate()
|
||||
{
|
||||
genTangSpaceDefault(&context);
|
||||
genTangSpaceDefault(&m_Context);
|
||||
}
|
||||
|
||||
|
||||
int MikkTSpace::getNumFaces(const SMikkTSpaceContext *pContext)
|
||||
{
|
||||
return ((MikkTSpace*)pContext->m_pUserData)->model->GetNumFaces();
|
||||
return ((MikkTSpace*)pContext->m_pUserData)->m_Model->GetNumFaces();
|
||||
}
|
||||
|
||||
|
||||
@ -71,9 +73,9 @@ int MikkTSpace::getNumVerticesOfFace(const SMikkTSpaceContext* UNUSED(pContext),
|
||||
void MikkTSpace::getPosition(const SMikkTSpaceContext *pContext,
|
||||
float fvPosOut[], const int iFace, const int iVert)
|
||||
{
|
||||
SModelFace &face = ((MikkTSpace*)pContext->m_pUserData)->model->GetFaces()[iFace];
|
||||
SModelFace &face = ((MikkTSpace*)pContext->m_pUserData)->m_Model->GetFaces()[iFace];
|
||||
long i = face.m_Verts[iVert];
|
||||
const CVector3D &p = ((MikkTSpace*)pContext->m_pUserData)->model->GetVertices()[i].m_Coords;
|
||||
const CVector3D &p = ((MikkTSpace*)pContext->m_pUserData)->m_Model->GetVertices()[i].m_Coords;
|
||||
|
||||
fvPosOut[0] = p.X;
|
||||
fvPosOut[1] = p.Y;
|
||||
@ -84,9 +86,9 @@ void MikkTSpace::getPosition(const SMikkTSpaceContext *pContext,
|
||||
void MikkTSpace::getNormal(const SMikkTSpaceContext *pContext,
|
||||
float fvNormOut[], const int iFace, const int iVert)
|
||||
{
|
||||
SModelFace &face = ((MikkTSpace*)pContext->m_pUserData)->model->GetFaces()[iFace];
|
||||
SModelFace &face = ((MikkTSpace*)pContext->m_pUserData)->m_Model->GetFaces()[iFace];
|
||||
long i = face.m_Verts[iVert];
|
||||
const CVector3D &n = ((MikkTSpace*)pContext->m_pUserData)->model->GetVertices()[i].m_Norm;
|
||||
const CVector3D &n = ((MikkTSpace*)pContext->m_pUserData)->m_Model->GetVertices()[i].m_Norm;
|
||||
|
||||
fvNormOut[0] = n.X;
|
||||
fvNormOut[1] = n.Y;
|
||||
@ -97,9 +99,9 @@ void MikkTSpace::getNormal(const SMikkTSpaceContext *pContext,
|
||||
void MikkTSpace::getTexCoord(const SMikkTSpaceContext *pContext,
|
||||
float fvTexcOut[], const int iFace, const int iVert)
|
||||
{
|
||||
SModelFace &face = ((MikkTSpace*)pContext->m_pUserData)->model->GetFaces()[iFace];
|
||||
SModelFace &face = ((MikkTSpace*)pContext->m_pUserData)->m_Model->GetFaces()[iFace];
|
||||
long i = face.m_Verts[iVert];
|
||||
SModelVertex &v = ((MikkTSpace*)pContext->m_pUserData)->model->GetVertices()[i];
|
||||
SModelVertex &v = ((MikkTSpace*)pContext->m_pUserData)->m_Model->GetVertices()[i];
|
||||
|
||||
// the tangents are calculated according to the 'default' UV set
|
||||
fvTexcOut[0] = v.m_UVs[0];
|
||||
@ -111,33 +113,42 @@ void MikkTSpace::setTSpace(const SMikkTSpaceContext * pContext, const float fvTa
|
||||
const float UNUSED(fvBiTangent)[], const float UNUSED(fMagS), const float UNUSED(fMagT),
|
||||
const tbool bIsOrientationPreserving, const int iFace, const int iVert)
|
||||
{
|
||||
SModelFace &face = ((MikkTSpace*)pContext->m_pUserData)->model->GetFaces()[iFace];
|
||||
SModelFace &face = ((MikkTSpace*)pContext->m_pUserData)->m_Model->GetFaces()[iFace];
|
||||
long i = face.m_Verts[iVert];
|
||||
|
||||
SModelVertex* vertices = ((MikkTSpace*)pContext->m_pUserData)->model->GetVertices();
|
||||
size_t numUVsPerVertex = ((MikkTSpace*)pContext->m_pUserData)->model->GetNumUVsPerVertex();
|
||||
std::vector<float>& newVertices = ((MikkTSpace*)pContext->m_pUserData)->newVertices;
|
||||
SModelVertex* vertices = ((MikkTSpace*)pContext->m_pUserData)->m_Model->GetVertices();
|
||||
size_t numUVsPerVertex = ((MikkTSpace*)pContext->m_pUserData)->m_Model->GetNumUVsPerVertex();
|
||||
std::vector<float>& m_NewVertices = ((MikkTSpace*)pContext->m_pUserData)->m_NewVertices;
|
||||
|
||||
const CVector3D &p = vertices[i].m_Coords;
|
||||
const CVector3D &n = vertices[i].m_Norm;
|
||||
|
||||
newVertices.push_back(p.X);
|
||||
newVertices.push_back(p.Y);
|
||||
newVertices.push_back(p.Z);
|
||||
m_NewVertices.push_back(p.X);
|
||||
m_NewVertices.push_back(p.Y);
|
||||
m_NewVertices.push_back(p.Z);
|
||||
|
||||
newVertices.push_back(n.X);
|
||||
newVertices.push_back(n.Y);
|
||||
newVertices.push_back(n.Z);
|
||||
m_NewVertices.push_back(n.X);
|
||||
m_NewVertices.push_back(n.Y);
|
||||
m_NewVertices.push_back(n.Z);
|
||||
|
||||
newVertices.push_back(fvTangent[0]);
|
||||
newVertices.push_back(fvTangent[1]);
|
||||
newVertices.push_back(fvTangent[2]);
|
||||
newVertices.push_back(bIsOrientationPreserving > 0.5 ? 1.0f : (-1.0f));
|
||||
m_NewVertices.push_back(fvTangent[0]);
|
||||
m_NewVertices.push_back(fvTangent[1]);
|
||||
m_NewVertices.push_back(fvTangent[2]);
|
||||
m_NewVertices.push_back(bIsOrientationPreserving > 0.5 ? 1.0f : (-1.0f));
|
||||
|
||||
if (((MikkTSpace*)pContext->m_pUserData)->m_GpuSkinning)
|
||||
{
|
||||
for (size_t j = 0; j < 4; ++j)
|
||||
{
|
||||
m_NewVertices.push_back(vertices[i].m_Blend.m_Bone[j]);
|
||||
m_NewVertices.push_back(255.f * vertices[i].m_Blend.m_Weight[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t UVset = 0; UVset < numUVsPerVertex; ++UVset)
|
||||
{
|
||||
newVertices.push_back(vertices[i].m_UVs[UVset * 2]);
|
||||
newVertices.push_back(1.0 - vertices[i].m_UVs[UVset * 2 + 1]);
|
||||
m_NewVertices.push_back(vertices[i].m_UVs[UVset * 2]);
|
||||
m_NewVertices.push_back(1.0 - vertices[i].m_UVs[UVset * 2 + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define INCLUDED_MIKKWRAP
|
||||
|
||||
|
||||
#include "graphics/mikktspace.h"
|
||||
#include "third_party/mikktspace/mikktspace.h"
|
||||
|
||||
// Disable useless MSVC warning
|
||||
#if MSC_VERSION
|
||||
@ -31,18 +31,19 @@ class MikkTSpace
|
||||
|
||||
public:
|
||||
|
||||
MikkTSpace(const CModelDefPtr& m, std::vector<float>& v);
|
||||
MikkTSpace(const CModelDefPtr& m, std::vector<float>& v, bool gpuSkinning);
|
||||
|
||||
void generate();
|
||||
|
||||
private:
|
||||
|
||||
SMikkTSpaceInterface interface;
|
||||
SMikkTSpaceContext context;
|
||||
SMikkTSpaceInterface m_Interface;
|
||||
SMikkTSpaceContext m_Context;
|
||||
|
||||
const CModelDefPtr& model;
|
||||
const CModelDefPtr& m_Model;
|
||||
|
||||
std::vector<float>& newVertices;
|
||||
std::vector<float>& m_NewVertices;
|
||||
bool m_GpuSkinning;
|
||||
|
||||
|
||||
// Returns the number of faces (triangles/quads) on the mesh to be processed.
|
||||
@ -66,20 +67,6 @@ private:
|
||||
float fvTexcOut[], const int iFace, const int iVert);
|
||||
|
||||
|
||||
// either (or both) of the two setTSpace callbacks can be set.
|
||||
// The call-back m_setTSpaceBasic() is sufficient for basic normal mapping.
|
||||
|
||||
// This function is used to return the tangent and fSign to the application.
|
||||
// fvTangent is a unit length vector.
|
||||
// For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
|
||||
// bitangent = fSign * cross(vN, tangent);
|
||||
// Note that the results are returned unindexed. It is possible to generate a new index list
|
||||
// But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
|
||||
// DO NOT! use an already existing index list.
|
||||
//void setTSpaceBasic(const MikkTSpace *parent, const SMikkTSpaceContext *pContext,
|
||||
// const float fvTangent[], const float fSign, const int iFace, const int iVert);
|
||||
|
||||
|
||||
// This function is used to return tangent space results to the application.
|
||||
// fvTangent and fvBiTangent are unit length vectors and fMagS and fMagT are their
|
||||
// true magnitudes which can be used for relief mapping effects.
|
||||
@ -88,9 +75,6 @@ private:
|
||||
// For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
|
||||
// fSign = bIsOrientationPreserving ? 1.0f : (-1.0f);
|
||||
// bitangent = fSign * cross(vN, tangent);
|
||||
// Note that the results are returned unindexed. It is possible to generate a new index list
|
||||
// But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
|
||||
// DO NOT! use an already existing index list.
|
||||
static void setTSpace(const SMikkTSpaceContext * pContext, const float fvTangent[],
|
||||
const float fvBiTangent[], const float fMagS, const float fMagT,
|
||||
const tbool bIsOrientationPreserving, const int iFace, const int iVert);
|
||||
|
@ -149,9 +149,9 @@ void ModelRenderer::BuildColor4ub(
|
||||
}
|
||||
|
||||
|
||||
void ModelRenderer::GenTangents(const CModelDefPtr& mdef, std::vector<float>& newVertices)
|
||||
void ModelRenderer::GenTangents(const CModelDefPtr& mdef, std::vector<float>& newVertices, bool gpuSkinning)
|
||||
{
|
||||
MikkTSpace ms(mdef, newVertices);
|
||||
MikkTSpace ms(mdef, newVertices, gpuSkinning);
|
||||
|
||||
ms.generate();
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ public:
|
||||
* @param newVertices An out vector of the unindexed vertices with tangents added.
|
||||
* The new vertices cannot be used with existing face index and must be welded/reindexed.
|
||||
*/
|
||||
static void GenTangents(const CModelDefPtr& mdef, std::vector<float>& newVertices);
|
||||
static void GenTangents(const CModelDefPtr& mdef, std::vector<float>& newVertices, bool gpuSkinning);
|
||||
};
|
||||
|
||||
|
||||
|
@ -584,7 +584,7 @@ void CRenderer::ReloadShaders()
|
||||
|
||||
if (GetRenderPath() == RP_SHADER && m_Options.m_GPUSkinning) // TODO: should check caps and GLSL etc too
|
||||
{
|
||||
m->Model.VertexGPUSkinningShader = ModelVertexRendererPtr(new InstancingModelRenderer(true, false));
|
||||
m->Model.VertexGPUSkinningShader = ModelVertexRendererPtr(new InstancingModelRenderer(true, m_Options.m_GenTangents));
|
||||
m->Model.NormalSkinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexGPUSkinningShader));
|
||||
m->Model.TranspSkinned = ModelRendererPtr(new ShaderModelRenderer(m->Model.VertexGPUSkinningShader));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user