Commits

Lars Viklund committed fcddf58

Fixup UV generation, materials

Comments (0)

Files changed (4)

meshes/workspace.mel

+//Maya 2014 x64 Project Definition
+
+workspace -fr "scene" "scenes";
+workspace -fr "3dPaintTextures" "sourceimages/3dPaintTextures";
+workspace -fr "eps" "data";
+workspace -fr "mel" "scripts";
+workspace -fr "particles" "cache/particles";
+workspace -fr "STEP_DC" "data";
+workspace -fr "CATIAV5_DC" "data";
+workspace -fr "sound" "sound";
+workspace -fr "furFiles" "renderData/fur/furFiles";
+workspace -fr "depth" "renderData/depth";
+workspace -fr "CATIAV4_DC" "data";
+workspace -fr "autoSave" "autosave";
+workspace -fr "diskCache" "data";
+workspace -fr "fileCache" "cache/nCache";
+workspace -fr "IPT_DC" "data";
+workspace -fr "SW_DC" "data";
+workspace -fr "DAE_FBX export" "data";
+workspace -fr "Autodesk Packet File" "data";
+workspace -fr "DAE_FBX" "data";
+workspace -fr "DXF_DCE" "data";
+workspace -fr "mayaAscii" "scenes";
+workspace -fr "iprImages" "renderData/iprImages";
+workspace -fr "move" "data";
+workspace -fr "mayaBinary" "scenes";
+workspace -fr "fluidCache" "cache/nCache/fluid";
+workspace -fr "clips" "clips";
+workspace -fr "templates" "assets";
+workspace -fr "DWG_DC" "data";
+workspace -fr "offlineEdit" "scenes/edits";
+workspace -fr "translatorData" "data";
+workspace -fr "DXF_DC" "data";
+workspace -fr "renderData" "renderData";
+workspace -fr "SPF_DCE" "data";
+workspace -fr "ZPR_DCE" "data";
+workspace -fr "furShadowMap" "renderData/fur/furShadowMap";
+workspace -fr "audio" "sound";
+workspace -fr "IV_DC" "data";
+workspace -fr "scripts" "scripts";
+workspace -fr "STL_DCE" "data";
+workspace -fr "furAttrMap" "renderData/fur/furAttrMap";
+workspace -fr "FBX export" "data";
+workspace -fr "JT_DC" "data";
+workspace -fr "sourceImages" "sourceimages";
+workspace -fr "DWG_DCE" "data";
+workspace -fr "FBX" "data";
+workspace -fr "movie" "movies";
+workspace -fr "Alembic" "data";
+workspace -fr "furImages" "renderData/fur/furImages";
+workspace -fr "IGES_DC" "data";
+workspace -fr "illustrator" "data";
+workspace -fr "furEqualMap" "renderData/fur/furEqualMap";
+workspace -fr "UG_DC" "data";
+workspace -fr "images" "images";
+workspace -fr "SPF_DC" "data";
+workspace -fr "PTC_DC" "data";
+workspace -fr "OBJ" "data";
+workspace -fr "CSB_DC" "data";
+workspace -fr "STL_DC" "data";
+workspace -fr "IGES_DCE" "data";
+workspace -fr "shaders" "renderData/shaders";
+workspace -fr "UG_DCE" "data";
   auto WindowStyle = Options.Fullscreen ?
     sf::Style::Fullscreen :
     sf::Style::Default;
-  sf::RenderWindow Window(VideoMode, "Klappjakten", WindowStyle);
+  sf::ContextSettings ContextSettings;
+  ContextSettings.depthBits = 32;
+  sf::RenderWindow Window(VideoMode, "Klappjakten", WindowStyle, ContextSettings);
   Window.setVerticalSyncEnabled(true);
   Window.setMouseCursorVisible(false);
 
   GameState State;
   State.Level = assembleLevel(Blueprint);
 
-  Mesh GiftMesh = loadMesh("meshes/gift1.dae");
+  Mesh GiftMesh = loadMesh("meshes", "gift1.dae");
   MeshInstance GiftMeshInstance;
   GiftMeshInstance.setMesh(&GiftMesh);
 
-  Mesh SledMesh = loadMesh("meshes/Sleigh.DAE");
+  Mesh SledMesh = loadMesh("meshes", "Sleigh.DAE");
   MeshInstance SledMeshInstance;
   SledMeshInstance.setMesh(&SledMesh);
 
       TempPositions.reserve(9);
       Window.clear(sf::Color::Black);
       Window.pushGLStates();
