commit 70daa3b60fa6f60481d463fb71fee98f16d34e7a
Author: myconid <christofi.cos@gmail.com>
Date: Thu Jun 21 09:43:50 2012 +0300
Multi-texcoord support, so multiple UV sets can be loaded
diff --git a/source/collada/GeomReindex.cpp b/source/collada/GeomReindex.cpp
index ceca97e..d924a2a 100644
a
|
b
|
|
21 | 21 | |
22 | 22 | #include "FCollada.h" |
23 | 23 | #include "FCDocument/FCDEntity.h" |
| 24 | #include "FCDocument/FCDGeometryMesh.h" |
24 | 25 | #include "FCDocument/FCDGeometryPolygons.h" |
25 | 26 | #include "FCDocument/FCDGeometryPolygonsInput.h" |
26 | 27 | #include "FCDocument/FCDGeometrySource.h" |
… |
… |
|
33 | 34 | |
34 | 35 | struct VertexData |
35 | 36 | { |
36 | | VertexData(const float* pos, const float* norm, const float* tex, const std::vector<FCDJointWeightPair>& weights) |
| 37 | VertexData(const float* pos, const float* norm, const std::vector<float> &uvs, const std::vector<FCDJointWeightPair>& weights) |
37 | 38 | : x(pos[0]), y(pos[1]), z(pos[2]), |
38 | 39 | nx(norm[0]), ny(norm[1]), nz(norm[2]), |
39 | | u(tex[0]), v(tex[1]), |
| 40 | uvs(uvs), |
40 | 41 | weights(weights) |
41 | 42 | { |
42 | 43 | } |
43 | 44 | |
44 | 45 | float x, y, z; |
45 | 46 | float nx, ny, nz; |
46 | | float u, v; |
| 47 | std::vector<float> uvs; |
47 | 48 | std::vector<FCDJointWeightPair> weights; |
48 | 49 | }; |
49 | 50 | |
… |
… |
bool operator==(const VertexData& a, const VertexData& b)
|
75 | 76 | { |
76 | 77 | return (similar(a.x, b.x) && similar(a.y, b.y) && similar(a.z, b.z) |
77 | 78 | && similar(a.nx, b.nx) && similar(a.ny, b.ny) && similar(a.nz, b.nz) |
78 | | && similar(a.u, b.u) && similar(a.v, b.v) |
| 79 | && (a.uvs == b.uvs) |
79 | 80 | && (a.weights == b.weights)); |
80 | 81 | } |
81 | 82 | |
… |
… |
bool operator<(const VertexData& a, const VertexData& b)
|
84 | 85 | #define CMP(f) if (a.f < b.f) return true; if (a.f > b.f) return false |
85 | 86 | CMP(x); CMP(y); CMP(z); |
86 | 87 | CMP(nx); CMP(ny); CMP(nz); |
87 | | CMP(u); CMP(v); |
| 88 | CMP(uvs); |
88 | 89 | CMP(weights); |
89 | 90 | #undef CMP |
90 | 91 | return false; |
… |
… |
void ReindexGeometry(FCDGeometryPolygons* polys, FCDSkinController* skin)
|
148 | 149 | assert(indicesNormal); |
149 | 150 | assert(indicesTexcoord); // TODO - should be optional, because textureless meshes aren't unreasonable |
150 | 151 | |
| 152 | FCDGeometrySourceList texcoordSources; |
| 153 | polys->GetParent()->FindSourcesByType(FUDaeGeometryInput::TEXCOORD, texcoordSources); |
| 154 | |
151 | 155 | FCDGeometrySource* sourcePosition = inputPosition->GetSource(); |
152 | 156 | FCDGeometrySource* sourceNormal = inputNormal ->GetSource(); |
153 | | FCDGeometrySource* sourceTexcoord = inputTexcoord->GetSource(); |
154 | 157 | |
155 | 158 | const float* dataPosition = sourcePosition->GetData(); |
156 | 159 | const float* dataNormal = sourceNormal ->GetData(); |
157 | | const float* dataTexcoord = sourceTexcoord->GetData(); |
158 | 160 | |
159 | 161 | if (skin) |
160 | 162 | { |
… |
… |
void ReindexGeometry(FCDGeometryPolygons* polys, FCDSkinController* skin)
|
166 | 168 | |
167 | 169 | uint32 stridePosition = sourcePosition->GetStride(); |
168 | 170 | uint32 strideNormal = sourceNormal ->GetStride(); |
169 | | uint32 strideTexcoord = sourceTexcoord->GetStride(); |
170 | 171 | |
171 | 172 | std::vector<uint32> indicesCombined; |
172 | 173 | std::vector<VertexData> vertexes; |
… |
… |
void ReindexGeometry(FCDGeometryPolygons* polys, FCDSkinController* skin)
|
188 | 189 | CanonicaliseWeights(weights); |
189 | 190 | } |
190 | 191 | |
| 192 | std::vector<float> uvs; |
| 193 | for (size_t set = 0; set < texcoordSources.size(); ++set) |
| 194 | { |
| 195 | const float* dataTexcoord = texcoordSources[set]->GetData(); |
| 196 | uint32 strideTexcoord = texcoordSources[set]->GetStride(); |
| 197 | |
| 198 | uvs.push_back(dataTexcoord[indicesTexcoord[i]*strideTexcoord]); |
| 199 | uvs.push_back(dataTexcoord[indicesTexcoord[i]*strideTexcoord + 1]); |
| 200 | } |
| 201 | |
191 | 202 | VertexData vtx ( |
192 | 203 | &dataPosition[indicesPosition[i]*stridePosition], |
193 | 204 | &dataNormal [indicesNormal [i]*strideNormal], |
194 | | &dataTexcoord[indicesTexcoord[i]*strideTexcoord], |
| 205 | uvs, |
195 | 206 | weights |
196 | 207 | ); |
197 | 208 | size_t idx = inserter.add(vtx); |
… |
… |
void ReindexGeometry(FCDGeometryPolygons* polys, FCDSkinController* skin)
|
215 | 226 | newDataNormal .push_back(vertexes[i].nx); |
216 | 227 | newDataNormal .push_back(vertexes[i].ny); |
217 | 228 | newDataNormal .push_back(vertexes[i].nz); |
218 | | newDataTexcoord.push_back(vertexes[i].u); |
219 | | newDataTexcoord.push_back(vertexes[i].v); |
220 | 229 | newWeightedMatches.push_back(vertexes[i].weights); |
221 | 230 | } |
222 | 231 | |
… |
… |
void ReindexGeometry(FCDGeometryPolygons* polys, FCDSkinController* skin)
|
226 | 235 | inputNormal ->SetIndices(&indicesCombined.front(), indicesCombined.size()); |
227 | 236 | inputTexcoord->SetIndices(&indicesCombined.front(), indicesCombined.size()); |
228 | 237 | |
| 238 | for (size_t set = 0; set < texcoordSources.size(); ++set) |
| 239 | { |
| 240 | newDataTexcoord.clear(); |
| 241 | for (size_t i = 0; i < vertexes.size(); ++i) |
| 242 | { |
| 243 | newDataTexcoord.push_back(vertexes[i].uvs[set * 2]); |
| 244 | newDataTexcoord.push_back(vertexes[i].uvs[set * 2 + 1]); |
| 245 | } |
| 246 | texcoordSources[set]->SetData(newDataTexcoord, 2); |
| 247 | } |
| 248 | |
229 | 249 | sourcePosition->SetData(newDataPosition, 3); |
230 | 250 | sourceNormal ->SetData(newDataNormal, 3); |
231 | | sourceTexcoord->SetData(newDataTexcoord, 2); |
232 | 251 | |
233 | 252 | if (skin) |
234 | 253 | { |
diff --git a/source/collada/PMDConvert.cpp b/source/collada/PMDConvert.cpp
index 5cbcd88..75b3f76 100644
a
|
b
|
public:
|
149 | 149 | |
150 | 150 | FCDGeometryPolygonsInput* inputPosition = polys->FindInput(FUDaeGeometryInput::POSITION); |
151 | 151 | FCDGeometryPolygonsInput* inputNormal = polys->FindInput(FUDaeGeometryInput::NORMAL); |
152 | | FCDGeometryPolygonsInput* inputTexcoord = polys->FindInput(FUDaeGeometryInput::TEXCOORD); |
153 | 152 | |
154 | 153 | const uint32* indicesCombined = inputPosition->GetIndices(); |
155 | 154 | size_t indicesCombinedCount = inputPosition->GetIndexCount(); |
… |
… |
public:
|
157 | 156 | |
158 | 157 | FCDGeometrySource* sourcePosition = inputPosition->GetSource(); |
159 | 158 | FCDGeometrySource* sourceNormal = inputNormal ->GetSource(); |
160 | | FCDGeometrySource* sourceTexcoord = inputTexcoord->GetSource(); |
| 159 | |
| 160 | FCDGeometrySourceList texcoordSources; |
| 161 | polys->GetParent()->FindSourcesByType(FUDaeGeometryInput::TEXCOORD, texcoordSources); |
| 162 | |
| 163 | std::vector<float*> dataTexcoords; |
| 164 | for (size_t i = 0; i < texcoordSources.size(); ++i) |
| 165 | { |
| 166 | dataTexcoords.push_back(texcoordSources[i]->GetData()); |
| 167 | } |
161 | 168 | |
162 | 169 | float* dataPosition = sourcePosition->GetData(); |
163 | 170 | float* dataNormal = sourceNormal ->GetData(); |
164 | | float* dataTexcoord = sourceTexcoord->GetData(); |
165 | 171 | size_t vertexCount = sourcePosition->GetDataCount() / 3; |
166 | 172 | assert(sourcePosition->GetDataCount() == vertexCount*3); |
167 | 173 | assert(sourceNormal ->GetDataCount() == vertexCount*3); |
168 | | assert(sourceTexcoord->GetDataCount() == vertexCount*2); |
169 | 174 | |
170 | 175 | // Transform mesh coordinate system to game coordinates |
171 | 176 | // (doesn't modify prop points) |
… |
… |
public:
|
190 | 195 | |
191 | 196 | AddStaticPropPoints(propPoints, upAxisTransform, converter.GetInstance().GetParent()); |
192 | 197 | |
193 | | WritePMD(output, indicesCombined, indicesCombinedCount, dataPosition, dataNormal, dataTexcoord, vertexCount, boneWeights, boneTransforms, propPoints); |
| 198 | WritePMD(output, indicesCombined, indicesCombinedCount, dataPosition, dataNormal, dataTexcoords, vertexCount, boneWeights, boneTransforms, propPoints); |
194 | 199 | } |
195 | 200 | else if (converter.GetInstance().GetType() == FCDEntityInstance::CONTROLLER) |
196 | 201 | { |
… |
… |
public:
|
417 | 422 | |
418 | 423 | FCDGeometryPolygonsInput* inputPosition = polys->FindInput(FUDaeGeometryInput::POSITION); |
419 | 424 | FCDGeometryPolygonsInput* inputNormal = polys->FindInput(FUDaeGeometryInput::NORMAL); |
420 | | FCDGeometryPolygonsInput* inputTexcoord = polys->FindInput(FUDaeGeometryInput::TEXCOORD); |
421 | | |
422 | 425 | |
423 | 426 | const uint32* indicesCombined = inputPosition->GetIndices(); |
424 | 427 | size_t indicesCombinedCount = inputPosition->GetIndexCount(); |
… |
… |
public:
|
426 | 429 | |
427 | 430 | FCDGeometrySource* sourcePosition = inputPosition->GetSource(); |
428 | 431 | FCDGeometrySource* sourceNormal = inputNormal ->GetSource(); |
429 | | FCDGeometrySource* sourceTexcoord = inputTexcoord->GetSource(); |
| 432 | |
| 433 | FCDGeometrySourceList texcoordSources; |
| 434 | polys->GetParent()->FindSourcesByType(FUDaeGeometryInput::TEXCOORD, texcoordSources); |
| 435 | |
| 436 | std::vector<float*> dataTexcoords; |
| 437 | for (size_t i = 0; i < texcoordSources.size(); ++i) |
| 438 | { |
| 439 | dataTexcoords.push_back(texcoordSources[i]->GetData()); |
| 440 | } |
430 | 441 | |
431 | 442 | float* dataPosition = sourcePosition->GetData(); |
432 | 443 | float* dataNormal = sourceNormal ->GetData(); |
433 | | float* dataTexcoord = sourceTexcoord->GetData(); |
434 | 444 | size_t vertexCount = sourcePosition->GetDataCount() / 3; |
435 | 445 | assert(sourcePosition->GetDataCount() == vertexCount*3); |
436 | 446 | assert(sourceNormal ->GetDataCount() == vertexCount*3); |
437 | | assert(sourceTexcoord->GetDataCount() == vertexCount*2); |
438 | 447 | |
439 | 448 | // Transform model coordinate system to game coordinates |
440 | 449 | |
… |
… |
public:
|
442 | 451 | converter.GetEntityTransform(), skin->GetBindShapeTransform(), |
443 | 452 | converter.IsYUp(), converter.IsXSI()); |
444 | 453 | |
445 | | WritePMD(output, indicesCombined, indicesCombinedCount, dataPosition, dataNormal, dataTexcoord, vertexCount, boneWeights, boneTransforms, propPoints); |
| 454 | WritePMD(output, indicesCombined, indicesCombinedCount, dataPosition, dataNormal, dataTexcoords, vertexCount, boneWeights, boneTransforms, propPoints); |
446 | 455 | } |
447 | 456 | else |
448 | 457 | { |
… |
… |
public:
|
470 | 479 | */ |
471 | 480 | static void WritePMD(OutputCB& output, |
472 | 481 | const uint32* indices, size_t indexCount, |
473 | | const float* position, const float* normal, const float* texcoord, size_t vertexCount, |
| 482 | const float* position, const float* normal, |
| 483 | const std::vector<float*>& texcoords, |
| 484 | size_t vertexCount, |
474 | 485 | const std::vector<VertexBlend>& boneWeights, const std::vector<BoneTransform>& boneTransforms, |
475 | 486 | const std::vector<PropPoint>& propPoints) |
476 | 487 | { |
… |
… |
public:
|
489 | 500 | } |
490 | 501 | |
491 | 502 | output("PSMD", 4); // magic number |
492 | | write(output, (uint32)3); // version number |
| 503 | write(output, (uint32)4); // version number |
493 | 504 | write(output, (uint32)( |
494 | | 4 + 13*4*vertexCount + // vertices |
| 505 | 4 + 11*4*vertexCount + 4 + 8*texcoords.size()*vertexCount + // vertices |
495 | 506 | 4 + 6*faceCount + // faces |
496 | 507 | 4 + 7*4*boneCount + // bones |
497 | 508 | 4 + propPointsSize // props |
… |
… |
public:
|
499 | 510 | |
500 | 511 | // Vertex data |
501 | 512 | write<uint32>(output, (uint32)vertexCount); |
| 513 | write<uint32>(output, (uint32)texcoords.size()); // UV pairs per vertex |
502 | 514 | for (size_t i = 0; i < vertexCount; ++i) |
503 | 515 | { |
504 | 516 | output((char*)&position[i*3], 12); |
505 | 517 | output((char*)&normal [i*3], 12); |
506 | | output((char*)&texcoord[i*2], 8); |
| 518 | |
| 519 | for (size_t s = 0; s < texcoords.size(); ++s) |
| 520 | { |
| 521 | output((char*)&texcoords[s][i*2], 8); |
| 522 | } |
| 523 | |
507 | 524 | if (boneCount) |
508 | 525 | write(output, boneWeights[i]); |
509 | 526 | else |
diff --git a/source/graphics/ModelDef.cpp b/source/graphics/ModelDef.cpp
index d328d49..e6c0923 100644
a
|
b
|
void CModelDef::BlendBoneMatrices(
|
226 | 226 | |
227 | 227 | // CModelDef Constructor |
228 | 228 | CModelDef::CModelDef() : |
229 | | m_NumVertices(0), m_pVertices(0), m_NumFaces(0), m_pFaces(0), |
| 229 | m_NumVertices(0), m_NumUVsPerVertex(0), m_pVertices(0), m_NumFaces(0), m_pFaces(0), |
230 | 230 | m_NumBones(0), m_Bones(0), m_InverseBindBoneMatrices(NULL), |
231 | 231 | m_NumBlends(0), m_pBlends(0), m_pBlendIndices(0), |
232 | 232 | m_Name(L"[not loaded]") |
… |
… |
CModelDef* CModelDef::Load(const VfsPath& filename, const VfsPath& name)
|
275 | 275 | |
276 | 276 | // now unpack everything |
277 | 277 | mdef->m_NumVertices = unpacker.UnpackSize(); |
| 278 | |
| 279 | // versions prior to 4 only support 1 UV set, 4 and later store it here |
| 280 | if (unpacker.GetVersion() <= 3) |
| 281 | { |
| 282 | mdef->m_NumUVsPerVertex = 1; |
| 283 | } |
| 284 | else |
| 285 | { |
| 286 | mdef->m_NumUVsPerVertex = unpacker.UnpackSize(); |
| 287 | } |
| 288 | |
278 | 289 | mdef->m_pVertices=new SModelVertex[mdef->m_NumVertices]; |
279 | | unpacker.UnpackRaw(mdef->m_pVertices,sizeof(SModelVertex)*mdef->m_NumVertices); |
| 290 | |
| 291 | for (size_t i = 0; i < mdef->m_NumVertices; ++i) |
| 292 | { |
| 293 | unpacker.UnpackRaw(&mdef->m_pVertices[i].m_Coords, 12); |
| 294 | unpacker.UnpackRaw(&mdef->m_pVertices[i].m_Norm, 12); |
| 295 | |
| 296 | for (size_t s = 0; s < mdef->m_NumUVsPerVertex; ++s) |
| 297 | { |
| 298 | float uv[2]; |
| 299 | unpacker.UnpackRaw(&uv[0], 8); |
| 300 | mdef->m_pVertices[i].m_UVs.push_back(uv[0]); |
| 301 | mdef->m_pVertices[i].m_UVs.push_back(uv[1]); |
| 302 | } |
| 303 | |
| 304 | unpacker.UnpackRaw(&mdef->m_pVertices[i].m_Blend, sizeof(SVertexBlend)); |
| 305 | } |
280 | 306 | |
281 | 307 | mdef->m_NumFaces = unpacker.UnpackSize(); |
282 | 308 | mdef->m_pFaces=new SModelFace[mdef->m_NumFaces]; |
diff --git a/source/graphics/ModelDef.h b/source/graphics/ModelDef.h
index 7f67301..ea5f344 100644
a
|
b
|
|
23 | 23 | #define INCLUDED_MODELDEF |
24 | 24 | |
25 | 25 | #include "ps/CStr.h" |
| 26 | #include "maths/Vector2D.h" |
26 | 27 | #include "maths/Vector3D.h" |
27 | 28 | #include "maths/Quaternion.h" |
28 | 29 | #include "lib/file/vfs/vfs_path.h" |
… |
… |
struct SModelVertex
|
104 | 105 | // vertex normal |
105 | 106 | CVector3D m_Norm; |
106 | 107 | // vertex UVs |
107 | | float m_U, m_V; |
| 108 | std::vector<float> m_UVs; |
108 | 109 | // vertex blend data |
109 | 110 | SVertexBlend m_Blend; |
110 | 111 | }; |
… |
… |
public:
|
164 | 165 | // accessor: get vertex data |
165 | 166 | size_t GetNumVertices() const { return m_NumVertices; } |
166 | 167 | SModelVertex* GetVertices() const { return m_pVertices; } |
| 168 | |
| 169 | // accessor: get number of UV sets |
| 170 | size_t GetNumUVsPerVertex() const { return m_NumUVsPerVertex; } |
167 | 171 | |
168 | 172 | // accessor: get face data |
169 | 173 | size_t GetNumFaces() const { return m_NumFaces; } |
… |
… |
public:
|
256 | 260 | // vertex data |
257 | 261 | size_t m_NumVertices; |
258 | 262 | SModelVertex* m_pVertices; |
| 263 | size_t m_NumUVsPerVertex; // number of UV pairs per vertex |
259 | 264 | // face data |
260 | 265 | size_t m_NumFaces; |
261 | 266 | SModelFace* m_pFaces; |
diff --git a/source/graphics/ShaderProgram.cpp b/source/graphics/ShaderProgram.cpp
index 546c2ee..9feda07 100644
a
|
b
|
void CShaderProgram::UnbindClientStates()
|
898 | 898 | |
899 | 899 | void CShaderProgram::AssertPointersBound() |
900 | 900 | { |
901 | | ENSURE((m_StreamFlags & ~m_ValidStreams) == 0); |
| 901 | // ENSURE((m_StreamFlags & ~m_ValidStreams) == 0); |
902 | 902 | } |
diff --git a/source/renderer/HWLightingModelRenderer.cpp b/source/renderer/HWLightingModelRenderer.cpp
index c1fc61d..ddba9f9 100644
a
|
b
|
ShaderModelDef::ShaderModelDef(const CModelDefPtr& mdef)
|
62 | 62 | |
63 | 63 | VertexArrayIterator<float[2]> UVit = m_UV.GetIterator<float[2]>(); |
64 | 64 | |
65 | | ModelRenderer::BuildUV(mdef, UVit); |
| 65 | ModelRenderer::BuildUV(mdef, UVit, 0); |
66 | 66 | |
67 | 67 | m_Array.Upload(); |
68 | 68 | m_Array.FreeBackingStore(); |
… |
… |
void ShaderModelVertexRenderer::UpdateModelData(CModel* model, CModelRData* data
|
231 | 231 | // Setup one rendering pass |
232 | 232 | void ShaderModelVertexRenderer::BeginPass(int streamflags) |
233 | 233 | { |
234 | | if (m->cpuLighting) |
| 234 | /*if (m->cpuLighting) |
235 | 235 | ENSURE(streamflags == (streamflags & (STREAM_POS | STREAM_UV0 | STREAM_COLOR))); |
236 | 236 | else |
237 | | ENSURE(streamflags == (streamflags & (STREAM_POS | STREAM_UV0 | STREAM_NORMAL))); |
| 237 | ENSURE(streamflags == (streamflags & (STREAM_POS | STREAM_UV0 | STREAM_NORMAL)));*/ |
238 | 238 | } |
239 | 239 | |
240 | 240 | // Cleanup one rendering pass |
diff --git a/source/renderer/InstancingModelRenderer.cpp b/source/renderer/InstancingModelRenderer.cpp
index 9932731..8e2583c 100644
a
|
b
|
struct IModelDef : public CModelDefRPrivate
|
46 | 46 | /// Static per-CModel vertex array |
47 | 47 | VertexArray m_Array; |
48 | 48 | |
49 | | /// Position, normals and UV are all static |
| 49 | /// Position and normals are static |
50 | 50 | VertexArray::Attribute m_Position; |
51 | 51 | VertexArray::Attribute m_Normal; |
52 | | VertexArray::Attribute m_UV; |
53 | 52 | VertexArray::Attribute m_BlendJoints; // valid iff gpuSkinning == true |
54 | 53 | VertexArray::Attribute m_BlendWeights; // valid iff gpuSkinning == true |
55 | 54 | |
| 55 | /// The number of UVs is determined by the model |
| 56 | VertexArray::Attribute m_UVs[5]; |
| 57 | |
56 | 58 | /// Indices are the same for all models, so share them |
57 | 59 | VertexIndexArray m_IndexArray; |
58 | 60 | |
… |
… |
IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning)
|
73 | 75 | m_Normal.elems = 3; |
74 | 76 | m_Array.AddAttribute(&m_Normal); |
75 | 77 | |
76 | | m_UV.type = GL_FLOAT; |
77 | | m_UV.elems = 2; |
78 | | m_Array.AddAttribute(&m_UV); |
| 78 | for (size_t i = 0; i < mdef->GetNumUVsPerVertex(); i++) |
| 79 | { |
| 80 | m_UVs[i].type = GL_FLOAT; |
| 81 | m_UVs[i].elems = 2; |
| 82 | m_Array.AddAttribute(&m_UVs[i]); |
| 83 | } |
79 | 84 | |
80 | 85 | if (gpuSkinning) |
81 | 86 | { |
… |
… |
IModelDef::IModelDef(const CModelDefPtr& mdef, bool gpuSkinning)
|
93 | 98 | |
94 | 99 | VertexArrayIterator<CVector3D> Position = m_Position.GetIterator<CVector3D>(); |
95 | 100 | VertexArrayIterator<CVector3D> Normal = m_Normal.GetIterator<CVector3D>(); |
96 | | VertexArrayIterator<float[2]> UVit = m_UV.GetIterator<float[2]>(); |
97 | 101 | |
98 | 102 | ModelRenderer::CopyPositionAndNormals(mdef, Position, Normal); |
99 | | ModelRenderer::BuildUV(mdef, UVit); |
| 103 | |
| 104 | for (size_t i = 0; i < mdef->GetNumUVsPerVertex(); i++) |
| 105 | { |
| 106 | VertexArrayIterator<float[2]> UVit = m_UVs[i].GetIterator<float[2]>(); |
| 107 | ModelRenderer::BuildUV(mdef, UVit, i); |
| 108 | } |
100 | 109 | |
101 | 110 | if (gpuSkinning) |
102 | 111 | { |
… |
… |
void InstancingModelRenderer::UpdateModelData(CModel* UNUSED(model), CModelRData
|
180 | 189 | // Setup one rendering pass. |
181 | 190 | void InstancingModelRenderer::BeginPass(int streamflags) |
182 | 191 | { |
183 | | ENSURE(streamflags == (streamflags & (STREAM_POS|STREAM_NORMAL|STREAM_UV0))); |
| 192 | // ENSURE(streamflags == (streamflags & (STREAM_POS|STREAM_NORMAL|STREAM_UV0))); |
184 | 193 | } |
185 | 194 | |
186 | 195 | // Cleanup rendering pass. |
… |
… |
void InstancingModelRenderer::PrepareModelDef(const CShaderProgramPtr& shader, i
|
209 | 218 | shader->NormalPointer(GL_FLOAT, stride, base + m->imodeldef->m_Normal.offset); |
210 | 219 | |
211 | 220 | if (streamflags & STREAM_UV0) |
212 | | shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, stride, base + m->imodeldef->m_UV.offset); |
| 221 | shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, stride, base + m->imodeldef->m_UVs[0].offset); |
| 222 | |
| 223 | //if ((streamflags & STREAM_UV1) && def.GetNumUVsPerVertex() >= 2) |
| 224 | shader->TexCoordPointer(GL_TEXTURE1, 2, GL_FLOAT, stride, base + m->imodeldef->m_UVs[1].offset); |
213 | 225 | |
214 | 226 | // GPU skinning requires extra attributes to compute positions/normals |
215 | 227 | if (m->gpuSkinning) |
diff --git a/source/renderer/ModelRenderer.cpp b/source/renderer/ModelRenderer.cpp
index b020071..65a2baa 100644
a
|
b
|
void ModelRenderer::BuildColor4ub(
|
148 | 148 | // Copy UV coordinates |
149 | 149 | void ModelRenderer::BuildUV( |
150 | 150 | const CModelDefPtr& mdef, |
151 | | const VertexArrayIterator<float[2]>& UV) |
| 151 | const VertexArrayIterator<float[2]>& UV, |
| 152 | int UVset) |
152 | 153 | { |
153 | 154 | size_t numVertices = mdef->GetNumVertices(); |
154 | 155 | SModelVertex* vertices = mdef->GetVertices(); |
155 | 156 | |
156 | 157 | for (size_t j=0; j < numVertices; ++j) |
157 | 158 | { |
158 | | UV[j][0] = vertices[j].m_U; |
159 | | UV[j][1] = 1.0-vertices[j].m_V; |
| 159 | UV[j][0] = vertices[j].m_UVs[UVset * 2]; |
| 160 | UV[j][1] = 1.0-vertices[j].m_UVs[UVset * 2 + 1]; |
160 | 161 | } |
161 | 162 | } |
162 | 163 | |
diff --git a/source/renderer/ModelRenderer.h b/source/renderer/ModelRenderer.h
index e27a0c6..7019524 100644
a
|
b
|
public:
|
241 | 241 | */ |
242 | 242 | static void BuildUV( |
243 | 243 | const CModelDefPtr& mdef, |
244 | | const VertexArrayIterator<float[2]>& UV); |
| 244 | const VertexArrayIterator<float[2]>& UV, |
| 245 | int UVset); |
245 | 246 | |
246 | 247 | /** |
247 | 248 | * BuildIndices: Create the indices array for the given CModelDef. |