private SSMeshOBJSubsetData _loadMaterialSubset(SSAssetManager.Context ctx, WavefrontObjLoader wff, WavefrontObjLoader.MaterialInfoWithFaces objMatSubset) { // generate renderable geometry data... SSVertex_PosNormTexDiff[] vertices; UInt16[] triIndices, wireframeIndices; VertexSoup_VertexFormatBinder.generateDrawIndexBuffer( wff, out triIndices, out vertices); wireframeIndices = OpenTKHelper.generateLineIndicies(triIndices); SSMeshOBJSubsetData subsetData = new SSMeshOBJSubsetData( vertices, triIndices, wireframeIndices); // setup the material... // load and link every texture present subsetData.TextureMaterial = new SSTextureMaterial(); if (objMatSubset.mtl.diffuseTextureResourceName != null) { subsetData.TextureMaterial.diffuseTex = SSAssetManager.GetInstance <SSTexture>(ctx, objMatSubset.mtl.diffuseTextureResourceName); } if (objMatSubset.mtl.ambientTextureResourceName != null) { subsetData.TextureMaterial.ambientTex = SSAssetManager.GetInstance <SSTexture>(ctx, objMatSubset.mtl.ambientTextureResourceName); } if (objMatSubset.mtl.bumpTextureResourceName != null) { subsetData.TextureMaterial.bumpMapTex = SSAssetManager.GetInstance <SSTexture>(ctx, objMatSubset.mtl.bumpTextureResourceName); } if (objMatSubset.mtl.specularTextureResourceName != null) { subsetData.TextureMaterial.specularTex = SSAssetManager.GetInstance <SSTexture>(ctx, objMatSubset.mtl.specularTextureResourceName); } return(subsetData); }
private SSMeshOBJSubsetData _loadMaterialSubset(string baseDirectory, WavefrontObjLoader wff, WavefrontObjLoader.MaterialInfoWithFaces objMatSubset) { // generate renderable geometry data... SSVertex_PosNormTex[] vertices; UInt16[] triIndices, wireframeIndices; VertexSoup_VertexFormatBinder.generateDrawIndexBuffer( wff, objMatSubset, out triIndices, out vertices); wireframeIndices = OpenTKHelper.generateLineIndicies(triIndices); SSMeshOBJSubsetData subsetData = new SSMeshOBJSubsetData( vertices, triIndices, wireframeIndices); // setup the material... // load and link every texture present subsetData.textureMaterial = SSTextureMaterial.FromBlenderMtl(baseDirectory, objMatSubset.mtl); subsetData.colorMaterial = SSColorMaterial.fromMtl(objMatSubset.mtl); return(subsetData); }
private SSMeshOBJSubsetData _loadMaterialSubset(SSAssetManager.Context ctx, WavefrontObjLoader wff, WavefrontObjLoader.MaterialInfoWithFaces objMatSubset) { // create new mesh subset-data SSMeshOBJSubsetData subsetData = new SSMeshOBJSubsetData(); // setup the material... // load and link every texture present subsetData.TextureMaterial = new SSTextureMaterial(); if (objMatSubset.mtl.diffuseTextureResourceName != null) { subsetData.TextureMaterial.diffuseTex = SSAssetManager.GetInstance <SSTexture>(ctx, objMatSubset.mtl.diffuseTextureResourceName); } if (objMatSubset.mtl.ambientTextureResourceName != null) { subsetData.TextureMaterial.ambientTex = SSAssetManager.GetInstance <SSTexture>(ctx, objMatSubset.mtl.ambientTextureResourceName); } if (objMatSubset.mtl.bumpTextureResourceName != null) { subsetData.TextureMaterial.bumpMapTex = SSAssetManager.GetInstance <SSTexture>(ctx, objMatSubset.mtl.bumpTextureResourceName); } if (objMatSubset.mtl.specularTextureResourceName != null) { subsetData.TextureMaterial.specularTex = SSAssetManager.GetInstance <SSTexture>(ctx, objMatSubset.mtl.specularTextureResourceName); } // generate renderable geometry data... VertexSoup_VertexFormatBinder.generateDrawIndexBuffer(wff, out subsetData.indicies, out subsetData.vertices); // TODO: setup VBO/IBO buffers // http://www.opentk.com/doc/graphics/geometry/vertex-buffer-objects subsetData.wireframe_indicies = OpenTKHelper.generateLineIndicies(subsetData.indicies); subsetData.vbo = new SSVertexBuffer <SSVertex_PosNormTexDiff>(subsetData.vertices); subsetData.ibo = new SSIndexBuffer(subsetData.indicies, subsetData.vbo); subsetData.ibo_wireframe = new SSIndexBuffer(subsetData.wireframe_indicies, subsetData.vbo); return(subsetData); }
// convert wavefrontobjloader vector formats, to our OpenTK Vector3 format // generateDrawIndexBuffer(..) // // Walks the wavefront faces, feeds pre-configured verticies to the VertexSoup, // and returns a new index-buffer pointing to the new VertexSoup.verticies indicies. public static void generateDrawIndexBuffer( WavefrontObjLoader wff, WavefrontObjLoader.MaterialInfoWithFaces objMatSubset, out UInt32[] indicies_return, out VertexPositionNormalTexture[] verticies_return) { const bool shouldDedup = true; // this lets us turn on/of vertex-soup deduping var soup = new VertexSoup <VertexPositionNormalTexture>(deDup: shouldDedup); List <UInt32> draw_indicies = new List <UInt32>(); // (0) go throu`gh the materials and faces, DENORMALIZE from WF-OBJ into fully-configured verticies // load indexes var m = objMatSubset; // wavefrontOBJ stores color in CIE-XYZ color space. Convert this to Alpha-RGB var materialDiffuseColor = WavefrontObjLoader.CIEXYZtoColor(m.mtl.vDiffuse).ToArgb(); foreach (var face in m.faces) { // iterate over the vericies of a wave-front FACE... // DEREFERENCE each .obj vertex paramater (position, normal, texture coordinate) VertexPositionNormalTexture[] vertex_list = new VertexPositionNormalTexture[face.v_idx.Length]; for (int facevertex = 0; facevertex < face.v_idx.Length; facevertex++) { // position vertex_list[facevertex].Position = wff.positions[face.v_idx[facevertex]].XYZ(); // normal int normal_idx = face.n_idx[facevertex]; if (normal_idx != -1) { vertex_list[facevertex].Normal = wff.normals[normal_idx]; } // texture coordinate int tex_index = face.tex_idx[facevertex]; if (tex_index != -1) { vertex_list[facevertex].TextureCoordinate.X = wff.texCoords[tex_index].X; vertex_list[facevertex].TextureCoordinate.Y = 1 - wff.texCoords[tex_index].Y; } } // turn them into indicies in the vertex soup.. // .. we hand the soup a set of fully configured verticies. It // .. dedups and accumulates them, and hands us back indicies // .. relative to it's growing list of deduped verticies. UInt32[] soup_indicies = soup.digestVerticies(vertex_list); // now we add these indicies to the draw-list. Right now we assume // draw is using GL_TRIANGLE, so we convert NGONS into triange lists if (soup_indicies.Length == 3) // triangle { draw_indicies.Add(soup_indicies[0]); draw_indicies.Add(soup_indicies[2]); draw_indicies.Add(soup_indicies[1]); } else if (soup_indicies.Length == 4) // quad { draw_indicies.Add(soup_indicies[0]); draw_indicies.Add(soup_indicies[2]); draw_indicies.Add(soup_indicies[1]); draw_indicies.Add(soup_indicies[0]); draw_indicies.Add(soup_indicies[3]); draw_indicies.Add(soup_indicies[2]); } else { // This n-gon algorithm only works if the n-gon is coplanar and convex, // which Wavefront OBJ says they must be. // .. to tesselate concave ngons, one must tesselate using a more complex method, see // http://en.wikipedia.org/wiki/Polygon_triangulation#Ear_clipping_method // manually generate a triangle-fan for (int x = 1; x < (soup_indicies.Length - 1); x++) { draw_indicies.Add(soup_indicies[0]); draw_indicies.Add(soup_indicies[x + 1]); draw_indicies.Add(soup_indicies[x]); } // throw new NotImplementedException("unhandled face size: " + newindicies.Length); } } // convert the linked-lists into arrays and return indicies_return = draw_indicies.ToArray(); verticies_return = soup.verticies.ToArray(); Console.WriteLine("VertexSoup_VertexFormatBinder:generateDrawIndexBuffer : \r\n {0} verticies, {1} indicies. Dedup = {2}", verticies_return.Length, indicies_return.Length, shouldDedup ? "YES" : "NO"); }