-//      sf::Texture::bind(&*BackgroundStarfield.Textures.front());
+      glClear(GL_DEPTH_BUFFER_BIT);
+      glEnable(GL_DEPTH_TEST);
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
       gluPerspective(45, 16.0f / 9.0f, 0.1f, 100.0f);
       glMatrixMode(GL_MODELVIEW);
       glLoadIdentity();
-      glTranslatef(0.0f, 0.0f, -10.0f);
-      glScalef(0.1f, 0.1f, 0.1f);
-      GiftMeshInstance.draw();
+      glTranslatef(0.0f, -2.0f, -50.0f);
+      glScalef(0.2f, 0.2f, 0.2f);
       SledMeshInstance.draw();
-      glRotatef(Now.asSeconds() * 60.0f, 0.0f, 0.0f, 1.0f);
-      sf::Vector3f Points[] = { { -0.5f, -0.5f, 0.0f }, { 0.5f, -0.5f, 0.0f }, { 0.5f, 0.5f, 0.0f }, { -0.5f, 0.5f, 0.0f } };
-      sf::Vector2f Texcoords[] = { { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 0.0f, 0.0f } };
-      glBegin(GL_TRIANGLES);
-      glTexCoord2fv((float*)&Texcoords[0]);
-      glVertex3fv((float*)&Points[0]);
-      glTexCoord2fv((float*)&Texcoords[1]);
-      glVertex3fv((float*)&Points[1]);
-      glTexCoord2fv((float*)&Texcoords[2]);
-      glVertex3fv((float*)&Points[2]);
-
-      glTexCoord2fv((float*)&Texcoords[0]);
-      glVertex3fv((float*)&Points[0]);
-      glTexCoord2fv((float*)&Texcoords[2]);
-      glVertex3fv((float*)&Points[2]);
-      glTexCoord2fv((float*)&Texcoords[3]);
-      glVertex3fv((float*)&Points[3]);
-      glEnd();
-      sf::Texture::bind(nullptr);
       Window.popGLStates();
 #if 0
       for (auto& Layer : BackgroundStarfield.Layers) {
 #include <cstring>
 #include <vector>
 
+static std::shared_ptr<sf::Texture>
+loadTexture(std::string FullPath) {
+  auto Tex = std::make_shared<sf::Texture>();
+  Tex->loadFromFile(FullPath);
+  Tex->setSmooth(true);
+  return Tex;
+}
+
 Mesh
-loadMesh(char const* filename) {
+loadMesh(char const* BasePath, char const* Filename) {
   Mesh Ret;
   Assimp::Importer Importer;
-  aiScene const* Scene = Importer.ReadFile(filename, aiProcess_Triangulate | aiProcess_PreTransformVertices | aiProcess_JoinIdenticalVertices | aiProcess_TransformUVCoords | aiProcess_GenSmoothNormals);
-  for (unsigned i = 0; i < Scene->mNumMeshes; ++i) {
+  std::string FullPath = std::string(BasePath) + "/" + Filename;
+  auto ProcessFlags =
+    aiProcess_RemoveRedundantMaterials |
+    aiProcess_Triangulate |
+    aiProcess_PreTransformVertices |
+    aiProcess_JoinIdenticalVertices |
+    aiProcess_TransformUVCoords |
+    aiProcess_FlipUVs |
+    aiProcess_GenSmoothNormals |
+    0;
+  aiScene const* Scene = Importer.ReadFile(FullPath, ProcessFlags);
+
+  // ===[Load materials]===
+  for (unsigned i = 0; i < Scene->mNumMaterials; ++i) {
+    auto SourceMat = Scene->mMaterials[i];
+    Mesh::Material Mat;
+
+    aiString Path;
+    int NumTextures = SourceMat->GetTextureCount(aiTextureType_DIFFUSE);
+    if (NumTextures != 0) {
+      if (aiReturn_SUCCESS == SourceMat->GetTexture(aiTextureType_DIFFUSE, 0, &Path)) {
+        Mat.TextureImage = loadTexture(std::string(BasePath) + "/" + Path.C_Str());
+      }
+    }
+    Ret.Materials.push_back(Mat);
+  }
+
+  // ===[Load meshes into source arrays]===
+  for (unsigned i = 0; i < (false ? 1 : Scene->mNumMeshes); ++i) {
     auto SourceMesh = Scene->mMeshes[i];
-   
+    Mesh::SubMesh Sub;
+    Sub.MaterialIndex = SourceMesh->mMaterialIndex;
+
     auto VB = std::make_shared<GLBuffer<OwnedId>>();
-    Ret.NumVertices = SourceMesh->mNumVertices;
+    Sub.NumVertices = SourceMesh->mNumVertices;
     std::vector<char> VertexData;
     {
       enum { NUM_ATTRIBUTES = 3 };
       std::array<float, 3> Normal = { 0.0f, 0.0f, -1.0f }, Normals[] = { Normal, Normal, Normal, Normal };
 #endif
 
-      Ret.PositionAttribute.ByteOffset = 0;
-      Ret.PositionAttribute.Stride = sizeof(aiVector3D);
-      Ret.NormalAttribute.ByteOffset = byteEndOffset(Ret.PositionAttribute, N);
-      Ret.NormalAttribute.Stride = sizeof(aiVector3D);
-      Ret.TexcoordAttribute.ByteOffset = byteEndOffset(Ret.NormalAttribute, N);
-      Ret.TexcoordAttribute.Stride = sizeof(aiVector2D);
+      Sub.PositionAttribute.ByteOffset = 0;
+      Sub.PositionAttribute.Stride = sizeof(aiVector3D);
+      Sub.NormalAttribute.ByteOffset = byteEndOffset(Sub.PositionAttribute, N);
+      Sub.NormalAttribute.Stride = sizeof(aiVector3D);
+      Sub.TexcoordAttribute.ByteOffset = byteEndOffset(Sub.NormalAttribute, N);
+      Sub.TexcoordAttribute.Stride = sizeof(aiVector2D);
 
-      VertexData.resize(byteEndOffset(Ret.TexcoordAttribute, N));
+      VertexData.resize(byteEndOffset(Sub.TexcoordAttribute, N));
       char* P = VertexData.data();
 #if 0
       std::memcpy(P + byteBeginOffset(Ret.PositionAttribute), Points,    byteSize(Ret.PositionAttribute, N));
       std::memcpy(P + byteBeginOffset(Ret.NormalAttribute),   Normals,   byteSize(Ret.NormalAttribute, N));
       std::memcpy(P + byteBeginOffset(Ret.TexcoordAttribute), Texcoords, byteSize(Ret.TexcoordAttribute, N));
 #else
-      std::memcpy(P + byteBeginOffset(Ret.PositionAttribute), SourceMesh->mVertices,         byteSize(Ret.PositionAttribute, N));
-      std::memcpy(P + byteBeginOffset(Ret.NormalAttribute),   SourceMesh->mNormals,          byteSize(Ret.NormalAttribute,   N));
-      std::memcpy(P + byteBeginOffset(Ret.TexcoordAttribute), SourceMesh->mTextureCoords[0], byteSize(Ret.TexcoordAttribute, N));
+      std::memcpy(P + byteBeginOffset(Sub.PositionAttribute), SourceMesh->mVertices, byteSize(Sub.PositionAttribute, N));
+      std::memcpy(P + byteBeginOffset(Sub.NormalAttribute), SourceMesh->mNormals, byteSize(Sub.NormalAttribute, N));
+      {
+        aiVector3D const* SrcP = SourceMesh->mTextureCoords[0];
+        char* DstP = P + byteBeginOffset(Sub.TexcoordAttribute);
+        for (size_t i = 0; i < N; ++i) {
+          std::memcpy(DstP, SrcP, sizeof(aiVector2D));
+          ++SrcP;
+          DstP += sizeof(aiVector2D);
+        }
+      }
 #endif
     }
 
+    // ===[Create OpenGL buffers]===
     glGenBuffers(1, into(VB));
     glBindBuffer(GL_ARRAY_BUFFER, from(VB));
     glBufferData(GL_ARRAY_BUFFER, VertexData.size(), VertexData.data(), GL_STATIC_DRAW);
     glBindBuffer(GL_ARRAY_BUFFER, 0);
-    Ret.VBId = VB;
+    Sub.VBId = VB;
 
     auto IB = std::make_shared<GLBuffer<OwnedId>>();
     std::vector<uint32_t> Indices;
       auto& Face = SourceMesh->mFaces[FaceIndex];
       Indices.insert(Indices.end(), Face.mIndices, Face.mIndices + Face.mNumIndices);
     }
-    Ret.NumIndices = Indices.size();
+    Sub.NumIndices = Indices.size();
 
     glGenBuffers(1, into(IB));
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, from(IB));
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, Indices.size() * sizeof(uint32_t), Indices.data(), GL_STATIC_DRAW);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-    Ret.IBId = IB;
-    return Ret;
+    Sub.IBId = IB;
+    Ret.SubMeshes.push_back(Sub);
   }
   return Ret;
 }
 
   bool WasBlending = glIsEnabled(GL_BLEND) == GL_TRUE;
   glDisable(GL_BLEND);
