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));
}
}
}
}
}