/// <summary> /// Checks if VBOs are created, if they are, bind them, if not create new /// </summary> /// <param name="face">Which face's mesh is uploaded in this VBO</param> /// <returns>True, if face data was succesfully uploaded to the graphics card memory</returns> public bool CheckVBO(Face face) { if (VertexVBO == -1) { Vertex[] vArray = face.Vertices.ToArray(); Compat.GenBuffers(out VertexVBO); Compat.BindBuffer(BufferTarget.ArrayBuffer, VertexVBO); Compat.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vArray.Length * VertexSize), vArray, BufferUsageHint.StaticDraw); if (Compat.BufferSize(BufferTarget.ArrayBuffer) != vArray.Length * VertexSize) { VBOFailed = true; Compat.BindBuffer(BufferTarget.ArrayBuffer, 0); Compat.DeleteBuffer(VertexVBO); VertexVBO = -1; return false; } } if (IndexVBO == -1) { ushort[] iArray = face.Indices.ToArray(); Compat.GenBuffers(out IndexVBO); Compat.BindBuffer(BufferTarget.ElementArrayBuffer, IndexVBO); Compat.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(iArray.Length * sizeof(ushort)), iArray, BufferUsageHint.StaticDraw); if (Compat.BufferSize(BufferTarget.ElementArrayBuffer) != iArray.Length * sizeof(ushort)) { VBOFailed = true; Compat.BindBuffer(BufferTarget.ElementArrayBuffer, 0); Compat.DeleteBuffer(IndexVBO); IndexVBO = -1; return false; } } return true; }
public override void Render(RenderPass pass, int pickingID, SceneWindow scene, float time) { terrainTimeSinceUpdate += time; if (Modified && terrainTimeSinceUpdate > RenderSettings.MinimumTimeBetweenTerrainUpdated) { if (!terrainInProgress) { terrainInProgress = true; ResetTerrain(false); UpdateTerrain(); } } if (terrainTextureNeedsUpdate) { UpdateTerrainTexture(); } if (terrainIndices == null || terrainVertices == null) { return; } GL.Color3(1f, 1f, 1f); GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.TextureCoordArray); GL.EnableClientState(ArrayCap.NormalArray); if (pass == RenderPass.Picking) { GL.EnableClientState(ArrayCap.ColorArray); GL.ShadeModel(ShadingModel.Flat); } if (terrainImage != null) { if (terrainTexture != -1) { GL.DeleteTexture(terrainTexture); } terrainTexture = RHelp.GLLoadImage(terrainImage, false); terrainImage.Dispose(); terrainImage = null; } if (pass != RenderPass.Picking && terrainTexture != -1) { GL.Enable(EnableCap.Texture2D); GL.BindTexture(TextureTarget.Texture2D, terrainTexture); } if (!RenderSettings.UseVBO || terrainVBOFailed) { unsafe { fixed(float *normalPtr = &terrainVertices[0].Vertex.Normal.X) fixed(float *texPtr = &terrainVertices[0].Vertex.TexCoord.X) fixed(byte *colorPtr = &terrainVertices[0].Color.R) { GL.NormalPointer(NormalPointerType.Float, ColorVertex.Size, (IntPtr)normalPtr); GL.TexCoordPointer(2, TexCoordPointerType.Float, ColorVertex.Size, (IntPtr)texPtr); GL.VertexPointer(3, VertexPointerType.Float, ColorVertex.Size, terrainVertices); if (pass == RenderPass.Picking) { GL.ColorPointer(4, ColorPointerType.UnsignedByte, ColorVertex.Size, (IntPtr)colorPtr); } GL.DrawElements(BeginMode.Triangles, terrainIndices.Length, DrawElementsType.UnsignedInt, terrainIndices); } } } else { if (terrainVBO == -1) { Compat.GenBuffers(out terrainVBO); Compat.BindBuffer(BufferTarget.ArrayBuffer, terrainVBO); Compat.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(terrainVertices.Length * ColorVertex.Size), terrainVertices, BufferUsageHint.StaticDraw); if (Compat.BufferSize(BufferTarget.ArrayBuffer) != terrainVertices.Length * ColorVertex.Size) { terrainVBOFailed = true; Compat.BindBuffer(BufferTarget.ArrayBuffer, 0); terrainVBO = -1; } } else { Compat.BindBuffer(BufferTarget.ArrayBuffer, terrainVBO); } if (terrainIndexVBO == -1) { Compat.GenBuffers(out terrainIndexVBO); Compat.BindBuffer(BufferTarget.ElementArrayBuffer, terrainIndexVBO); Compat.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(terrainIndices.Length * sizeof(uint)), terrainIndices, BufferUsageHint.StaticDraw); if (Compat.BufferSize(BufferTarget.ElementArrayBuffer) != terrainIndices.Length * sizeof(uint)) { terrainVBOFailed = true; Compat.BindBuffer(BufferTarget.ElementArrayBuffer, 0); terrainIndexVBO = -1; } } else { Compat.BindBuffer(BufferTarget.ElementArrayBuffer, terrainIndexVBO); } if (!terrainVBOFailed) { GL.NormalPointer(NormalPointerType.Float, ColorVertex.Size, (IntPtr)12); GL.TexCoordPointer(2, TexCoordPointerType.Float, ColorVertex.Size, (IntPtr)(24)); if (pass == RenderPass.Picking) { GL.ColorPointer(4, ColorPointerType.UnsignedByte, ColorVertex.Size, (IntPtr)32); } GL.VertexPointer(3, VertexPointerType.Float, ColorVertex.Size, (IntPtr)(0)); GL.DrawElements(BeginMode.Triangles, terrainIndices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero); } Compat.BindBuffer(BufferTarget.ArrayBuffer, 0); Compat.BindBuffer(BufferTarget.ElementArrayBuffer, 0); } if (pass == RenderPass.Picking) { GL.DisableClientState(ArrayCap.ColorArray); GL.ShadeModel(ShadingModel.Smooth); } else { GL.BindTexture(TextureTarget.Texture2D, 0); } GL.DisableClientState(ArrayCap.VertexArray); GL.DisableClientState(ArrayCap.TextureCoordArray); GL.DisableClientState(ArrayCap.NormalArray); }