-  glBindBuffer(GL_ARRAY_BUFFER, from(CurrentMesh->VBId));
-  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-  glEnableClientState(GL_NORMAL_ARRAY);
-  glEnableClientState(GL_VERTEX_ARRAY);
-  glTexCoordPointer(2, GL_FLOAT, CurrentMesh->TexcoordAttribute.Stride,
-    (void*)(uintptr_t)CurrentMesh->TexcoordAttribute.ByteOffset);
-  glNormalPointer(GL_FLOAT, CurrentMesh->NormalAttribute.Stride,
-    (void*)(uintptr_t)CurrentMesh->NormalAttribute.ByteOffset);
-  glVertexPointer(3, GL_FLOAT, CurrentMesh->PositionAttribute.Stride,
-    (void*)(uintptr_t)CurrentMesh->PositionAttribute.ByteOffset);
-
-  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, from(CurrentMesh->IBId));
-  glDrawElements(GL_TRIANGLES, CurrentMesh->NumIndices, GL_UNSIGNED_INT, nullptr);
-  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-  glVertexPointer(4, GL_FLOAT, 0, nullptr);
-  glNormalPointer(GL_FLOAT, 0, nullptr);
-  glTexCoordPointer(4, GL_FLOAT, 0, nullptr);
-  glDisableClientState(GL_VERTEX_ARRAY);
-  glDisableClientState(GL_NORMAL_ARRAY);
-  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-  glBindBuffer(GL_ARRAY_BUFFER, 0);
-  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-  glBindVertexArray(0);
-  glDeleteVertexArrays(1, &VAOId);
+
+  for (auto& Sub : CurrentMesh->SubMeshes) {
+    auto& Material = CurrentMesh->Materials.at(Sub.MaterialIndex);
+
+    sf::Texture::bind(Material.TextureImage.get());
+    glBindBuffer(GL_ARRAY_BUFFER, from(Sub.VBId));
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glEnableClientState(GL_NORMAL_ARRAY);
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glTexCoordPointer(2, GL_FLOAT, Sub.TexcoordAttribute.Stride,
+      (void*)(uintptr_t)Sub.TexcoordAttribute.ByteOffset);
+    glNormalPointer(GL_FLOAT, Sub.NormalAttribute.Stride,
+      (void*)(uintptr_t)Sub.NormalAttribute.ByteOffset);
+    glVertexPointer(3, GL_FLOAT, Sub.PositionAttribute.Stride,
+      (void*)(uintptr_t)Sub.PositionAttribute.ByteOffset);
+
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, from(Sub.IBId));
+    glDrawElements(GL_TRIANGLES, Sub.NumIndices, GL_UNSIGNED_INT, nullptr);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    glVertexPointer(4, GL_FLOAT, 0, nullptr);
+    glNormalPointer(GL_FLOAT, 0, nullptr);
+    glTexCoordPointer(4, GL_FLOAT, 0, nullptr);
+    glDisableClientState(GL_VERTEX_ARRAY);
+    glDisableClientState(GL_NORMAL_ARRAY);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    sf::Texture::bind(nullptr);
+  }
 
   (WasBlending ? glEnable : glDisable)(GL_BLEND);
