Reshuffled
This commit is contained in:
@ -1,53 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Msters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "camera.h"
|
||||
|
||||
camera_t * cameraCreate() {
|
||||
camera_t *camera = malloc(sizeof(camera_t));
|
||||
if(!camera) return NULL;
|
||||
return camera;
|
||||
}
|
||||
|
||||
void cameraDispose(camera_t *camera) {
|
||||
free(camera);
|
||||
}
|
||||
|
||||
void cameraLookAt(camera_t *camera,
|
||||
float x, float y, float z, float targetX, float targetY, float targetZ
|
||||
) {
|
||||
glm_lookat(
|
||||
(vec3){ x, y, z },
|
||||
(vec3){ targetX, targetY, targetZ },
|
||||
(vec3){ 0, 1, 0 },
|
||||
camera->view
|
||||
);
|
||||
}
|
||||
|
||||
void cameraLook(camera_t *camera,
|
||||
float x, float y, float z,
|
||||
float pitch, float yaw, float roll
|
||||
) {
|
||||
glm_look(
|
||||
(vec3){ x, y, z },
|
||||
(vec3){ pitch, yaw, roll },
|
||||
(vec3){ 0, 1, 0 },
|
||||
camera->view
|
||||
);
|
||||
}
|
||||
|
||||
void cameraPerspective(camera_t *camera,
|
||||
float fov, float aspect, float near, float far
|
||||
) {
|
||||
glm_perspective(fov, aspect, near, far, camera->projection);
|
||||
}
|
||||
|
||||
void cameraOrtho(camera_t *camera,
|
||||
float left, float right, float bottom, float top, float near, float far
|
||||
) {
|
||||
glm_ortho(left, right, bottom, top, near, far, camera->projection);
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Msters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <cglm/cglm.h>
|
||||
#include <malloc.h>
|
||||
|
||||
/** The math for the camera is stored here. */
|
||||
typedef struct {
|
||||
/** View Matrix (Where the camera looks) */
|
||||
mat4 view;
|
||||
|
||||
/** Projection Matrix (How the camera looks) */
|
||||
mat4 projection;
|
||||
} camera_t;
|
||||
|
||||
/**
|
||||
* Create a new camera instance.
|
||||
*
|
||||
* @return A new camera instance.
|
||||
*/
|
||||
camera_t * cameraCreate();
|
||||
|
||||
/**
|
||||
* Cleanup a previously created camera
|
||||
*
|
||||
* @param camera Camera instance to dispose.
|
||||
*/
|
||||
void cameraDispose(camera_t *camera);
|
||||
|
||||
/**
|
||||
* Make a camera look at a position in world space while itself being positioned
|
||||
* within world space.
|
||||
*
|
||||
* @param camera The camera to position.
|
||||
* @param x The X position in world space of the camera.
|
||||
* @param y The Y position in world space of the camera.
|
||||
* @param z The Z position in world space of the camera.
|
||||
* @param targetX The Target X position in world space of the camera.
|
||||
* @param targetY The Target Y position in world space of the camera.
|
||||
* @param targetZ The Target Z position in world space of the camera.
|
||||
*/
|
||||
void cameraLookAt(camera_t *camera,
|
||||
float x, float y, float z, float targetX, float targetY, float targetZ
|
||||
);
|
||||
|
||||
/**
|
||||
* Make a camera look in a direction based on a rotation direction.
|
||||
*
|
||||
* @param camera The camera to position.
|
||||
* @param x The X position in world space of the camera.
|
||||
* @param y The Y position in world space of the camera.
|
||||
* @param z The Z position in world space of the camera.
|
||||
* @param pitch The pitch of the camera.
|
||||
* @param yaw The yaw of the camera.
|
||||
* @param roll The roll of the camera.
|
||||
*/
|
||||
void cameraLook(camera_t *camera,
|
||||
float x, float y, float z,
|
||||
float pitch, float yaw, float roll
|
||||
);
|
||||
|
||||
/**
|
||||
* Make a camera's projection be a 3D Perspective view.
|
||||
*
|
||||
* @param camera The camera to project.
|
||||
* @param fov The field of view of the camera.
|
||||
* @param aspect The aspect ratio of the camera (w / h)
|
||||
* @param near The near plane clip.
|
||||
* @param far the far plane clip.
|
||||
*/
|
||||
void cameraPerspective(camera_t *camera,
|
||||
float fov, float aspect, float near, float far
|
||||
);
|
||||
|
||||
/**
|
||||
* Defines an orthorgonal camera matrix.
|
||||
*
|
||||
* @param camera Camera to position.
|
||||
* @param left The left side of the viewport.
|
||||
* @param right The right side of the viewport.
|
||||
* @param bottom The bottom side of the viewport.
|
||||
* @param near The near plane clip.
|
||||
* @param far the far plane clip.
|
||||
*/
|
||||
void cameraOrtho(camera_t *camera,
|
||||
float left, float right, float bottom, float top, float near, float far
|
||||
);
|
@ -1,114 +0,0 @@
|
||||
#include "primitive.h"
|
||||
|
||||
primitive_t * primitiveCreate(int32_t verticeCount, int32_t indiceCount) {
|
||||
primitive_t *primitive = malloc(sizeof(primitive_t));
|
||||
|
||||
primitive->verticeCount = verticeCount;
|
||||
primitive->indiceCount = indiceCount;
|
||||
|
||||
// size_t sizeIndices = sizeof(uint32_t) * verticeCount;
|
||||
size_t sizePositions = sizeof(float) * verticeCount * PRIMITIVE_POSITIONS_PER_VERTICE;
|
||||
size_t sizeCoordinates = sizeof(float) * verticeCount * PRIMITIVE_COORDINATES_PER_VERTICE;
|
||||
size_t sizeIndices = sizeof(indice_t) * indiceCount;
|
||||
|
||||
// Create some buffers, one for the vertex data, one for the indices
|
||||
GLuint *buffer = malloc(sizeof(GLuint) * 2);
|
||||
glGenBuffers(2, buffer);
|
||||
|
||||
primitive->vertexBuffer = buffer[0];
|
||||
primitive->indexBuffer = buffer[1];
|
||||
free(buffer);
|
||||
|
||||
//Buffer an empty set of data then buffer each component
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, primitive->indexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeIndices, 0, GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, primitive->vertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizePositions+sizeCoordinates, 0, GL_DYNAMIC_DRAW);
|
||||
|
||||
size_t offset = 0;
|
||||
|
||||
// Setup the attrib pointers
|
||||
glVertexAttribPointer(0, PRIMITIVE_POSITIONS_PER_VERTICE, GL_FLOAT,
|
||||
GL_FALSE, 0, (void *)offset
|
||||
);
|
||||
offset += sizePositions;
|
||||
|
||||
glVertexAttribPointer(1, PRIMITIVE_COORDINATES_PER_VERTICE, GL_FLOAT,
|
||||
GL_FALSE, 0, (void *)offset
|
||||
);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
return primitive;
|
||||
}
|
||||
|
||||
void primitiveBufferVertices(primitive_t *primitive,
|
||||
int32_t position, int32_t count, vertice_t *vertices
|
||||
) {
|
||||
// Memory
|
||||
size_t lengthPositions, lengthCoordinates, offsetPositions, offsetCoordinates;
|
||||
float *positions, *coordinates;
|
||||
int32_t i;
|
||||
|
||||
// Setup the size of the memory that the positions and coordinates will use
|
||||
lengthPositions = sizeof(float) * PRIMITIVE_POSITIONS_PER_VERTICE * count;
|
||||
offsetPositions = sizeof(float) * PRIMITIVE_POSITIONS_PER_VERTICE * position;
|
||||
|
||||
lengthCoordinates = sizeof(float) * PRIMITIVE_COORDINATES_PER_VERTICE * count;
|
||||
offsetCoordinates = (
|
||||
(sizeof(float) * PRIMITIVE_POSITIONS_PER_VERTICE * primitive->verticeCount)+
|
||||
(sizeof(float) * PRIMITIVE_COORDINATES_PER_VERTICE * position)
|
||||
);
|
||||
|
||||
// Create some memory
|
||||
positions = malloc(lengthPositions);
|
||||
coordinates = malloc(lengthCoordinates);
|
||||
|
||||
// Now copy the positions and coordinates from the vertices into the buffer
|
||||
for(i = 0; i < count; i++) {
|
||||
positions[i * PRIMITIVE_POSITIONS_PER_VERTICE] = vertices[i].x;
|
||||
positions[i * PRIMITIVE_POSITIONS_PER_VERTICE + 1] = vertices[i].y;
|
||||
positions[i * PRIMITIVE_POSITIONS_PER_VERTICE + 2] = vertices[i].z;
|
||||
|
||||
coordinates[i * PRIMITIVE_COORDINATES_PER_VERTICE] = vertices[i].u;
|
||||
coordinates[i * PRIMITIVE_COORDINATES_PER_VERTICE + 1] = vertices[i].v;
|
||||
}
|
||||
|
||||
// Buffer the data into the GPU
|
||||
glBindBuffer(GL_ARRAY_BUFFER, primitive->vertexBuffer);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, offsetPositions, lengthPositions, positions);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, offsetCoordinates, lengthCoordinates, coordinates);
|
||||
|
||||
// Free the vertices.
|
||||
free(positions);
|
||||
free(coordinates);
|
||||
}
|
||||
|
||||
void primitiveBufferIndices(primitive_t *primitive,
|
||||
int32_t position, int32_t count, indice_t *indices
|
||||
) {
|
||||
size_t length, offset;
|
||||
offset = position * sizeof(indice_t);
|
||||
length = count * sizeof(indice_t);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, primitive->indexBuffer);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, length, indices);
|
||||
}
|
||||
|
||||
void primitiveDraw(primitive_t *primitive, int32_t start, int32_t count) {
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, primitive->indexBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, primitive->vertexBuffer);
|
||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, (void *)(
|
||||
sizeof(indice_t)*start
|
||||
));
|
||||
}
|
||||
|
||||
void primitiveDispose(primitive_t *primitive) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glDeleteBuffers(1, &primitive->vertexBuffer);
|
||||
glDeleteBuffers(1, &primitive->indexBuffer);
|
||||
free(primitive);
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <glad/glad.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#define PRIMITIVE_POSITIONS_PER_VERTICE 3
|
||||
#define PRIMITIVE_COORDINATES_PER_VERTICE 2
|
||||
|
||||
/** Structure containing information about a primitive */
|
||||
typedef struct {
|
||||
int32_t verticeCount;
|
||||
int32_t indiceCount;
|
||||
|
||||
GLuint vertexBuffer;
|
||||
GLuint indexBuffer;
|
||||
} primitive_t;
|
||||
|
||||
/** Structure containing vertice position information */
|
||||
typedef struct {
|
||||
float x, y, z;
|
||||
float u, v;
|
||||
} vertice_t;
|
||||
|
||||
/** Indice that references a specific vertice */
|
||||
typedef unsigned int indice_t;
|
||||
|
||||
/**
|
||||
* Creates a new primitive.
|
||||
* @param verticeCount How many vertices can the primitive hold.
|
||||
* @param indiceCount How many indices can the primitive hold.
|
||||
* @return The newly created primitive ready to be buffered to.
|
||||
*/
|
||||
primitive_t * primitiveCreate(int32_t verticeCount, int32_t indiceCount);
|
||||
|
||||
/**
|
||||
* Buffer Vertices to a primitive for use in rendering.
|
||||
* @param primitive The primitive to buffer vertices into.
|
||||
* @param position The position (index) to overwrite the vertices of.
|
||||
* @param count The count of vertices to buffer.
|
||||
* @param vertices Array of vertices to buffer into the primitive.
|
||||
*/
|
||||
void primitiveBufferVertices(primitive_t *primitive,
|
||||
int32_t position, int32_t count, vertice_t *vertices
|
||||
);
|
||||
|
||||
/**
|
||||
* Buffer Indices to a primitive for use in rendering.
|
||||
* @param primitive The primitive to buffer indices into.
|
||||
* @param position The position (index) to overwrite the indices of.
|
||||
* @param count The count of indices to buffer.
|
||||
* @param indices Array of indices to buffer into the primitive.
|
||||
*/
|
||||
void primitiveBufferIndices(primitive_t *primitive,
|
||||
int32_t position, int32_t count, indice_t *indices
|
||||
);
|
||||
|
||||
/**
|
||||
* Draw a primitive. Primitives are drawn by their indices.
|
||||
* @param primitive Primitive to draw.
|
||||
* @param start Start indice (index) to draw.
|
||||
* @param count Count of indices to draw.
|
||||
*/
|
||||
void primitiveDraw(primitive_t *primitive, int32_t start, int32_t count);
|
||||
|
||||
/**
|
||||
* Cleanup a previously created primitive.
|
||||
* @param primitive Primitive to cleanup.
|
||||
*/
|
||||
void primitiveDispose(primitive_t *primitive);
|
@ -1,112 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "cube.h"
|
||||
|
||||
void cubeBuffer(primitive_t *prim,
|
||||
float x, float y, float z,
|
||||
float w, float h, float d,
|
||||
int32_t verticeStart, int32_t indiceStart
|
||||
) {
|
||||
vertice_t *vertices = malloc(sizeof(vertice_t) * CUBE_VERTICE_COUNT);
|
||||
indice_t *indices = malloc(sizeof(indice_t) * CUBE_INDICE_COUNT);
|
||||
|
||||
vertices[0].x = x, vertices[0].y = y, vertices[0].z = z;
|
||||
vertices[0].u = 0, vertices[0].v = 0;
|
||||
|
||||
vertices[1].x = x+w, vertices[1].y = y, vertices[1].z = z;
|
||||
vertices[1].u = 1, vertices[1].v = 0;
|
||||
|
||||
vertices[2].x = x, vertices[2].y = y+h, vertices[2].z = z;
|
||||
vertices[2].u = 0, vertices[2].v = 1;
|
||||
|
||||
vertices[3].x = x+w, vertices[3].y = y+h, vertices[3].z = z;
|
||||
vertices[3].u = 1, vertices[3].v = 1;
|
||||
|
||||
vertices[4].x = x, vertices[4].y = y, vertices[4].z = z+d;
|
||||
vertices[4].u = 0, vertices[4].v = 0;
|
||||
|
||||
vertices[5].x = x+w, vertices[5].y = y, vertices[5].z = z+d;
|
||||
vertices[5].u = 1, vertices[5].v = 0;
|
||||
|
||||
vertices[6].x = x, vertices[6].y = y+h, vertices[6].z = z+d;
|
||||
vertices[6].u = 0, vertices[6].v = 1;
|
||||
|
||||
vertices[7].x = x+w, vertices[7].y = y+h, vertices[7].z = z+d;
|
||||
vertices[7].u = 1, vertices[7].v = 1;
|
||||
|
||||
// Back
|
||||
indices[ 0] = (indice_t)(verticeStart + 0);
|
||||
indices[ 1] = (indice_t)(verticeStart + 1);
|
||||
indices[ 2] = (indice_t)(verticeStart + 3);
|
||||
|
||||
indices[ 3] = (indice_t)(verticeStart + 0);
|
||||
indices[ 4] = (indice_t)(verticeStart + 2);
|
||||
indices[ 5] = (indice_t)(verticeStart + 3);
|
||||
|
||||
// Right
|
||||
indices[ 6] = (indice_t)(verticeStart + 1);
|
||||
indices[ 7] = (indice_t)(verticeStart + 5);
|
||||
indices[ 8] = (indice_t)(verticeStart + 7);
|
||||
|
||||
indices[ 9] = (indice_t)(verticeStart + 1);
|
||||
indices[10] = (indice_t)(verticeStart + 3);
|
||||
indices[11] = (indice_t)(verticeStart + 7);
|
||||
|
||||
// Left
|
||||
indices[12] = (indice_t)(verticeStart + 4);
|
||||
indices[13] = (indice_t)(verticeStart + 0);
|
||||
indices[14] = (indice_t)(verticeStart + 2);
|
||||
|
||||
indices[15] = (indice_t)(verticeStart + 4);
|
||||
indices[16] = (indice_t)(verticeStart + 6);
|
||||
indices[17] = (indice_t)(verticeStart + 2);
|
||||
|
||||
// Front
|
||||
indices[18] = (indice_t)(verticeStart + 5);
|
||||
indices[19] = (indice_t)(verticeStart + 4);
|
||||
indices[20] = (indice_t)(verticeStart + 6);
|
||||
|
||||
indices[21] = (indice_t)(verticeStart + 5);
|
||||
indices[22] = (indice_t)(verticeStart + 7);
|
||||
indices[23] = (indice_t)(verticeStart + 6);
|
||||
|
||||
// Top
|
||||
indices[24] = (indice_t)(verticeStart + 7);
|
||||
indices[25] = (indice_t)(verticeStart + 2);
|
||||
indices[26] = (indice_t)(verticeStart + 6);
|
||||
|
||||
indices[27] = (indice_t)(verticeStart + 7);
|
||||
indices[28] = (indice_t)(verticeStart + 3);
|
||||
indices[29] = (indice_t)(verticeStart + 2);
|
||||
|
||||
// Bottom
|
||||
indices[30] = (indice_t)(verticeStart + 1);
|
||||
indices[31] = (indice_t)(verticeStart + 0);
|
||||
indices[32] = (indice_t)(verticeStart + 4);
|
||||
|
||||
indices[33] = (indice_t)(verticeStart + 1);
|
||||
indices[34] = (indice_t)(verticeStart + 4);
|
||||
indices[35] = (indice_t)(verticeStart + 5);
|
||||
|
||||
|
||||
primitiveBufferVertices(prim, verticeStart, CUBE_VERTICE_COUNT, vertices);
|
||||
primitiveBufferIndices(prim, indiceStart, CUBE_INDICE_COUNT, indices);
|
||||
|
||||
free(vertices);
|
||||
free(indices);
|
||||
}
|
||||
|
||||
primitive_t * cubeCreate(float w, float h, float d) {
|
||||
primitive_t *cube = primitiveCreate(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
|
||||
cubeBuffer(cube,
|
||||
-w/2, -h/2, -d/2,
|
||||
w, h, d,
|
||||
0, 0
|
||||
);
|
||||
return cube;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include "../primitive.h"
|
||||
|
||||
#define CUBE_VERTICE_COUNT 8
|
||||
#define CUBE_INDICE_COUNT 36
|
||||
|
||||
|
||||
/**
|
||||
* Buffer the vertices and indices of a cube onto a primitive.
|
||||
* @param primitive Primitive to buffer to.
|
||||
* @param x X position of the cube.
|
||||
* @param y Y position of the cube.
|
||||
* @param z Z position of the cube.
|
||||
* @param w Width of cube.
|
||||
* @param h Height of cube.
|
||||
* @param d Depth of cube.
|
||||
* @param verticeStart The position of the vertex buffer to buffer into.
|
||||
* @param indiceStart The position of the index buffer to buffer into.
|
||||
*/
|
||||
void cubeBuffer(primitive_t *primitive,
|
||||
float x, float y, float z,
|
||||
float w, float h, float d,
|
||||
int32_t verticeStart, int32_t indiceStart
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates a cube primitive of given size.
|
||||
* @param w Width of cube.
|
||||
* @param h Height of cube.
|
||||
* @param d Depth of cube.
|
||||
* @return Primitive of the cube.
|
||||
*/
|
||||
primitive_t * cubeCreate(float w, float h, float d);
|
@ -1,58 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "quad.h"
|
||||
|
||||
void quadBuffer(primitive_t *primitive, float z,
|
||||
float x0, float y0, float u0, float v0,
|
||||
float x1, float y1, float u1, float v1,
|
||||
int32_t verticeStart, int32_t indiceStart
|
||||
) {
|
||||
vertice_t *vertices = malloc(sizeof(vertice_t) * QUAD_VERTICE_COUNT);
|
||||
indice_t *indices = malloc(sizeof(indice_t) * QUAD_INDICE_COUNT);
|
||||
|
||||
vertices[0].x = x0, vertices[0].y = y0, vertices[0].z = z;
|
||||
vertices[0].u = u0, vertices[0].v = v0;
|
||||
|
||||
vertices[1].x = x1, vertices[1].y = y0, vertices[1].z = z;
|
||||
vertices[1].u = u1, vertices[1].v = v0;
|
||||
|
||||
vertices[2].x = x0, vertices[2].y = y1, vertices[2].z = z;
|
||||
vertices[2].u = u0, vertices[2].v = v1;
|
||||
|
||||
vertices[3].x = x1, vertices[3].y = y1, vertices[3].z = z;
|
||||
vertices[3].u = u1, vertices[3].v = v1;
|
||||
|
||||
indices[0] = (indice_t)(verticeStart + 0);
|
||||
indices[1] = (indice_t)(verticeStart + 1);
|
||||
indices[2] = (indice_t)(verticeStart + 2);
|
||||
|
||||
indices[3] = (indice_t)(verticeStart + 1);
|
||||
indices[4] = (indice_t)(verticeStart + 2);
|
||||
indices[5] = (indice_t)(verticeStart + 3);
|
||||
|
||||
primitiveBufferVertices(primitive,verticeStart,QUAD_VERTICE_COUNT,vertices);
|
||||
primitiveBufferIndices( primitive,indiceStart, QUAD_INDICE_COUNT, indices );
|
||||
|
||||
free(vertices);
|
||||
free(indices);
|
||||
}
|
||||
|
||||
primitive_t * quadCreate(float z,
|
||||
float x0, float y0, float u0, float v0,
|
||||
float x1, float y1, float u1, float v1
|
||||
) {
|
||||
primitive_t *primitive = primitiveCreate(4, 6);
|
||||
|
||||
quadBuffer(primitive, z,
|
||||
x0, y0, u0, v0,
|
||||
x1, y1, u1, v1,
|
||||
0, 0
|
||||
);
|
||||
|
||||
return primitive;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "../primitive.h"
|
||||
|
||||
#define QUAD_VERTICE_COUNT 4
|
||||
#define QUAD_INDICE_COUNT 6
|
||||
|
||||
/**
|
||||
* Buffers the vertices of a quad onto a primitive.
|
||||
*
|
||||
* @param primitive The primitive to buffer to.
|
||||
* @param z The Z axis coordinate of the quad.
|
||||
* @param x0 The X lower coordinate.
|
||||
* @param y0 The Y lower coordinate.
|
||||
* @param u0 The X lower texture coordinate.
|
||||
* @param v0 The Y lower texture coordinate.
|
||||
* @param x1 The X higher coordinate.
|
||||
* @param y1 The Y higher coordinate.
|
||||
* @param u1 The X higher texture coordinate.
|
||||
* @param v1 The Y higher texture coordinate.
|
||||
* @param verticeStart Start vertice to buffer to.
|
||||
* @param indiceStart Start indice to buffer to.
|
||||
*/
|
||||
void quadBuffer(primitive_t *primitive, float z,
|
||||
float x0, float y0, float u0, float v0,
|
||||
float x1, float y1, float u1, float v1,
|
||||
int32_t verticeStart, int32_t indiceStart
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates a new quad primitive.
|
||||
*
|
||||
* @param z The Z axis coordinate of the quad.
|
||||
* @param x0 The X lower coordinate.
|
||||
* @param y0 The Y lower coordinate.
|
||||
* @param u0 The X lower texture coordinate.
|
||||
* @param v0 The Y lower texture coordinate.
|
||||
* @param x1 The X higher coordinate.
|
||||
* @param y1 The Y higher coordinate.
|
||||
* @param u1 The X higher texture coordinate.
|
||||
* @param v1 The Y higher texture coordinate.
|
||||
* @return The quad primitive.
|
||||
*/
|
||||
primitive_t * quadCreate(float z,
|
||||
float x0, float y0, float u0, float v0,
|
||||
float x1, float y1, float u1, float v1
|
||||
);
|
@ -1,44 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Msters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "render.h"
|
||||
|
||||
render_t * renderInit(char *name) {
|
||||
// Initialize the renderer
|
||||
render_t *render = malloc(sizeof(render_t));
|
||||
if(!render) return NULL;
|
||||
// render->width = WINDOW_WIDTH_DEFAULT;
|
||||
// render->height = WINDOW_HEIGHT_DEFAULT;
|
||||
|
||||
// Enable GL things.
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// Setup the alpha blend function.
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask(GL_TRUE);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
return render;
|
||||
}
|
||||
|
||||
void renderFrame(render_t *render) {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
bool renderDispose(render_t *render) {
|
||||
// Free up the renderer
|
||||
free(render);
|
||||
return true;
|
||||
}
|
||||
|
||||
void renderSetResolution(render_t *render, uint32_t width, uint32_t height) {
|
||||
render->width = width;
|
||||
render->height = height;
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Msters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include <glad/glad.h>
|
||||
#include <cglm/call.h>
|
||||
#include "primitive.h"
|
||||
|
||||
/**
|
||||
* Contains information about the current render state, can be used for querying
|
||||
* how the renderer is currently set up.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Resolution (in pixels) */
|
||||
int32_t width, height;
|
||||
} render_t;
|
||||
|
||||
/**
|
||||
* Initialize the renderer.
|
||||
*
|
||||
* @param name String of the windows' name.
|
||||
* @return Rendering Context information.
|
||||
*/
|
||||
render_t * renderInit(char *name);
|
||||
|
||||
/**
|
||||
* Render a single frame of the render loop. The renderer is not (currently)
|
||||
* responsible for render looping.
|
||||
*
|
||||
* @param render The renderer to loop for.
|
||||
*/
|
||||
void renderFrame(render_t *render);
|
||||
|
||||
/**
|
||||
* Cleanup a render context.
|
||||
*
|
||||
* @param render Renderer to cleanup.
|
||||
* @return True or False if Successful/Not.
|
||||
*/
|
||||
bool renderDispose(render_t *render);
|
||||
|
||||
/**
|
||||
* Set the internal display resolution.
|
||||
*
|
||||
* @param render Renderer to set resolution for.
|
||||
* @param width Width (in pixels) of the viewport.
|
||||
* @param height Height (in pixels) of the viewport.
|
||||
*/
|
||||
void renderSetResolution(render_t *render, uint32_t width, uint32_t height);
|
@ -1,141 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Msters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "shader.h"
|
||||
|
||||
shader_t * shaderCompile(char *vertexShaderSource, char* fragmentShaderSource) {
|
||||
int isSuccess, maxLength;
|
||||
char *error;
|
||||
GLuint shaderVertex, shaderFragment, shaderProgram;
|
||||
|
||||
|
||||
// Load the vertex shader first
|
||||
shaderVertex = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(shaderVertex, 1, &vertexShaderSource, 0);
|
||||
glCompileShader(shaderVertex);
|
||||
|
||||
// Validate
|
||||
glGetShaderiv(shaderVertex, GL_COMPILE_STATUS, &isSuccess);
|
||||
if(!isSuccess) {
|
||||
glGetShaderiv(shaderVertex, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
error = malloc(maxLength);
|
||||
glGetShaderInfoLog(shaderVertex, maxLength, &maxLength, error);
|
||||
printf("Failed to compile vertex shader %s\n", error);
|
||||
free(error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Now load the Frag shader
|
||||
shaderFragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(shaderFragment, 1, &fragmentShaderSource, 0);
|
||||
glCompileShader(shaderFragment);
|
||||
glGetShaderiv(shaderFragment, GL_COMPILE_STATUS, &isSuccess);
|
||||
if(!isSuccess) {
|
||||
glGetShaderiv(shaderFragment, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
error = malloc(maxLength);
|
||||
glGetShaderInfoLog(shaderFragment, maxLength, &maxLength, error);
|
||||
printf("Failed to compile fragment shader %s\n", error);
|
||||
free(error);
|
||||
glDeleteShader(shaderVertex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Now create the shader program.
|
||||
shaderProgram = glCreateProgram();
|
||||
glAttachShader(shaderProgram, shaderVertex);
|
||||
glAttachShader(shaderProgram, shaderFragment);
|
||||
|
||||
//Bind, Verify & Use the shader program
|
||||
glLinkProgram(shaderProgram);
|
||||
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &isSuccess);
|
||||
if(!isSuccess) {
|
||||
glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
error = malloc(maxLength);
|
||||
glGetProgramInfoLog(shaderProgram, maxLength, &maxLength, error);
|
||||
printf("Failed to load shader program %s\n", error);
|
||||
free(error);
|
||||
glDeleteShader(shaderVertex);
|
||||
glDeleteShader(shaderFragment);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Everything is okay, let's create the encapsulated shader.
|
||||
shader_t *shader = malloc(sizeof(shader_t));
|
||||
if(shader == NULL) {
|
||||
glDeleteProgram(shaderProgram);
|
||||
glDeleteShader(shaderVertex);
|
||||
glDeleteShader(shaderFragment);
|
||||
return NULL;
|
||||
}
|
||||
shader->shaderVertex = shaderVertex;
|
||||
shader->shaderFrag = shaderFragment;
|
||||
shader->shaderProgram = shaderProgram;
|
||||
|
||||
shader->uniProj = glGetUniformLocation(shader->shaderProgram, SHADER_UNI_PROJ);
|
||||
shader->uniView = glGetUniformLocation(shader->shaderProgram, SHADER_UNI_VIEW);
|
||||
shader->uniText = glGetUniformLocation(shader->shaderProgram, SHADER_UNI_TEXT);
|
||||
shader->uniModl = glGetUniformLocation(shader->shaderProgram, SHADER_UNI_MODL);
|
||||
|
||||
// Bind the shader
|
||||
shaderUse(shader);
|
||||
|
||||
// Reset position
|
||||
shaderUsePosition(shader, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
// Fetch the uniforms.
|
||||
return shader;
|
||||
}
|
||||
|
||||
bool shaderDipose(shader_t *shader) {
|
||||
glDeleteProgram(shader->shaderProgram);
|
||||
glDeleteShader(shader->shaderVertex);
|
||||
glDeleteShader(shader->shaderFrag);
|
||||
free(shader);
|
||||
return true;
|
||||
}
|
||||
|
||||
void shaderUse(shader_t *shader) {
|
||||
glUseProgram(shader->shaderProgram);
|
||||
}
|
||||
|
||||
void shaderUseCamera(shader_t *shader, camera_t *camera) {
|
||||
glUniformMatrix4fv(shader->uniView, 1, GL_FALSE, (float*)camera->view);
|
||||
glUniformMatrix4fv(shader->uniProj, 1, GL_FALSE, (float*)camera->projection);
|
||||
}
|
||||
|
||||
void shaderUseTexture(shader_t *shader, texture_t *texture) {
|
||||
// OpenGL requires us to set the active texure.
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
glUniform1i(shader->uniText, 0);
|
||||
}
|
||||
|
||||
void shaderUsePosition(shader_t *shader,
|
||||
float x, float y, float z,
|
||||
float pitch, float yaw, float roll
|
||||
) {
|
||||
mat4 MATRIX_POSITION;
|
||||
vec3 axis;
|
||||
|
||||
// Identify mat.
|
||||
glm_mat4_identity(MATRIX_POSITION);
|
||||
|
||||
//Position
|
||||
axis[0] = x, axis[1] = y, axis[2] = z;
|
||||
glm_translate(MATRIX_POSITION, axis);
|
||||
|
||||
//Rotation, we do each axis individually
|
||||
axis[0] = 1, axis[1] = 0, axis[2] = 0;
|
||||
glm_rotate(MATRIX_POSITION, pitch, axis);
|
||||
axis[0] = 0, axis[1] = 1;
|
||||
glm_rotate(MATRIX_POSITION, yaw, axis);
|
||||
axis[1] = 0, axis[2] = 1;
|
||||
glm_rotate(MATRIX_POSITION, roll, axis);
|
||||
|
||||
//Send to the shader.
|
||||
glUniformMatrix4fv(shader->uniModl, 1, GL_FALSE, (float*)MATRIX_POSITION);
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Msters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <malloc.h>
|
||||
#include "camera.h"
|
||||
#include "texture.h"
|
||||
|
||||
#define SHADER_UNI_VIEW "u_View"
|
||||
#define SHADER_UNI_PROJ "u_Proj"
|
||||
#define SHADER_UNI_TEXT "u_Text"
|
||||
#define SHADER_UNI_MODL "u_Modl"
|
||||
|
||||
/**
|
||||
* Structure containing information about an OpenGL Shader. For simplicity sake
|
||||
* we demand certain uninforms to be present on the shader target.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Pointer to an uploaded vertex shader program */
|
||||
GLuint shaderVertex;
|
||||
|
||||
/** Pointer to an uploaded fragment shader program */
|
||||
GLuint shaderFrag;
|
||||
|
||||
/** Pointer to an uploaded shader program linked */
|
||||
GLuint shaderProgram;
|
||||
|
||||
/** Matrix for the view matrix */
|
||||
GLint uniView;
|
||||
|
||||
/** Matrix for the projection matrix */
|
||||
GLint uniProj;
|
||||
|
||||
/** Uniform for the current texture */
|
||||
GLint uniText;
|
||||
|
||||
/** Uniform for the current model world position */
|
||||
GLint uniModl;
|
||||
} shader_t;
|
||||
|
||||
/**
|
||||
* Create a shader from vertex and fragment shader code.
|
||||
*
|
||||
* @param vertexShaderSource The raw vertex shader code.
|
||||
* @param fragmentShaderSource The raw fragment shader code.
|
||||
* @return Pointer to the loaded shader.
|
||||
*/
|
||||
shader_t * shaderCompile(char *vertexShaderSource, char* fragmentShaderSource);
|
||||
|
||||
/**
|
||||
* Cleanup and unload a previously loaded shader.
|
||||
*
|
||||
* @param shader The shader to unload
|
||||
* @return True if successfully disposed.
|
||||
*/
|
||||
bool shaderDipose(shader_t *shader);
|
||||
|
||||
/**
|
||||
* Attaches the supplied shader as the current shader.
|
||||
* @param shader The shader to attach
|
||||
*/
|
||||
void shaderUse(shader_t *shader);
|
||||
|
||||
|
||||
/**
|
||||
* Attaches a camera to the shader.
|
||||
* @param shader Shader to attach to.
|
||||
* @param camera Camera to attach.
|
||||
*/
|
||||
void shaderUseCamera(shader_t *shader, camera_t *camera);
|
||||
|
||||
/**
|
||||
* Attaches a texture to the shader.
|
||||
* @param shader Shader to attach to.
|
||||
* @param texture Texture to attach.
|
||||
*/
|
||||
void shaderUseTexture(shader_t *shader, texture_t *texture);
|
||||
|
||||
void shaderUsePosition(shader_t *shader,
|
||||
float x, float y, float z,
|
||||
float pitch, float yaw, float roll
|
||||
);
|
@ -1,59 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "spritebatch.h"
|
||||
|
||||
spritebatch_t * spriteBatchCreate(int32_t maxSprites) {
|
||||
spritebatch_t *batch = malloc(sizeof(spritebatch_t));
|
||||
if(batch == NULL) return NULL;
|
||||
|
||||
batch->maxSprites = maxSprites;
|
||||
batch->currentSprite = 0;
|
||||
|
||||
batch->primitive = primitiveCreate(
|
||||
maxSprites*QUAD_VERTICE_COUNT, maxSprites*QUAD_INDICE_COUNT
|
||||
);
|
||||
if(batch == NULL) {
|
||||
free(batch);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return batch;
|
||||
}
|
||||
|
||||
void spriteBatchQuad(spritebatch_t *spriteBatch, int32_t index,
|
||||
float x, float y, float z, float width, float height,
|
||||
float u0, float v0, float u1, float v1
|
||||
) {
|
||||
if(index == -1) {
|
||||
index = spriteBatch->currentSprite++;
|
||||
} else {
|
||||
spriteBatch->currentSprite = mathMax(index, spriteBatch->currentSprite);
|
||||
}
|
||||
|
||||
quadBuffer(spriteBatch->primitive, z,
|
||||
x, y, u0, v0,
|
||||
x+width, y+height, u1, v1,
|
||||
index*QUAD_VERTICE_COUNT, index*QUAD_INDICE_COUNT
|
||||
);
|
||||
}
|
||||
|
||||
void spriteBatchFlush(spritebatch_t *spriteBatch) {
|
||||
spriteBatch->currentSprite = 0;
|
||||
}
|
||||
|
||||
void spriteBatchDraw(spritebatch_t *spriteBatch, int32_t index, int32_t count) {
|
||||
if(count == -1) count = spriteBatch->currentSprite;
|
||||
primitiveDraw(spriteBatch->primitive,
|
||||
index*QUAD_INDICE_COUNT, count*QUAD_INDICE_COUNT
|
||||
);
|
||||
}
|
||||
|
||||
void spriteBatchDispose(spritebatch_t *spriteBatch) {
|
||||
primitiveDispose(spriteBatch->primitive);
|
||||
free(spriteBatch);
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "primitive.h"
|
||||
#include "primitives/quad.h"
|
||||
#include "../util/math.h"
|
||||
|
||||
typedef struct {
|
||||
/** Maximum sprites the batch can hold. */
|
||||
int32_t maxSprites;
|
||||
|
||||
/** The current/next sprite index. */
|
||||
int32_t currentSprite;
|
||||
|
||||
/** Internal primitive */
|
||||
primitive_t *primitive;
|
||||
} spritebatch_t;
|
||||
|
||||
/**
|
||||
* Creates a new Sprite Batch made of standard quads.
|
||||
*
|
||||
* @param maxSprites The maxiumum number of sprites the batch can hold.
|
||||
* @returns A new quad Sprite Batch.
|
||||
*/
|
||||
spritebatch_t * spriteBatchCreate(int32_t maxSprites);
|
||||
|
||||
/**
|
||||
* Renders a sprite onto a given Sprite Batch.
|
||||
*
|
||||
* @param spriteBatch The sprite batch to render to.
|
||||
* @param index The index within the sprite batch. Set to -1 to select "next".
|
||||
* @param x X coordinate of the sprite.
|
||||
* @param y Y coordinate of the sprite.
|
||||
* @param width Width of the sprite.
|
||||
* @param height Height of the sprite.
|
||||
* @param u0 Texture U coordinate (min).
|
||||
* @param v0 Texture V coordinate (min).
|
||||
* @param u1 Texture U coordinate (max).
|
||||
* @param v1 Texture V coordinate (max).
|
||||
*/
|
||||
void spriteBatchQuad(spritebatch_t *spriteBatch, int32_t index,
|
||||
float x, float y, float z, float width, float height,
|
||||
float u0, float v0, float u1, float v1
|
||||
);
|
||||
|
||||
/**
|
||||
* Flushes a sprite batch to reset the indexes.
|
||||
* @param spriteBatch The batch.
|
||||
*/
|
||||
void spriteBatchFlush(spritebatch_t *spriteBatch);
|
||||
|
||||
/**
|
||||
* Draws the Sprite Batch.
|
||||
*
|
||||
* @param spriteBatch The sprite batch to render.
|
||||
* @param start Start index to render from.
|
||||
* @param count Count of sprites to render. Set to -1 to render to the current.
|
||||
*/
|
||||
void spriteBatchDraw(spritebatch_t *spriteBatch, int32_t start, int32_t count);
|
||||
|
||||
/**
|
||||
* Disposes a previously created Sprite Batch.
|
||||
*
|
||||
* @param spriteBatch The sprite batch to dispose.
|
||||
*/
|
||||
void spriteBatchDispose(spritebatch_t *spriteBatch);
|
@ -1,61 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
texture_t * textureCreate(int32_t width, int32_t height, pixel_t *pixels) {
|
||||
texture_t *texture = malloc(sizeof(texture_t));
|
||||
if(texture == NULL) return NULL;
|
||||
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
|
||||
// Generate a texture ID and bind.
|
||||
glGenTextures(1, &texture->id);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
|
||||
// Setup our preferred texture params
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
// Start by buffering all transparent black pixels.
|
||||
if(pixels == NULL) {
|
||||
pixels = calloc(width * height, sizeof(pixel_t));
|
||||
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, pixels
|
||||
);
|
||||
|
||||
free(pixels);
|
||||
} else {
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, pixels
|
||||
);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
void textureBufferPixels(texture_t *texture,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height, pixel_t *pixels
|
||||
) {
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
x, y, width, height,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, pixels
|
||||
);
|
||||
}
|
||||
|
||||
void textureDispose(texture_t *texture) {
|
||||
glDeleteTextures(1, &texture->id);
|
||||
free(texture);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <glad/glad.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
|
||||
/**
|
||||
* Structure detailing information about a texture.
|
||||
* Because we plan to upload the pixels of a texture into the GPU, we don't
|
||||
* store the pixels in memory because we don't need to!
|
||||
*/
|
||||
typedef struct {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
GLuint id;
|
||||
} texture_t;
|
||||
|
||||
/** Information about a single pixel. */
|
||||
typedef struct {
|
||||
uint8_t r, g, b, a ;
|
||||
} pixel_t;
|
||||
|
||||
/**
|
||||
* Creates a new texture that can be written in to.
|
||||
*
|
||||
* @param width Width of the texture (in pixels).
|
||||
* @param height Height of the texture (in pixels).
|
||||
* @param pixels Default pixel array, set to NULL to set all pixel data to 0.
|
||||
* @return The newly created texture instance.
|
||||
*/
|
||||
texture_t * textureCreate(int32_t width, int32_t height, pixel_t *pixels);
|
||||
|
||||
/**
|
||||
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so avoid
|
||||
* doing this too often.
|
||||
*
|
||||
* @param texture Texture to buffer in to.
|
||||
* @param x X coordinate in texture space to render to.
|
||||
* @param y Y coordinate in texture space to render to.
|
||||
* @param width Width of the pixel region you're buffering.
|
||||
* @param height Height of the pixel region you're buffering.
|
||||
* @param pixels Array of pixels to buffer onto the GPU.
|
||||
*/
|
||||
void textureBufferPixels(texture_t *texture,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height, pixel_t *pixels
|
||||
);
|
||||
|
||||
/**
|
||||
* Clean a previously created texture.
|
||||
* @param texture Texture to clean up.
|
||||
*/
|
||||
void textureDispose(texture_t *texture);
|
@ -1,66 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "tileset.h"
|
||||
|
||||
tileset_t * tilesetCreate(
|
||||
int32_t columns, int32_t rows,
|
||||
int32_t width, int32_t height,
|
||||
int32_t gapX, int32_t gapY,
|
||||
int32_t borderX, int32_t borderY
|
||||
) {
|
||||
tileset_t *tileset;
|
||||
float divX, divY, tdivX;
|
||||
int32_t x, y, i;
|
||||
|
||||
tileset = malloc(sizeof(tileset_t));
|
||||
if(tileset == NULL) return NULL;
|
||||
|
||||
tileset->count = rows * columns;
|
||||
tileset->divisions = malloc(sizeof(tilesetdiv_t) * tileset->count);
|
||||
if(tileset->divisions == NULL) {
|
||||
free(tileset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tileset->columns = columns;
|
||||
tileset->rows = rows;
|
||||
|
||||
// Calculate division sizes (pixels)
|
||||
divX = (width - (borderX * 2) - (gapX * (columns - 1))) / columns;
|
||||
divY = (height - (borderY * 2) - (gapY * (rows - 1))) / rows;
|
||||
|
||||
// Calculate the division sizes (units)
|
||||
divX = divX / width;
|
||||
divY = divY / height;
|
||||
|
||||
// Calculate the divisions
|
||||
i = -1;
|
||||
for(y = 0; y < rows; y++) {
|
||||
for(x = 0; x < columns; x++) {
|
||||
tileset->divisions[++i].x0 = borderX + (divX * x) + (gapX * x);
|
||||
tileset->divisions[i].y0 = borderY + (divY * y) + (gapY * y);
|
||||
tileset->divisions[i].x1 = tileset->divisions[i].x0 + divX;
|
||||
tileset->divisions[i].y1 = tileset->divisions[i].y0 + divY;
|
||||
}
|
||||
}
|
||||
|
||||
return tileset;
|
||||
}
|
||||
|
||||
tilesetdiv_t tilesetGetDivision(tileset_t *tileset,
|
||||
int32_t column, int32_t row
|
||||
) {
|
||||
return tileset->divisions[
|
||||
(column % tileset->columns) + (row * tileset->columns)
|
||||
];
|
||||
}
|
||||
|
||||
void tilesetDispose(tileset_t *tileset) {
|
||||
free(tileset->divisions);
|
||||
free(tileset);
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
|
||||
/** Division of a texture */
|
||||
typedef struct {
|
||||
float x0, y0, x1, y1;
|
||||
} tilesetdiv_t;
|
||||
|
||||
/** Definition of a Tileset */
|
||||
typedef struct {
|
||||
/** Count of X/Y divisions */
|
||||
int32_t columns, rows;
|
||||
|
||||
/** Count of divisions (unused) */
|
||||
int32_t count;
|
||||
|
||||
/** Division information */
|
||||
tilesetdiv_t *divisions;
|
||||
} tileset_t;
|
||||
|
||||
|
||||
/**
|
||||
* Create a tileset. Tilesets will be pre-divided to save performance later.
|
||||
*
|
||||
* @param columns Count of columns.
|
||||
* @param rows Count of rows.
|
||||
* @param width Width of the tileset.
|
||||
* @param height Height of the tileset.
|
||||
* @param gapX Space between each column.
|
||||
* @param gapY Space between each row.
|
||||
* @param borderX Space around the edge of the tileset.
|
||||
* @param borderY Space around the edge of the tileset.
|
||||
* @returns The tileset.
|
||||
*/
|
||||
tileset_t * tilesetCreate(
|
||||
int32_t columns, int32_t rows,
|
||||
int32_t width, int32_t height,
|
||||
int32_t gapX, int32_t gapY,
|
||||
int32_t borderX, int32_t borderY
|
||||
);
|
||||
|
||||
/**
|
||||
* Retreive the division for a given tileset coordinate.
|
||||
*
|
||||
* @param tileset Tileset to retreive from.
|
||||
* @param column X axis of the tileset.
|
||||
* @param row Y axis of the tileset.
|
||||
* @returns The Tileset division.
|
||||
*/
|
||||
tilesetdiv_t tilesetGetDivision(tileset_t *tileset,
|
||||
int32_t column, int32_t row
|
||||
);
|
||||
|
||||
/**
|
||||
* Cleans a previously created tileset
|
||||
*
|
||||
* @param tileset Cleanup the tileset.
|
||||
*/
|
||||
void tilesetDispose(tileset_t *tileset);
|
@ -1,46 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
#include "engine.h"
|
||||
|
||||
engine_t * engineInit(platform_t *platform, char *name, uint32_t inputCount) {
|
||||
// Create the engine instance.
|
||||
engine_t *engine = malloc(sizeof(engine_t));
|
||||
if(engine == NULL) return NULL;
|
||||
|
||||
engine->name = name;
|
||||
engine->platform = platform;
|
||||
|
||||
// Setup the renderer.
|
||||
engine->render = renderInit(name);
|
||||
if(engine->render == NULL) {
|
||||
free(engine);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Setup the input manager.
|
||||
engine->input = inputInit(inputCount, platform->inputSourceCount);
|
||||
if(engine->input == NULL) {
|
||||
free(engine->render);
|
||||
free(engine);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
||||
uint32_t engineUpdate(engine_t *engine) {
|
||||
renderFrame(engine->render);
|
||||
inputUpdate(engine->input);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool engineDispose(engine_t *engine) {
|
||||
if(!renderDispose(engine->render)) return false;
|
||||
free(engine);
|
||||
|
||||
return true;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Msters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include "display/render.h"
|
||||
#include "input/input.h"
|
||||
#include "./platform.h"
|
||||
|
||||
/** Information about the current engine context. */
|
||||
typedef struct {
|
||||
/** Name of the game running. */
|
||||
char *name;
|
||||
|
||||
/** Platform the game is running on */
|
||||
platform_t *platform;
|
||||
|
||||
/** Renderer for the engine. */
|
||||
render_t *render;
|
||||
|
||||
/** Input Manager for the engine. */
|
||||
input_t *input;
|
||||
} engine_t;
|
||||
|
||||
/**
|
||||
* Initialize the engine context.
|
||||
*
|
||||
* @param platform The platform that the game is running on.
|
||||
* @param name Name of the game being initialized.
|
||||
* @param inputCount Count of input binds that exist in-engine.
|
||||
* @return The engine context.
|
||||
*/
|
||||
engine_t * engineInit(platform_t *platform, char *name, uint32_t inputCount);
|
||||
|
||||
/**
|
||||
* Start the main engine loop.
|
||||
*
|
||||
* @param engine The game to start the loop for.
|
||||
* @return 0 if success (and loop to continue), 1 for non error terminate.
|
||||
*/
|
||||
uint32_t engineUpdate(engine_t *engine);
|
||||
|
||||
/**
|
||||
* Cleanup a previously constructed game engine instance.
|
||||
*
|
||||
* @param engine The engine to cleanup.
|
||||
* @return True if successful or not.
|
||||
*/
|
||||
bool engineDispose(engine_t *engine);
|
||||
|
@ -1,129 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Msters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "asset.h"
|
||||
|
||||
#ifndef STB_IMAGE_IMPLEMENTATION
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
#endif
|
||||
|
||||
char * assetStringLoad(char *assetName) {
|
||||
// Open a buffer.
|
||||
FILE *fptr = assetBufferOpen(assetName);
|
||||
if(fptr == NULL) return NULL;
|
||||
|
||||
// Read the count of bytes in the file
|
||||
fseek(fptr, 0, SEEK_END);// Seek to the end
|
||||
size_t length = ftell(fptr);// Get our current position (the end)
|
||||
fseek(fptr, 0, SEEK_SET);// Reset the seek
|
||||
|
||||
// Create the string buffer
|
||||
char *str = malloc(length + 1);// Add 1 for the null terminator.
|
||||
if(str == NULL) {
|
||||
assetBufferClose(fptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Read and seal the string.
|
||||
fread(str, 1, length, fptr);// Read all the bytes
|
||||
str[length] = '\0';// Null terminate.
|
||||
assetBufferClose(fptr); // Close the buffer.
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
FILE * assetBufferOpen(char *assetName) {
|
||||
// Get the directory based on the raw input by creating a new string.
|
||||
size_t lenAsset = strlen(assetName);// Get the length of asset
|
||||
size_t lenPrefix = strlen(ASSET_PREFIX);// Get the length of the prefix
|
||||
|
||||
// Create str to house both the prefix and asset, and null terminator
|
||||
char *joined = malloc(lenAsset + lenPrefix + 1);
|
||||
if(joined == NULL) return NULL;// Mem okay?
|
||||
|
||||
joined[0] = '\0';//Start at null
|
||||
strcat(joined, ASSET_PREFIX);//Add prefix
|
||||
strcat(joined, assetName);//Add body
|
||||
|
||||
// Open the file pointer now.
|
||||
FILE *fptr = fopen(joined, "rb");
|
||||
free(joined);// Free the string we just created
|
||||
if(!fptr) return NULL;// File available?
|
||||
return fptr;
|
||||
}
|
||||
|
||||
bool assetBufferClose(FILE *buffer) {
|
||||
return fclose(buffer);
|
||||
}
|
||||
|
||||
int32_t assetBufferRead(FILE *buffer, char *data, int32_t size) {
|
||||
return (int32_t)fread(data, 1, size, buffer);
|
||||
}
|
||||
|
||||
int32_t assetBufferEnd(FILE *buffer) {
|
||||
return feof(buffer);
|
||||
}
|
||||
|
||||
void assetBufferSkip(FILE *buffer, int32_t n) {
|
||||
fseek(buffer, n, SEEK_CUR);
|
||||
}
|
||||
|
||||
shader_t * assetShaderLoad(char *fileVertex, char *fileFragment) {
|
||||
// Load the vertex shader into memory
|
||||
char *vertexShader = assetStringLoad(fileVertex);
|
||||
if(vertexShader == NULL) return NULL;
|
||||
|
||||
// Load the fragment shader into memory
|
||||
char *fragmentShader = assetStringLoad(fileFragment);
|
||||
if(fragmentShader == NULL) {
|
||||
free(vertexShader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Now attempt to load the shader
|
||||
shader_t *shader = shaderCompile(vertexShader, fragmentShader);
|
||||
|
||||
//Cleanup
|
||||
free(vertexShader);
|
||||
free(fragmentShader);
|
||||
|
||||
return shader;//shader may be NULL if loading failed, but not our problem.
|
||||
}
|
||||
|
||||
texture_t * assetTextureLoad(char *fileName) {
|
||||
FILE *buffer;
|
||||
texture_t *texture;
|
||||
int channels, width, height;
|
||||
pixel_t *data;
|
||||
stbi_io_callbacks OPENGL_STBI_CALLBACKS;
|
||||
|
||||
buffer = assetBufferOpen(fileName);
|
||||
if(buffer == NULL) return NULL;
|
||||
|
||||
// Setup the interface for STBI
|
||||
OPENGL_STBI_CALLBACKS.read = &assetBufferRead;
|
||||
OPENGL_STBI_CALLBACKS.skip = &assetBufferSkip;
|
||||
OPENGL_STBI_CALLBACKS.eof = &assetBufferEnd;
|
||||
|
||||
// Buffer the image
|
||||
channels = 0;
|
||||
data = (pixel_t *)stbi_load_from_callbacks(
|
||||
&OPENGL_STBI_CALLBACKS, buffer,
|
||||
&width, &height,
|
||||
&channels, STBI_rgb_alpha
|
||||
);
|
||||
|
||||
// Close the buffer
|
||||
assetBufferClose(buffer);
|
||||
if(data == NULL) return NULL;
|
||||
|
||||
// Turn into a texture.
|
||||
texture = textureCreate(width, height, data);
|
||||
stbi_image_free(data);
|
||||
return texture;
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Msters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../display/shader.h"
|
||||
#include "../display/texture.h"
|
||||
|
||||
/** Prefix of all asset load methods, may be customizable in future. */
|
||||
#define ASSET_PREFIX "../assets/"
|
||||
|
||||
/**
|
||||
* Method to load an asset into memory as a raw string.
|
||||
*
|
||||
* @param assetName Path leading to the asset within the root asset directory.
|
||||
* @return Pointer to char array of data from asset, NULL if unsuccesful.
|
||||
*/
|
||||
char * assetStringLoad(char *assetName);
|
||||
|
||||
/**
|
||||
* Platform-centric method to open a file buffer to an asset.
|
||||
*
|
||||
* @param assetName The asset name to open a buffer for.
|
||||
* @return Pointer to a buffer, NULL if unsuccessfuil.
|
||||
*/
|
||||
FILE * assetBufferOpen(char *assetName);
|
||||
|
||||
/**
|
||||
* Closes a previously opened asset buffer.
|
||||
*
|
||||
* @param buffer Buffer to close.
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool assetBufferClose(FILE *buffer);
|
||||
|
||||
/**
|
||||
* Read bytes from buffer.
|
||||
*
|
||||
* @param buffer The buffer pointing to an asset.
|
||||
* @param data Pointer to a ubyte array to buffer data into.
|
||||
* @param size Length of the data buffer. Represents how many bytes can be read.
|
||||
* @return The count of bytes read. Complete when less than data array size.
|
||||
*/
|
||||
int32_t assetBufferRead(FILE *buffer, char *data, int32_t size);
|
||||
|
||||
/**
|
||||
* Skip to the end of the buffer, useful to find the length of the buffer.
|
||||
*
|
||||
* @param Buffer The buffer pointing to an asset.
|
||||
* @return How many bytes were skipped
|
||||
*/
|
||||
int32_t assetBufferEnd(FILE *buffer);
|
||||
|
||||
/**
|
||||
* Method to skip n bytes in the buffer
|
||||
*
|
||||
* @param buffer The buffer pointing to an asset.
|
||||
* @param n Count of bytes to skip.
|
||||
*/
|
||||
void assetBufferSkip(FILE *buffer, int32_t n);
|
||||
|
||||
/**
|
||||
* Load a shader program from a vertex and fragment shader file.
|
||||
*
|
||||
* @param fileVertex The file path of the vertex shader
|
||||
* @param fileFragment The file path of the fragment shader
|
||||
* @return The loaded shader_t instance (From shaderCompile)
|
||||
*/
|
||||
shader_t * assetShaderLoad(char *fileVertex, char *fileFragment);
|
||||
|
||||
/**
|
||||
* Load a texture from a PNG file.
|
||||
*
|
||||
* @param fileName The fike path of the PNG image.
|
||||
* @return The loaded texture object.
|
||||
*/
|
||||
texture_t * assetTextureLoad(char *fileName);
|
@ -1,47 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Msters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include "../engine.h"
|
||||
#include "../platform.h"
|
||||
|
||||
/** Information about the current game context. */
|
||||
#ifndef GAMETYPE_T
|
||||
#define GAMETYPE_T void
|
||||
#endif
|
||||
typedef GAMETYPE_T game_t;
|
||||
|
||||
/**
|
||||
* Initialize the game context.
|
||||
*
|
||||
* @return The game instance context.
|
||||
*/
|
||||
game_t * gameInit(platform_t *platform);
|
||||
|
||||
/**
|
||||
* Start the main game loop.
|
||||
*
|
||||
* @param game The game to start the loop for.
|
||||
* @return Refer to engineUpdate. 0 for loop continue, 1 for safe exit.
|
||||
*/
|
||||
uint32_t gameUpdate(game_t *game);
|
||||
|
||||
/**
|
||||
* Cleanup a previously constructed.
|
||||
* @param game The game to cleanup.
|
||||
*/
|
||||
void gameDispose(game_t *game);
|
||||
|
||||
/**
|
||||
* Because games are anonymously typed we simply request that they allow other
|
||||
* parts of the software to access the engine directly.
|
||||
*
|
||||
* @param game The game context
|
||||
* @return The engine context attached to the running game.
|
||||
*/
|
||||
engine_t * gameGetEngine(game_t *game);
|
@ -1,120 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Msters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "input.h"
|
||||
|
||||
input_t * inputInit(uint32_t inputBindCount, uint32_t inputSourceCount) {
|
||||
uint32_t i;
|
||||
|
||||
// Create the input manager
|
||||
input_t *input = malloc(sizeof(input_t));
|
||||
if(!input) return NULL;
|
||||
|
||||
// Setup the bind lists
|
||||
input->inputBindCount = inputBindCount;
|
||||
input->bindMap = malloc(sizeof(list_t) * inputBindCount);
|
||||
for(i = 0; i < inputBindCount; i++) {
|
||||
input->bindMap[i] = listCreate();
|
||||
}
|
||||
|
||||
// Create the current & previous input states
|
||||
input->current = malloc(sizeof(inputval_t) * inputBindCount);
|
||||
input->previous = malloc(sizeof(inputval_t) * inputBindCount);
|
||||
|
||||
// Create the input actuate times array.
|
||||
input->times = malloc(sizeof(float) * inputBindCount);
|
||||
|
||||
// Create the buffer, zero all the values out.
|
||||
input->buffer = calloc(inputSourceCount, sizeof(inputval_t));
|
||||
|
||||
// Pass off the input manager
|
||||
return input;
|
||||
}
|
||||
|
||||
void inputUpdate(input_t *input) {
|
||||
uint32_t i;
|
||||
listentry_t *item;
|
||||
inputval_t value;
|
||||
|
||||
// Flip the states to save memory.
|
||||
float * currentCurrent = input->current;
|
||||
input->current = input->previous;
|
||||
input->previous = currentCurrent;
|
||||
|
||||
// Now look at each bind...
|
||||
for(i = 0; i < input->inputBindCount; i++) {
|
||||
// Now get the list of input sources bound to this input
|
||||
item = input->bindMap[i]->start;
|
||||
value = 0;
|
||||
|
||||
// For each input source, add the value from the buffer
|
||||
while(item != NULL) {
|
||||
value += input->buffer[(inputsource_t)item->data];
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
// Set to the current state.
|
||||
input->current[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void inputDispose(input_t *input) {
|
||||
uint32_t i;
|
||||
|
||||
// Free up the bind lists
|
||||
for(i = 0; i < input->inputBindCount; i++) {
|
||||
listDispose(input->bindMap[i], false);
|
||||
}
|
||||
|
||||
free(input->buffer);
|
||||
free(input->times);
|
||||
free(input->previous);
|
||||
free(input->current);
|
||||
free(input->bindMap);
|
||||
free(input);
|
||||
}
|
||||
|
||||
void inputBind(input_t *input, inputbind_t bind, inputsource_t source) {
|
||||
listAdd(input->bindMap[bind], source);
|
||||
}
|
||||
|
||||
void inputUnbind(input_t *input, inputbind_t bind, inputsource_t source) {
|
||||
listRemove(input->bindMap[bind], source);
|
||||
}
|
||||
|
||||
bool inputIsDown(input_t *input, inputbind_t binding) {
|
||||
return input->current[binding] != 0;
|
||||
}
|
||||
|
||||
bool inputIsUp(input_t *input, inputbind_t binding) {
|
||||
return input->current[binding] == 0;
|
||||
}
|
||||
|
||||
bool inputIsPressed(input_t *input, inputbind_t binding) {
|
||||
return (
|
||||
input->previous[binding] == 0 &&
|
||||
input->current[binding] != 0
|
||||
);
|
||||
}
|
||||
|
||||
bool inputIsReleased(input_t *input, inputbind_t binding) {
|
||||
return input->current[binding] == 0 && input->previous[binding] != 0;
|
||||
}
|
||||
|
||||
inputval_t inputGetAxis(input_t *input, inputbind_t binding) {
|
||||
return input->current[binding];
|
||||
}
|
||||
|
||||
float inputGetFullAxis(input_t *input, inputbind_t positive,
|
||||
inputbind_t negative
|
||||
) {
|
||||
return input->current[negative] + input->current[positive];
|
||||
}
|
||||
|
||||
float inputGetAccuated(input_t *input, inputbind_t binding) {
|
||||
return input->times[binding];
|
||||
}
|
@ -1,180 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Msters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include "../util/list.h"
|
||||
#include "../platform.h"
|
||||
|
||||
/////////////////////////////////// CONSTANTS //////////////////////////////////
|
||||
#define INPUT_NULL (inputbind_t)0x00
|
||||
|
||||
/////////////////////////////// Type Definitions ///////////////////////////////
|
||||
/**
|
||||
* Input Bind, a specific action bind reference for the game engine to use.
|
||||
* e.g. "Jump" or "Walk Forward".
|
||||
*/
|
||||
typedef uint8_t inputbind_t;
|
||||
|
||||
/**
|
||||
* Input source identifier. It's up to the platform itself to decide what the
|
||||
* hell this number refers to. For most platforms it will be an input, such as a
|
||||
* keyboard scancode or a (pad number * button count) + button.
|
||||
*/
|
||||
typedef uint32_t inputsource_t;
|
||||
|
||||
/**
|
||||
* Value that represents the state of an input. Defined as 0-1 where 0 is set
|
||||
* to be completely off / netural state, and 1 is completely on / full state.
|
||||
*/
|
||||
typedef float inputval_t;
|
||||
|
||||
/**
|
||||
* Structure for the entire input mapping.
|
||||
*/
|
||||
typedef struct {
|
||||
/** How many input bindings are in the input managers' scope */
|
||||
uint32_t inputBindCount;
|
||||
|
||||
/** Float of the input between 0 and 1. For teh current frame */
|
||||
inputval_t *current;
|
||||
|
||||
/** Float of the input between 0 and 1. For the last frame */
|
||||
inputval_t *previous;
|
||||
|
||||
/**
|
||||
* Input buffer array. Keeps track of raw values from the inputs.
|
||||
* The engine will read from the buffer when necessary.
|
||||
*/
|
||||
inputval_t *buffer;
|
||||
|
||||
/** Float of the GameTime that the input was actuated last. */
|
||||
float *times;
|
||||
|
||||
/**
|
||||
* Binding Map, Array of lists where index = binding and entry is a list of
|
||||
* input sources.
|
||||
*/
|
||||
list_t **bindMap;
|
||||
} input_t;
|
||||
|
||||
//////////////////////////////////// Methods ///////////////////////////////////
|
||||
|
||||
/**
|
||||
* Initializes the input manager.
|
||||
*
|
||||
* @param inputCount The input binding counts to allow for.
|
||||
* @param inputSourceCount The input source count to allow for.
|
||||
* @return The input manager
|
||||
*/
|
||||
input_t * inputInit(uint32_t inputBindCount, uint32_t inputSourceCount);
|
||||
|
||||
/**
|
||||
* Tick the input manager.
|
||||
* @param input The input to update.
|
||||
*/
|
||||
void inputUpdate(input_t *input);
|
||||
|
||||
/**
|
||||
* Destroy the input manager and cleanup.
|
||||
* @param input The input to destroy.
|
||||
*/
|
||||
void inputDispose(input_t *input);
|
||||
|
||||
/**
|
||||
* Binds the given input binding to the input source. Essentially allowing any
|
||||
* time we fetch the state of bind, we will read the value from source.
|
||||
*
|
||||
* @param input The input manager to bind for.
|
||||
* @param bind The binding to bind against.
|
||||
* @param source The source that is being bound.
|
||||
*/
|
||||
void inputBind(input_t *input, inputbind_t bind, inputsource_t source);
|
||||
|
||||
/**
|
||||
* Unbind a previously bound input source from a binding. This method is costly.
|
||||
*
|
||||
* @param input The input manager to bind for.
|
||||
* @param bind The binding to unbind from.
|
||||
* @param source The source that is being unbound.
|
||||
*/
|
||||
void inputUnbind(input_t *input, inputbind_t bind, inputsource_t source);
|
||||
|
||||
/**
|
||||
* Is the current input "down", not being pressed, being moved, not in a state
|
||||
* of rest.
|
||||
*
|
||||
* @param state The input state to check against.
|
||||
* @param binding The previously bound input binding.
|
||||
* @return True if the input vector is non-zero.
|
||||
*/
|
||||
bool inputIsDown(input_t *state, inputbind_t binding);
|
||||
|
||||
/**
|
||||
* Is the current input "up", in a state of rest, not being actioned, moved.
|
||||
*
|
||||
* @param state The input state to check against.
|
||||
* @param binding The previously bound input binding.
|
||||
* @return True if input vector is zero
|
||||
*/
|
||||
bool inputIsUp(input_t *state, inputbind_t binding);
|
||||
|
||||
/**
|
||||
* Returns true on the first tick that an input was actioned/downed.
|
||||
*
|
||||
* @param input The input manager.
|
||||
* @param binding The previously bound input binding.
|
||||
* @return True if the input vector was non-zeroed this tick but not last.
|
||||
*/
|
||||
bool inputIsPressed(input_t *input, inputbind_t binding);
|
||||
|
||||
/**
|
||||
* Returns true on the first tick that an input was released/upped.
|
||||
*
|
||||
* @param input The input manager.
|
||||
* @param binding The previously bound input binding.
|
||||
* @return True if the input vector was zeroed this tick but not last.
|
||||
*/
|
||||
bool inputIsReleased(input_t *input, inputbind_t binding);
|
||||
|
||||
/**
|
||||
* Returns the raw input value as a float between 0 and 1. For digital (buttons)
|
||||
* this will typicall be 0 or 1 only. Other analogue inputs will have anywhere
|
||||
* within the range.
|
||||
*
|
||||
* @param input The input manager to check against.
|
||||
* @param binding The previously bound input binding.
|
||||
* @return Input state of the axis.
|
||||
*/
|
||||
inputval_t inputGetAxis(input_t *input, inputbind_t binding);
|
||||
|
||||
/**
|
||||
* Returns a raw input value between -1 and 1 between two axis. This would be
|
||||
* indicitive of having an input with an axis that can be moved one direction
|
||||
* for a positive input and another for a negative input, typically a game
|
||||
* controller's analogue sticks.
|
||||
*
|
||||
* @param input The input manager to check against.
|
||||
* @param postitive The positive axis binding.
|
||||
* @param negative The negative axis binding.
|
||||
* @return A float between -1 and 1 representing the result of both.
|
||||
*/
|
||||
float inputGetFullAxis(input_t *input, inputbind_t positive,
|
||||
inputbind_t negative
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the time that an input was actuated at. Actuate would count as a
|
||||
* non-zero input for analogue inputs.
|
||||
*
|
||||
* @param input The input manager to check against.
|
||||
* @param binding The previously bound input binding.
|
||||
* @return Game Engine time that an input was non-zeroed
|
||||
*/
|
||||
float inputGetAccuated(input_t *input, inputbind_t binding);
|
@ -1,31 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Msters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <malloc.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef PLATFORMINPUT_T
|
||||
#define PLATFORMINPUT_T void
|
||||
#endif
|
||||
/** Definition for the platform's input source */
|
||||
typedef PLATFORMINPUT_T platforminput_t;
|
||||
|
||||
/**
|
||||
* Contains information about the running platform. Essentially this is just
|
||||
* some context as to what is running the game engine itself. It's mostly for
|
||||
* metadata purposes but there may be some technical information required for
|
||||
* the engine.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Internal name of the platform */
|
||||
char *name;
|
||||
|
||||
/** Dimensions of the screen (in pixels) */
|
||||
uint32_t screenWidth, screenHeight;
|
||||
|
||||
/** Count of input sources that exist in engine. */
|
||||
uint32_t inputSourceCount;
|
||||
} platform_t;
|
@ -1,57 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <glad/glad.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
|
||||
/**
|
||||
* Structure detailing information about a texture.
|
||||
* Because we plan to upload the pixels of a texture into the GPU, we don't
|
||||
* store the pixels in memory because we don't need to!
|
||||
*/
|
||||
typedef struct {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
GLuint id;
|
||||
} texture_t;
|
||||
|
||||
/** Information about a single pixel. */
|
||||
typedef struct {
|
||||
uint8_t r, g, b, a ;
|
||||
} pixel_t;
|
||||
|
||||
/**
|
||||
* Creates a new texture that can be written in to.
|
||||
*
|
||||
* @param width Width of the texture (in pixels).
|
||||
* @param height Height of the texture (in pixels).
|
||||
* @param pixels Default pixel array, set to NULL to set all pixel data to 0.
|
||||
* @return The newly created texture instance.
|
||||
*/
|
||||
texture_t * textureCreate(int32_t width, int32_t height, pixel_t *pixels);
|
||||
|
||||
/**
|
||||
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so avoid
|
||||
* doing this too often.
|
||||
*
|
||||
* @param texture Texture to buffer in to.
|
||||
* @param x X coordinate in texture space to render to.
|
||||
* @param y Y coordinate in texture space to render to.
|
||||
* @param width Width of the pixel region you're buffering.
|
||||
* @param height Height of the pixel region you're buffering.
|
||||
* @param pixels Array of pixels to buffer onto the GPU.
|
||||
*/
|
||||
void textureBufferPixels(texture_t *texture,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height, pixel_t *pixels
|
||||
);
|
||||
|
||||
/**
|
||||
* Clean a previously created texture.
|
||||
* @param texture Texture to clean up.
|
||||
*/
|
||||
void textureDispose(texture_t *texture);
|
@ -1,138 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Msters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "list.h"
|
||||
|
||||
list_t * listCreate() {
|
||||
list_t *list = malloc(sizeof(list_t));
|
||||
if(list == NULL) return NULL;
|
||||
|
||||
list->start = NULL;
|
||||
list->end = NULL;
|
||||
list->size = 0;
|
||||
return list;
|
||||
}
|
||||
|
||||
listentry_t * listAdd(list_t *list, void *data) {
|
||||
//Create the list entry
|
||||
listentry_t *entry = malloc(sizeof(listentry_t));
|
||||
if(entry == NULL) return NULL;
|
||||
|
||||
entry->data = data;
|
||||
entry->next = NULL;
|
||||
entry->prev = NULL;
|
||||
|
||||
//Add it to the list
|
||||
listAddEntry(list, entry);
|
||||
|
||||
//Return the entry
|
||||
return entry;
|
||||
}
|
||||
|
||||
void listAddEntry(list_t *list, listentry_t *entry) {
|
||||
//Is this the first / only thing in the list?
|
||||
if(list->start == NULL) {
|
||||
list->start = entry;
|
||||
list->end = entry;
|
||||
} else {
|
||||
//Make the end's next be this entry, and this entry's prev the end, then
|
||||
//make this the new end
|
||||
entry->prev = list->end;
|
||||
list->end->next = entry;
|
||||
list->end = entry;
|
||||
}
|
||||
list->size++;
|
||||
}
|
||||
|
||||
void listRemove(list_t *list, void *data) {
|
||||
uint32_t i = 0;
|
||||
listentry_t *previous = list->start;
|
||||
|
||||
while(previous != NULL) {
|
||||
if(previous->data == data) {
|
||||
listRemoveEntry(list, previous, false);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
previous = previous->next;
|
||||
}
|
||||
}
|
||||
|
||||
void listRemoveEntry(list_t *list, listentry_t *entry, bool freeData) {
|
||||
//Update next and prev
|
||||
if(entry->prev != NULL) entry->prev->next = entry->next;
|
||||
if(entry->next != NULL) entry->next->prev = entry->prev;
|
||||
|
||||
//Was this at the end?
|
||||
if(list->start == entry) list->start = entry->next;
|
||||
if(list->end == entry) list->end = entry->prev;
|
||||
|
||||
if(freeData) free(entry->data);
|
||||
free(entry);
|
||||
|
||||
list->size--;
|
||||
}
|
||||
|
||||
|
||||
listentry_t * listGetByIndex(list_t *list, uint32_t index) {
|
||||
if(index >= list->size) return NULL;
|
||||
|
||||
//TODO: We can probably make this more efficient by deciding which way we
|
||||
//should loop from based on the list size.
|
||||
|
||||
uint32_t i = 0;
|
||||
listentry_t *previous = list->start;
|
||||
|
||||
while(previous != NULL) {
|
||||
if(i == index) return previous;
|
||||
i++;
|
||||
previous = previous->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t listGetIndex(list_t *list, void* data) {
|
||||
uint32_t i = 0;
|
||||
listentry_t *previous = list->start;
|
||||
|
||||
while(previous != NULL) {
|
||||
if(previous->data == data) return i;
|
||||
i++;
|
||||
previous = previous->next;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t listGetEntryIndex(list_t *list, listentry_t *entry) {
|
||||
uint32_t i = 0;
|
||||
listentry_t *previous = list->start;
|
||||
|
||||
while(previous != NULL) {
|
||||
if(previous == entry) return i;
|
||||
i++;
|
||||
previous = previous->next;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void listDispose(list_t *list, bool freeData) {
|
||||
//Free all of the entries
|
||||
listentry_t *next = list->start;
|
||||
listentry_t *current;
|
||||
|
||||
while(next != NULL) {
|
||||
current = next;
|
||||
next = current->next;
|
||||
if(freeData) free(current->data);
|
||||
free(current);
|
||||
}
|
||||
|
||||
free(list);
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Msters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <malloc.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Entry within a given linked list.
|
||||
* @param data* The pointer to the data that is within the entry.
|
||||
* @param prev* Pointer to the previous entry in the list.
|
||||
* @param next* Pointer to the next entry in the list.
|
||||
*/
|
||||
typedef struct listentry_t {
|
||||
void *data;
|
||||
struct listentry_t *prev;
|
||||
struct listentry_t *next;
|
||||
} listentry_t;
|
||||
|
||||
/**
|
||||
* Linked List of elements, Doubly Linked.
|
||||
* @param size The count of elements currently within the list
|
||||
* @param start* First element within the list.
|
||||
* @param end* Last element within the list.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t size;
|
||||
listentry_t *start;
|
||||
listentry_t *end;
|
||||
} list_t;
|
||||
|
||||
//Method definitions
|
||||
|
||||
/**
|
||||
* Creates a new linked list
|
||||
* @return Pointer to a new linked list.
|
||||
*/
|
||||
list_t * listCreate();
|
||||
|
||||
/**
|
||||
* Adds data to a linked list
|
||||
*
|
||||
* @param list* Pointer to a previously created linked list
|
||||
* @param data* Pointer to your data
|
||||
* @return A pointer to the new entry in the linked list that was created
|
||||
*/
|
||||
listentry_t * listAdd(list_t *list, void *data);
|
||||
|
||||
/**
|
||||
* Internal function
|
||||
*/
|
||||
void listAddEntry(list_t *list, listentry_t *entry);
|
||||
|
||||
/**
|
||||
* Remove data from a linked list.
|
||||
*
|
||||
* @param list Pointer to a previously created linked list.
|
||||
* @param data* Pointer to your data.
|
||||
*/
|
||||
void listRemove(list_t *list, void *data);
|
||||
|
||||
/**
|
||||
* Remove a list entry from the linked list.
|
||||
*
|
||||
* @param list* Pointer to a previously created linked list.
|
||||
* @param entry* Pointer to the entry within the linked list.
|
||||
* @param freeData If true the data of the listentry_t will be free()'d
|
||||
*/
|
||||
void listRemoveEntry(list_t *list, listentry_t *entry, bool freeData);
|
||||
|
||||
/**
|
||||
* Returns the entry at a given index. This method is costly.
|
||||
* @param list* Pointer to a previously created linked list
|
||||
* @param index Index of element within the linked list to remove
|
||||
* @return The entry at the index or NULL if outside the bounds.
|
||||
*/
|
||||
listentry_t * listGetByIndex(list_t *list, uint32_t index);
|
||||
|
||||
/**
|
||||
* Returns the index of data within the linked list. This method is costly.
|
||||
*
|
||||
* @param list* Pointer to a previously created linked list
|
||||
* @param data* Pointer to your data.
|
||||
* @return The index within the list the entry is in, or -1 if not found.
|
||||
*/
|
||||
uint32_t listGetIndex(list_t *list, void* data);
|
||||
|
||||
/**
|
||||
* Returns the index of an entry within the linked list. This method is costly.
|
||||
*
|
||||
* @param list* Pointer to a previously created linked list
|
||||
* @param entry* Pointer to the entry within the linked list.
|
||||
* @return The index within the list the entry is in, or -1 if not found.
|
||||
*/
|
||||
uint32_t listGetEntryIndex(list_t *list, listentry_t *entry);
|
||||
|
||||
/**
|
||||
* Dispose a previously created link list.
|
||||
* @param list* Pointer to a previously created linked list
|
||||
* @param freeData If true the data within each listentry_t will be free()'d
|
||||
*/
|
||||
void listDispose(list_t *list, bool freeData);
|
@ -1,10 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#define mathMod(a,b) (a%b+b)%b
|
||||
#define mathMax(a,b) (a<b?b:a)
|
||||
#define mathMin(a,b) (a>b?b:a)
|
@ -1,13 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# define strtok_r strtok_s
|
||||
#endif
|
Reference in New Issue
Block a user