/// <summary> /// Imports the mesh's vertex data. /// </summary> private void GetMeshVerts(Vector3[] verts, int arrayPos, Mesh meshData, VertexLayout vertexLayout) { VertexLayout.EntryInfo info; bool vertsExist = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Position, 0, out info); Assert.IsTrue(vertsExist); ReadVertexStream(verts, arrayPos, meshData, info); }
private void GetMeshNormals(Vector3[] normals, int arrayPos, Mesh meshData, VertexLayout vertexLayout) { VertexLayout.EntryInfo info; bool normalExists = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Normal, 0, out info); if (normalExists) { ReadVertexStream(normals, arrayPos, meshData, info); } }
/// <summary> /// Imports the mesh's texture coordinates. /// </summary> private void GetMeshUVs(Vector2[] uvs, int offset, Mesh meshData, VertexLayout vertexLayout) { VertexLayout.EntryInfo info; bool uvsExist = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Texcoord, 0, out info); if (uvsExist) { ReadVertexStream(uvs, offset, meshData, info); } }
public bool GetNormals(out Vector3[] normals, int usageIndex) { normals = null; VertexLayout vertexLayout = GetVertexLayout(0); if (vertexLayout == null) { return(false); } VertexLayout.Entry.DataTypes dataType; int streamOffset; int streamIndex; //todo: if normal does not exist, we can determine it from the tangent and binormal, if it exists bool normalExists = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Normal, usageIndex, out dataType, out streamIndex, out streamOffset); if (!normalExists) { return(false); } normals = new Vector3[VertexCount]; Mesh.VertexStream vertexStream = VertexStreams[streamIndex]; switch (dataType) { case VertexLayout.Entry.DataTypes.Float3: { vertexStream.ReadFloat3s(normals, streamOffset, 0, (int)VertexCount); } break; case VertexLayout.Entry.DataTypes.ubyte4n: { vertexStream.ReadUByte4Ns(normals, streamOffset, 0, (int)VertexCount); } break; default: break; } return(true); }
public bool GetTexCoords(out Vector2[] texCoords, int usageIndex) { texCoords = null; VertexLayout vertexLayout = GetVertexLayout(0); if (vertexLayout == null) { return(false); } VertexLayout.Entry.DataTypes dataType; int streamOffset; int streamIndex; bool texcoordExists = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Texcoord, usageIndex, out dataType, out streamIndex, out streamOffset); if (!texcoordExists) { return(false); } texCoords = new Vector2[VertexCount]; Mesh.VertexStream vertexStream = VertexStreams[streamIndex]; switch (dataType) { case VertexLayout.Entry.DataTypes.Float2: { vertexStream.ReadFloat2s(texCoords, streamOffset, 0, (int)VertexCount); } break; case VertexLayout.Entry.DataTypes.float16_2: { vertexStream.ReadHalf2s(texCoords, streamOffset, 0, (int)VertexCount); } break; default: break; } return(true); }
public bool GetPositions(out List <Vector3> positions, int usageIndex) { positions = null; VertexLayout vertexLayout = GetVertexLayout(0); if (vertexLayout == null) { return(false); } VertexLayout.Entry.DataTypes dataType; int streamOffset; int streamIndex; bool positionExists = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Position, usageIndex, out dataType, out streamIndex, out streamOffset); if (!positionExists) { return(false); } positions = new List <Vector3>((int)VertexCount); Mesh.VertexStream vertexStream = VertexStreams[streamIndex]; switch (dataType) { case VertexLayout.Entry.DataTypes.Float3: { vertexStream.ReadFloat3s(positions, streamOffset, 0, (int)VertexCount); } break; default: break; } return(true); }
public override void Render() { if (DesignMode) { return; } MakeCurrent(); GL.Viewport(0, 0, ClientSize.Width, ClientSize.Height); //clear GL.ClearColor(Color.Black); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); if (Camera == null) { return; } //projection matrix Matrix4 projection = Camera.Projection; GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref projection); //view matrix Matrix4 view = Camera.View; GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref view); if (DrawAxes) { // debug axes GL.Begin(BeginMode.Lines); //x GL.Color3(Color.Red); GL.Vertex3(Vector3.Zero); GL.Vertex3(Vector3.UnitX); GL.Vertex3(Vector3.UnitX); GL.Vertex3(Vector3.UnitX + new Vector3(-0.125f, 0.125f, 0.0f)); GL.Vertex3(Vector3.UnitX); GL.Vertex3(Vector3.UnitX + new Vector3(-0.125f, -0.125f, 0.0f)); //y GL.Color3(Color.Green); GL.Vertex3(Vector3.Zero); GL.Vertex3(Vector3.UnitY); GL.Vertex3(Vector3.UnitY); GL.Vertex3(Vector3.UnitY + new Vector3(0.125f, -0.125f, 0.0f)); GL.Vertex3(Vector3.UnitY); GL.Vertex3(Vector3.UnitY + new Vector3(-0.125f, -0.125f, 0.0f)); //z GL.Color3(Color.Blue); GL.Vertex3(Vector3.Zero); GL.Vertex3(Vector3.UnitZ); GL.Vertex3(Vector3.UnitZ); GL.Vertex3(Vector3.UnitZ + new Vector3(0, -0.125f, -0.125f)); GL.Vertex3(Vector3.UnitZ); GL.Vertex3(Vector3.UnitZ + new Vector3(0, 0.125f, -0.125f)); GL.End(); } if (Model != null) { GL.PushMatrix(); GL.PushAttrib(AttribMask.PolygonBit | AttribMask.EnableBit | AttribMask.LightingBit | AttribMask.CurrentBit); GL.UseProgram(shaderProgram); GL.Enable(EnableCap.DepthTest); GL.Disable(EnableCap.CullFace); GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.FrontFace(FrontFaceDirection.Cw); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, 0); int loc = GL.GetUniformLocation(shaderProgram, "colorMap"); GL.Uniform1(loc, 0); for (int i = 0; i < Model.Meshes.Length; ++i) { Mesh mesh = Model.Meshes[i]; //pin handles to stream data GCHandle[] streamDataGCHandles = new GCHandle[mesh.VertexStreams.Length]; for (int j = 0; j < streamDataGCHandles.Length; ++j) { streamDataGCHandles[j] = GCHandle.Alloc(mesh.VertexStreams[j].Data, GCHandleType.Pinned); } //fetch material definition and vertex layout VertexLayout vertexLayout = mesh.GetVertexLayout(0); GL.Color3(meshColors[i % meshColors.Length]); switch (RenderMode) { case RenderModes.Wireframe: { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); } break; case RenderModes.Smooth: { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } break; } //position VertexLayout.Entry.DataTypes positionDataType = VertexLayout.Entry.DataTypes.None; int positionStream = 0; int positionOffset = 0; bool positionExists = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Position, 0, out positionDataType, out positionStream, out positionOffset); if (positionExists) { IntPtr positionData = streamDataGCHandles[positionStream].AddrOfPinnedObject(); GL.EnableClientState(ArrayCap.VertexArray); GL.VertexPointer(3, VertexPointerType.Float, mesh.VertexStreams[positionStream].BytesPerVertex, positionData + positionOffset); } //normal VertexLayout.Entry.DataTypes normalDataType = VertexLayout.Entry.DataTypes.None; int normalStream = 0; int normalOffset = 0; bool normalExists = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Normal, 0, out normalDataType, out normalStream, out normalOffset); if (normalExists) { IntPtr normalData = streamDataGCHandles[normalStream].AddrOfPinnedObject(); GL.EnableClientState(ArrayCap.NormalArray); GL.NormalPointer(NormalPointerType.Float, mesh.VertexStreams[normalStream].BytesPerVertex, normalData + normalOffset); } //texture coordiantes VertexLayout.Entry.DataTypes texCoord0DataType = VertexLayout.Entry.DataTypes.None; int texCoord0Stream = 0; int texCoord0Offset = 0; bool texCoord0Exists = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Texcoord, 0, out texCoord0DataType, out texCoord0Stream, out texCoord0Offset); if (texCoord0Exists) { IntPtr texCoord0Data = streamDataGCHandles[texCoord0Stream].AddrOfPinnedObject(); GL.EnableClientState(ArrayCap.TextureCoordArray); TexCoordPointerType texCoord0PointerType = TexCoordPointerType.Float; switch (texCoord0DataType) { case VertexLayout.Entry.DataTypes.Float2: texCoord0PointerType = TexCoordPointerType.Float; break; case VertexLayout.Entry.DataTypes.float16_2: texCoord0PointerType = TexCoordPointerType.HalfFloat; break; default: break; } GL.TexCoordPointer(2, texCoord0PointerType, mesh.VertexStreams[texCoord0Stream].BytesPerVertex, texCoord0Data + texCoord0Offset); } //indices GCHandle indexDataHandle = GCHandle.Alloc(mesh.IndexData, GCHandleType.Pinned); IntPtr indexData = indexDataHandle.AddrOfPinnedObject(); GL.DrawElements(BeginMode.Triangles, (int)mesh.IndexCount, DrawElementsType.UnsignedShort, indexData); indexDataHandle.Free(); GL.DisableClientState(ArrayCap.VertexArray); GL.DisableClientState(ArrayCap.NormalArray); GL.DisableClientState(ArrayCap.TextureCoordArray); //free stream data handles for (int j = 0; j < streamDataGCHandles.Length; ++j) { streamDataGCHandles[j].Free(); } } GL.UseProgram(0); GL.PopAttrib(); } SwapBuffers(); }