Built tileset logic

This commit is contained in:
2021-04-05 13:58:17 +10:00
parent 5c54a10298
commit 932ba9fc6a
12 changed files with 193 additions and 45 deletions

View File

@ -7,7 +7,7 @@
#include "quad.h" #include "quad.h"
void quadBuffer(primitive_t *primitive, void quadBuffer(primitive_t *primitive, float z,
float x0, float y0, float u0, float v0, float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1, float x1, float y1, float u1, float v1,
int32_t verticeStart, int32_t indiceStart int32_t verticeStart, int32_t indiceStart
@ -15,16 +15,16 @@ void quadBuffer(primitive_t *primitive,
vertice_t *vertices = malloc(sizeof(vertice_t) * QUAD_VERTICE_COUNT); vertice_t *vertices = malloc(sizeof(vertice_t) * QUAD_VERTICE_COUNT);
indice_t *indices = malloc(sizeof(indice_t) * QUAD_INDICE_COUNT); indice_t *indices = malloc(sizeof(indice_t) * QUAD_INDICE_COUNT);
vertices[0].x = x0, vertices[0].y = y0, vertices[0].z = 0; vertices[0].x = x0, vertices[0].y = y0, vertices[0].z = z;
vertices[0].u = u0, vertices[0].v = v0; vertices[0].u = u0, vertices[0].v = v0;
vertices[1].x = x1, vertices[1].y = y0, vertices[1].z = 0; vertices[1].x = x1, vertices[1].y = y0, vertices[1].z = z;
vertices[1].u = u1, vertices[1].v = v0; vertices[1].u = u1, vertices[1].v = v0;
vertices[2].x = x0, vertices[2].y = y1, vertices[2].z = 0; vertices[2].x = x0, vertices[2].y = y1, vertices[2].z = z;
vertices[2].u = u0, vertices[2].v = v1; vertices[2].u = u0, vertices[2].v = v1;
vertices[3].x = x1, vertices[3].y = y1, vertices[3].z = 0; vertices[3].x = x1, vertices[3].y = y1, vertices[3].z = z;
vertices[3].u = u1, vertices[3].v = v1; vertices[3].u = u1, vertices[3].v = v1;
indices[0] = (indice_t)(verticeStart + 0); indices[0] = (indice_t)(verticeStart + 0);
@ -42,13 +42,13 @@ void quadBuffer(primitive_t *primitive,
free(indices); free(indices);
} }
primitive_t * quadCreate( primitive_t * quadCreate(float z,
float x0, float y0, float u0, float v0, float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1 float x1, float y1, float u1, float v1
) { ) {
primitive_t *primitive = primitiveCreate(4, 6); primitive_t *primitive = primitiveCreate(4, 6);
quadBuffer(primitive, quadBuffer(primitive, z,
x0, y0, u0, v0, x0, y0, u0, v0,
x1, y1, u1, v1, x1, y1, u1, v1,
0, 0 0, 0

View File

@ -13,6 +13,8 @@
/** /**
* Buffers the vertices of a quad onto a primitive. * 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 x0 The X lower coordinate.
* @param y0 The Y lower coordinate. * @param y0 The Y lower coordinate.
* @param u0 The X lower texture coordinate. * @param u0 The X lower texture coordinate.
@ -24,7 +26,7 @@
* @param verticeStart Start vertice to buffer to. * @param verticeStart Start vertice to buffer to.
* @param indiceStart Start indice to buffer to. * @param indiceStart Start indice to buffer to.
*/ */
void quadBuffer(primitive_t *primitive, void quadBuffer(primitive_t *primitive, float z,
float x0, float y0, float u0, float v0, float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1, float x1, float y1, float u1, float v1,
int32_t verticeStart, int32_t indiceStart int32_t verticeStart, int32_t indiceStart
@ -33,6 +35,7 @@ void quadBuffer(primitive_t *primitive,
/** /**
* Creates a new quad primitive. * Creates a new quad primitive.
* *
* @param z The Z axis coordinate of the quad.
* @param x0 The X lower coordinate. * @param x0 The X lower coordinate.
* @param y0 The Y lower coordinate. * @param y0 The Y lower coordinate.
* @param u0 The X lower texture coordinate. * @param u0 The X lower texture coordinate.
@ -43,7 +46,7 @@ void quadBuffer(primitive_t *primitive,
* @param v1 The Y higher texture coordinate. * @param v1 The Y higher texture coordinate.
* @return The quad primitive. * @return The quad primitive.
*/ */
primitive_t * quadCreate( primitive_t * quadCreate(float z,
float x0, float y0, float u0, float v0, float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1 float x1, float y1, float u1, float v1
); );

View File

@ -26,16 +26,16 @@ spritebatch_t * spriteBatchCreate(int32_t maxSprites) {
} }
void spriteBatchQuad(spritebatch_t *spriteBatch, int32_t index, void spriteBatchQuad(spritebatch_t *spriteBatch, int32_t index,
float x, float y, float width, float height, float x, float y, float z, float width, float height,
float u0, float v0, float u1, float v1 float u0, float v0, float u1, float v1
) { ) {
if(index == -1) { if(index == -1) {
index = spriteBatch->currentSprite++; index = spriteBatch->currentSprite++;
} else { } else {
spriteBatch->currentSprite = max(index, spriteBatch->currentSprite); spriteBatch->currentSprite = mathMax(index, spriteBatch->currentSprite);
} }
quadBuffer(spriteBatch->primitive, quadBuffer(spriteBatch->primitive, z,
x, y, u0, v0, x, y, u0, v0,
x+width, y+height, u1, v1, x+width, y+height, u1, v1,
index*QUAD_VERTICE_COUNT, index*QUAD_INDICE_COUNT index*QUAD_VERTICE_COUNT, index*QUAD_INDICE_COUNT
@ -54,6 +54,6 @@ void spriteBatchDraw(spritebatch_t *spriteBatch, int32_t index, int32_t count) {
} }
void spriteBatchDispose(spritebatch_t *spriteBatch) { void spriteBatchDispose(spritebatch_t *spriteBatch) {
primitiveDispose(spriteBatch); primitiveDispose(spriteBatch->primitive);
free(spriteBatch); free(spriteBatch);
} }

View File

@ -43,7 +43,7 @@ spritebatch_t * spriteBatchCreate(int32_t maxSprites);
* @param v1 Texture V coordinate (max). * @param v1 Texture V coordinate (max).
*/ */
void spriteBatchQuad(spritebatch_t *spriteBatch, int32_t index, void spriteBatchQuad(spritebatch_t *spriteBatch, int32_t index,
float x, float y, float width, float height, float x, float y, float z, float width, float height,
float u0, float v0, float u1, float v1 float u0, float v0, float u1, float v1
); );

View File

@ -0,0 +1,68 @@
/**
* 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 gapX, int32_t gapY,
int32_t borderX, int32_t borderY,
int32_t width, int32_t height
) {
tileset_t *tileset;
float divX, divY, tdivX;
int32_t x, y, i, j, count;
tileset = malloc(sizeof(tileset_t));
if(tileset == NULL) return NULL;
count = rows * columns;
tileset->divisions = malloc(sizeof(tilesetdiv_t) * 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);
}

View File

@ -0,0 +1,62 @@
// 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;
/** 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 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.
* @param width Width of the tileset.
* @param height Height of the tileset.
* @returns The tileset.
*/
tileset_t * tilesetCreate(
int32_t columns, int32_t rows,
int32_t gapX, int32_t gapY,
int32_t borderX, int32_t borderY,
int32_t width, int32_t height
);
/**
* 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);

View File

@ -12,6 +12,8 @@ shader_t *shader;
world_t *world; world_t *world;
spritebatch_t *batch; spritebatch_t *batch;
int i;
engine_t * engineInit(platform_t *platform, char *name, uint32_t inputCount) { engine_t * engineInit(platform_t *platform, char *name, uint32_t inputCount) {
// Create the engine instance. // Create the engine instance.
engine_t *engine = malloc(sizeof(engine_t)); engine_t *engine = malloc(sizeof(engine_t));
@ -38,13 +40,14 @@ engine_t * engineInit(platform_t *platform, char *name, uint32_t inputCount) {
shader = assetShaderLoad("shaders/test.vert", "shaders/test.frag"); shader = assetShaderLoad("shaders/test.vert", "shaders/test.frag");
camera = cameraCreate(); camera = cameraCreate();
cameraLookAt(camera, cameraLookAt(camera,
5, 5, 5, 30, 30, 30,
0, 0, 0 0, 0, 0
); );
cameraPerspective(camera, 45.0f, 1920.0f/1080.0f, 0.5f, 100.0f); cameraPerspective(camera, 45.0f, 1920.0f/1080.0f, 0.5f, 100.0f);
shaderUseCamera(shader, camera); shaderUseCamera(shader, camera);
world = worldCreate(); world = worldCreate();
i = 0;
return engine; return engine;
} }
@ -55,6 +58,10 @@ uint32_t engineUpdate(engine_t *engine) {
worldRender(world, shader); worldRender(world, shader);
if((++i % 10000) == 0) {
chunkListShift(world->chunkList, 0, 0, 1);
}
inputUpdate(engine->input); inputUpdate(engine->input);
return 0; return 0;
} }

View File

@ -5,6 +5,6 @@
#pragma once #pragma once
#define mod(a,b) (a%b+b)%b #define mathMod(a,b) (a%b+b)%b
#define max(a,b) (a<b?b:a) #define mathMax(a,b) (a<b?b:a)
#define min(a,b) (a>b?b:a) #define mathMin(a,b) (a>b?b:a)

View File

@ -8,38 +8,39 @@
#include "chunk.h" #include "chunk.h"
void chunkCreate(chunk_t *chunk) { void chunkCreate(chunk_t *chunk) {
int32_t count, x, y, z, i; int32_t count, x, y, i;
count = CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH; count = CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH;
chunk->primitive = primitiveCreate(count * 4, count * 6); chunk->batch = spriteBatchCreate(count);
chunk->tiles = malloc(sizeof(tile_t) * count);
i = 0;
for(z = 0; z < CHUNK_DEPTH; z++) {
for(y = 0; y < CHUNK_HEIGHT; y++) {
for(x = 0; x < CHUNK_WIDTH; x++) {
quadBuffer(chunk->primitive,
x, y, 0, 0,
x+1, y+1, 1, 1,
i*4, i*6
);
i++;
}
}
}
} }
void chunkRender(chunk_t *chunk, shader_t *shader) { void chunkRender(chunk_t *chunk, shader_t *shader) {
// Coordinates of the chunk.
float x, y, z; float x, y, z;
x = (chunk->x * CHUNK_WIDTH); x = (chunk->x * CHUNK_WIDTH);
y = (chunk->y * CHUNK_HEIGHT); y = (chunk->y * CHUNK_HEIGHT);
z = (chunk->z * CHUNK_DEPTH); z = (chunk->z * CHUNK_DEPTH);
shaderUsePosition(shader, x*2, y*2, z*2, 0, 0, 0); // Render the batch.
primitiveDraw(chunk->primitive, 0, chunk->primitive->indiceCount); shaderUsePosition(shader, x, y, z, 0, 0, 0);
spriteBatchDraw(chunk->batch, 0, -1);
} }
void chunkLoad(chunk_t *chunk, int32_t x, int32_t y, int32_t z) { void chunkLoad(chunk_t *chunk, int32_t x, int32_t y, int32_t z) {
int32_t tx, ty, tz;
spriteBatchFlush(chunk->batch);
// for(tx = 0; tx < CHUNK_WIDTH; tx++) {
// for(ty = 0; ty < CHUNK_HEIGHT; ty++) {
// for(tz = 0; tz < CHUNK_DEPTH; tz++) {
// spriteBatchQuad(chunk->batch, -1,
// x, y, z, 1, 1, 0, 0, 1, 1
// );
// }
// }
// }
} }
void chunkUnload(chunk_t *chunk) { void chunkUnload(chunk_t *chunk) {

View File

@ -7,7 +7,7 @@
#include <stdint.h> #include <stdint.h>
#include "../display/primitive.h" #include "../display/primitive.h"
#include "../display/shader.h" #include "../display/shader.h"
#include "../display/primitives/quad.h" #include "../display/spritebatch.h"
#define CHUNK_WIDTH 3 #define CHUNK_WIDTH 3
#define CHUNK_HEIGHT CHUNK_WIDTH #define CHUNK_HEIGHT CHUNK_WIDTH
@ -16,9 +16,14 @@
typedef uint8_t tile_t; typedef uint8_t tile_t;
typedef struct { typedef struct {
/** Absolute X Y Z chunklist coordinates */
int32_t x, y, z; int32_t x, y, z;
/** Tiles within the chunk */
tile_t *tiles; tile_t *tiles;
primitive_t *primitive;
/** Sprite Batch for holding static tiles */
spritebatch_t *batch;
} chunk_t; } chunk_t;
@ -29,8 +34,6 @@ typedef struct {
*/ */
void chunkCreate(chunk_t *chunk); void chunkCreate(chunk_t *chunk);
void chunkRender(chunk_t *chunk, shader_t *shader);
/** /**
* Loads a given chunk into the memory specified. * Loads a given chunk into the memory specified.
* *
@ -46,4 +49,8 @@ void chunkLoad(chunk_t *chunk, int32_t x, int32_t y, int32_t z);
* *
* @param chunk Chunk to unload. * @param chunk Chunk to unload.
*/ */
void chunkUnload(chunk_t *chunk); void chunkUnload(chunk_t *chunk);
void chunkRender(chunk_t *chunk, shader_t *shader);

View File

@ -90,9 +90,9 @@ void chunkListShift(chunklist_t *list, int32_t x, int32_t y, int32_t z) {
chunk = list->chunkList[i]; chunk = list->chunkList[i];
// Calculate the new local positions for the chunk. // Calculate the new local positions for the chunk.
nx = mod(chunk->x - list->x - x, list->width); nx = mathMod(chunk->x - list->x - x, list->width);
ny = mod(chunk->y - list->y - y, list->height); ny = mathMod(chunk->y - list->y - y, list->height);
nz = mod(chunk->z - list->z - z, list->depth); nz = mathMod(chunk->z - list->z - z, list->depth);
// Load the chunk if we need to. We also use this to calculate new absolutes // Load the chunk if we need to. We also use this to calculate new absolutes
if( if(

View File

@ -11,7 +11,7 @@ world_t * worldCreate() {
world_t *world = malloc(sizeof(world_t)); world_t *world = malloc(sizeof(world_t));
if(world == NULL) return NULL; if(world == NULL) return NULL;
world->chunkList = chunkListCreate(3, 3, 1); world->chunkList = chunkListCreate(3, 3, 3);
if(world->chunkList == NULL) { if(world->chunkList == NULL) {
free(world); free(world);
return NULL; return NULL;