+  glBindVertexArray(0);
+  glDeleteVertexArrays(1, &VAOId);
 }
 
 // vim: set ts=2 sw=2 et:
 #pragma once
 
 #include "OpenGL.h"
+#include <SFML/Graphics.hpp>
 
 #include <memory>
+#include <vector>
 
 struct MeshAttribute {
   uint32_t ByteOffset;
 
 struct Mesh {
   ~Mesh() {}
-  std::shared_ptr<GLBuffer<OwnedId>> VBId;
-  std::shared_ptr<GLBuffer<OwnedId>> IBId;
 
-  uint32_t NumVertices;
-  uint32_t NumIndices;
+  struct Material {
+    std::shared_ptr<sf::Texture> TextureImage;
+  };
+  std::vector<Material> Materials;
 
-  MeshAttribute PositionAttribute;
-  MeshAttribute NormalAttribute;
-  MeshAttribute TexcoordAttribute;
+  struct SubMesh {
+    std::shared_ptr<GLBuffer<OwnedId>> VBId;
+    std::shared_ptr<GLBuffer<OwnedId>> IBId;
+    uint8_t MaterialIndex;
+    uint32_t NumIndices;
+    uint32_t NumVertices;
+    MeshAttribute PositionAttribute;
+    MeshAttribute NormalAttribute;
+    MeshAttribute TexcoordAttribute;
+  };
+  std::vector<SubMesh> SubMeshes;
 };
 
 Mesh
-loadMesh(char const* filename);
+loadMesh(char const* BasePath, char const* Filename);
 
 struct MeshInstance {
   void