#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "mesh.h"
#include "renderer.h"
#define NUM_ARRAY_ELEMENTS(a) sizeof(a) / sizeof(*a)
Mesh *mesh_new(vertex_t* vertices, GLsizeiptr vertexBuffersize,
GLushort* indices, GLsizeiptr indexBuffersize)
{
Mesh *mesh;
mesh = malloc( sizeof(Mesh) );
memset(mesh, 0, sizeof(Mesh) );
render.meshes[render.num_meshes] = mesh;
render.num_meshes += 1;
mesh->num_indices = ( indexBuffersize / sizeof(GLushort) );
glGenVertexArrays(1, &mesh->vao);
glGenBuffers(1, &mesh->vbo);
glGenBuffers(1, &mesh->ebo);
glBindVertexArray(mesh->vao);
glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo);
glBufferData(GL_ARRAY_BUFFER, vertexBuffersize, vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffersize, indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (const void*)offsetof(vertex_t, position) );
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (const void*)offsetof(vertex_t, texCoord) );
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (const void*)offsetof(vertex_t, normal) );
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (const void*)offsetof(vertex_t, tangent) );
glBindVertexArray(0);
return mesh;
}
Mesh *mesh_make_skybox(float size)
{
Mesh *mesh;
mesh = malloc( sizeof(Mesh) );
memset(mesh, 0, sizeof(Mesh) );
render.meshes[render.num_meshes] = mesh;
render.num_meshes += 1;
Vec3 positions[] =
{
{-size, size, -size}, {-size, -size, -size}, {+size, -size, -size},
{+size, -size, -size}, {+size, +size, -size}, {-size, +size, -size},
{-size, -size, +size}, {-size, -size, -size}, {-size, +size, -size},
{-size, +size, -size}, {-size, +size, +size}, {-size, -size, +size},
{+size, -size, -size}, {+size, -size, +size}, {+size, +size, +size},
{+size, +size, +size}, {+size, +size, -size}, {+size, -size, -size},
{-size, -size, +size}, {-size, +size, +size}, {+size, +size, +size},
{+size, +size, +size}, {+size, -size, +size}, {-size, -size, +size},
{-size, +size, -size}, {+size, +size, -size}, {+size, +size, +size},
{+size, +size, +size}, {-size, +size, +size}, {-size, +size, -size},
{-size, -size, -size}, {-size, -size, +size}, {+size, -size, -size},
{+size, -size, -size}, {-size, -size, +size}, {+size, -size, +size}
};
mesh->num_indices = 0;
mesh->num_vertices = NUM_ARRAY_ELEMENTS(positions);
glGenVertexArrays(1, &mesh->vao);
glGenBuffers(1, &mesh->vbo);
mesh->ebo = 0;
glBindVertexArray(mesh->vao);
glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0 );
glBindVertexArray(0);
return mesh;
}
Mesh *mesh_make_quad()
{
Mesh *mesh;
mesh = malloc( sizeof(Mesh) );
memset(mesh, 0, sizeof(Mesh) );
render.meshes[render.num_meshes] = mesh;
render.num_meshes += 1;
Vec3 positions[] =
{
{ -0.5f, +0.5f, +0.0f}, { -0.5f, -0.5f, +0.0f},
{ +0.5f, +0.5f, +0.0f}, { +0.5f, -0.5f, +0.0f}
};
mesh->num_vertices = NUM_ARRAY_ELEMENTS(positions);
mesh->num_indices = 0;
glGenVertexArrays(1, &mesh->vao);
glGenBuffers(1, &mesh->vbo);
mesh->ebo = 0;
glBindVertexArray(mesh->vao);
glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0 );
glBindVertexArray(0);
return mesh;
}
void mesh_purge(Mesh *mesh)
{
if(mesh)
{
if(mesh->vbo)
glDeleteBuffers(1, &mesh->vbo);
if(mesh->ebo)
glDeleteBuffers(1, &mesh->ebo);
if(mesh->vao)
glDeleteVertexArrays(1, &mesh->vao);
memset(mesh, 0, sizeof(Mesh));
}
}