using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using OpenGL4NET; namespace ZPG_2011_Moulis_Jan_A09B0359P { class Planet { private int divisions = 32; private float radius; private uint vboData; private uint iboData; private int triCount; private PositionNormalTexCoor[] vertex; private uint[] index; private float posX; private float posY; public Planet(float radius) { this.radius = radius; vertex = new PositionNormalTexCoor[divisions + 1]; createCyrcle(); prepareVBOIBO(); } private void createCyrcle() { double angleStepRad = 360 / divisions * Math.PI / 180; for (int i = 0; i < divisions / 4; i++) { posX = (float)(radius * Math.Cos(i*angleStepRad)); posY = (float)(radius * Math.Sin(i*angleStepRad)); vertex[i] = new PositionNormalTexCoor(posX, posY, 0.0f, 0, 0, 0, (radius + posX) / (2 * radius), (radius + posY) / (2 * radius)); vertex[i + divisions / 4] = new PositionNormalTexCoor(-posY, posX, 0.0f, 0, 0, 0, (radius - posY) / (2 * radius), (radius + posX) / (2 * radius)); vertex[i + divisions / 2] = new PositionNormalTexCoor(-posX, -posY, 0.0f, 0, 0, 0, (radius - posX) / (2 * radius), (radius - posY) / (2 * radius)); vertex[i + 3 * divisions / 4] = new PositionNormalTexCoor(posY, -posX, 0.0f, 0, 0, 0, (radius + posY) / (2 * radius), (radius - posX) / (2 * radius)); } vertex[vertex.Length - 1] = new PositionNormalTexCoor(0, 0, 0, 0, 0, 0, 0.5f, 0.5f); triCount = 3 * divisions; index = new uint[triCount]; int p = 0; for (uint i = 0; i < vertex.Length - 1; i++ ) { index[p++] = i; if (i != vertex.Length - 2) { index[p++] = i + 1; } else { index[p++] = 0; } index[p++] = (uint) (vertex.Length - 1); } } private void prepareVBOIBO() { // Priprava vbo vboData = gl.GenBuffer(); gl.BindBuffer(GL.ARRAY_BUFFER, vboData); gl.BufferData(GL.ARRAY_BUFFER, vertex.Length * PositionNormalTexCoor.SizeInBytes, vertex, GL.STATIC_DRAW); gl.BindBuffer(GL.ARRAY_BUFFER, 0); // Priprava ibo iboData = gl.GenBuffer(); gl.BindBuffer(GL.ELEMENT_ARRAY_BUFFER, iboData); gl.BufferData(GL.ELEMENT_ARRAY_BUFFER, index.Length * sizeof(uint), index, GL.STATIC_DRAW); gl.BindBuffer(GL.ELEMENT_ARRAY_BUFFER, 0); gl.BindBuffer(GL.ARRAY_BUFFER, 0); } public void render(uint texture) { gl.ActiveTexture(GL.TEXTURE0); gl.Enable(GL.TEXTURE_2D); gl.BindTexture(GL.TEXTURE_2D, texture); gl.TexEnvf(GL.TEXTURE_ENV, GL.TEXTURE_ENV_MODE, GL.MODULATE); gl.BindBuffer(GL.ARRAY_BUFFER, vboData); // NAČTENÍ BUFFERU gl.BindBuffer(GL.ELEMENT_ARRAY_BUFFER, iboData); gl.ClientActiveTexture(GL.TEXTURE0); gl.EnableClientState(GL.TEXTURE_COORD_ARRAY); // TEXTURA gl.TexCoordPointer(2, GL.FLOAT, PositionNormalTexCoor.SizeInBytes, (IntPtr)24); gl.EnableClientState(GL.NORMAL_ARRAY); // NORMÁLY gl.NormalPointer(GL.FLOAT, PositionNormalTexCoor.SizeInBytes, (IntPtr)12); gl.EnableClientState(GL.VERTEX_ARRAY); // POZICE BODU gl.VertexPointer(3, GL.FLOAT, PositionNormalTexCoor.SizeInBytes, (IntPtr)0); gl.DrawElements(GL.TRIANGLES, triCount, GL.UNSIGNED_INT, (IntPtr)0); // VYKRESLENÍ gl.DisableClientState(GL.VERTEX_ARRAY); gl.DisableClientState(GL.NORMAL_ARRAY); gl.DisableClientState(GL.TEXTURE_COORD_ARRAY); gl.BindBuffer(GL.ARRAY_BUFFER, 0); gl.BindBuffer(GL.ELEMENT_ARRAY_BUFFER, 0); gl.BindTexture(GL.TEXTURE_2D, 0); gl.ActiveTexture(GL.TEXTURE0); gl.Disable(GL.TEXTURE_2D); gl.BindTexture(GL.TEXTURE_2D, 0); } public void destroy() { gl.DeleteBuffer(vboData); gl.DeleteBuffer(iboData); } [StructLayout(LayoutKind.Sequential)] struct PositionNormalTexCoor { public Vector3 position; public Vector3 normal; public float texCoorX; public float texCoorY; /// /// Konstruktor z floatu /// /// X /// Y /// Z /// nX /// nY /// nZ /// texCoorX /// texCoorY public PositionNormalTexCoor(float x, float y, float z, float nx, float ny, float nz, float texCoorX, float texCoorY) { position = new Vector3(x, y, z); normal = new Vector3(nx, ny, nz); this.texCoorX = texCoorX; this.texCoorY = texCoorY; } /// /// Velikost struktury v bytech /// public static int SizeInBytes { get { return Marshal.SizeOf(typeof(PositionNormalTexCoor)); } } } } }