summaryrefslogtreecommitdiff
path: root/src/object.c
blob: 25d504fb35f232ef3e73005f878d31d05ad393e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "object.h"

void createViewModel(ViewModel *model, int num_vertices, float *vert, int num_indices, unsigned int *indices)
{
	model->num_indices = num_indices;
	
	glGenVertexArrays(1, &model->VAO);
	glBindVertexArray(model->VAO);

	glGenBuffers(1, &model->VBO);
	glBindBuffer(GL_ARRAY_BUFFER, model->VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_vertices*3, vert, GL_STATIC_DRAW);

	glGenBuffers(1, &model->EBO);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*num_indices, indices, GL_STATIC_DRAW);

	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
}

void killViewModel(ViewModel *model)
{
	glDeleteVertexArrays(1, &model->VAO);
	glDeleteBuffers(1, &model->VBO);
	glDeleteBuffers(1, &model->EBO);
}

void bindViewModel(ViewModel *model)
{
	glBindVertexArray(model->VAO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->EBO);
}

ViewModel loadViewModel(const char* filename)
{
	const struct aiScene* scene = aiImportFile(filename,
			aiProcess_CalcTangentSpace |
			aiProcess_Triangulate |
			aiProcess_JoinIdenticalVertices |
			aiProcess_SortByPType);

	struct aiMesh *mesh = scene->mMeshes[0];

	unsigned int *indices = malloc(mesh->mNumFaces*3*sizeof(unsigned int));
	int index = 0;
	for (unsigned int i=0;i<mesh->mNumFaces;i++) {
		memcpy(&indices[index], mesh->mFaces[i].mIndices, 3*sizeof(unsigned int));
		index+=3;
	}

	ViewModel model;
	createViewModel(&model, mesh->mNumVertices, (float*)mesh->mVertices, mesh->mNumFaces*3, indices);
	free(indices);
	return model;
}

void createObject(Object *obj, ViewModel *model)
{
	obj->model = model;
	glm_mat4_identity(obj->transform);

	glm_vec3_zero(obj->pos);
	glm_vec3_one(obj->size);

	obj->rotation.angle = 0.0f;
	glm_vec3_zero(obj->rotation.direction);
}

void moveObject(Object *obj, vec3 pos)
{
	glm_vec3_copy(
			pos,
			obj->pos
			);
	updateObjectTransform(obj);
}

void scaleObject(Object *obj, vec3 scale)
{
	glm_scale(obj->transform, scale);
	updateObjectTransform(obj);
}

void rotateObject(Object *obj, float angle, vec3 direction)
{
	obj->rotation.angle = angle;
	glm_vec3_copy(
			direction,
			obj->rotation.direction
			);
	updateObjectTransform(obj);
}

inline void updateObjectTransform(Object *obj)
{
	glm_mat4_identity(obj->transform);
	glm_translate(obj->transform, obj->pos);
	glm_rotate(obj->transform, obj->rotation.angle, obj->rotation.direction);
	glm_scale(obj->transform, obj->size);
}

void drawObject(Game *game, Object *obj)
{
	glUniformMatrix4fv(game->transform_loc, 1, GL_FALSE, (float*)obj->transform);

	glDrawElements(GL_TRIANGLES, obj->model->num_indices, GL_UNSIGNED_INT, 0);
}