Tilesets working.
This commit is contained in:
BIN
assets/textures/8x8.png
Normal file
BIN
assets/textures/8x8.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB |
@ -11,7 +11,7 @@ tileset_t TILESETS[TILESET_COUNT] = {
|
||||
// TILESET_NULL
|
||||
{ 0, 0 },
|
||||
// TILESET_FONT
|
||||
{ 4, 4 }
|
||||
{ 1, 88 }
|
||||
};
|
||||
|
||||
tilesetid_t TILESET_SLOTS[TILESET_SLOT_COUNT] = {
|
||||
|
@ -10,7 +10,7 @@
|
||||
#define TILESET_SLOT_2 2
|
||||
#define TILESET_SLOT_3 3
|
||||
|
||||
#define TILESET_SLOT_ENTITIES TILESET_SLOT_0
|
||||
#define TILESET_SLOT_MAP TILESET_SLOT_1
|
||||
#define TILESET_SLOT_ENTITIES TILESET_SLOT_1
|
||||
#define TILESET_SLOT_MAP TILESET_SLOT_2
|
||||
|
||||
#define TILESET_SLOT_COUNT 4
|
@ -30,4 +30,4 @@ add_subdirectory(display)
|
||||
add_subdirectory(overworld)
|
||||
|
||||
# Assets
|
||||
copytool("textures/bolder-8x8.png")
|
||||
copytool("textures/8x8.png")
|
@ -4,12 +4,10 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "../../../../dusk/display/tilesetdefs.h"
|
||||
#include "../fragments/packed.glsl"
|
||||
|
||||
struct Tileset {
|
||||
int columns;
|
||||
int rows;
|
||||
int width;
|
||||
int height;
|
||||
uvec4 tileset;
|
||||
};
|
||||
|
||||
layout(std140) uniform b_Tilesets {
|
||||
@ -18,31 +16,47 @@ layout(std140) uniform b_Tilesets {
|
||||
|
||||
uniform sampler2D u_TilesetTextures[TILESET_SLOT_COUNT];
|
||||
|
||||
vec4 tilesetGetUVs(int tilesetIndex, int col, int row) {
|
||||
uint tilesetGetColumns(uint tilesetIndex) {
|
||||
return packedGetU32(0u, tilesets[tilesetIndex].tileset);
|
||||
}
|
||||
|
||||
uint tilesetGetRows(uint tilesetIndex) {
|
||||
return packedGetU32(1u, tilesets[tilesetIndex].tileset);
|
||||
}
|
||||
|
||||
uint tilesetGetWidth(uint tilesetIndex) {
|
||||
return packedGetU32(2u, tilesets[tilesetIndex].tileset);
|
||||
}
|
||||
|
||||
uint tilesetGetHeight(uint tilesetIndex) {
|
||||
return packedGetU32(3u, tilesets[tilesetIndex].tileset);
|
||||
}
|
||||
|
||||
vec4 tilesetGetUVs(uint tilesetIndex, uint col, uint row) {
|
||||
Tileset tileset = tilesets[tilesetIndex];
|
||||
float segWidth = 1.0 / float(tileset.columns);
|
||||
float segHeight = 1.0 / float(tileset.rows);
|
||||
float segWidth = 1.0 / float(tilesetGetColumns(tilesetIndex));
|
||||
float segHeight = 1.0 / float(tilesetGetRows(tilesetIndex));
|
||||
float x = float(col) * segWidth;
|
||||
float y = float(row) * segHeight;
|
||||
return vec4(x, y, x + segWidth, y + segHeight);
|
||||
}
|
||||
|
||||
vec4 tilesetGetUVsByIndex(int tilesetIndex, int index) {
|
||||
vec4 tilesetGetUVsByIndex(uint tilesetIndex, uint index) {
|
||||
Tileset tileset = tilesets[tilesetIndex];
|
||||
int col = index % tileset.columns;
|
||||
int row = index / tileset.columns;
|
||||
uint col = index % tilesetGetColumns(tilesetIndex);
|
||||
uint row = index / tilesetGetColumns(tilesetIndex);
|
||||
return tilesetGetUVs(tilesetIndex, col, row);
|
||||
}
|
||||
|
||||
vec4 tilesetGetColor(int tilesetIndex, vec2 coord) {
|
||||
vec4 tilesetGetColor(uint tilesetIndex, vec2 coord) {
|
||||
switch(tilesetIndex) {
|
||||
case 0:
|
||||
case 0u:
|
||||
return texture(u_TilesetTextures[0], coord);
|
||||
case 1:
|
||||
case 1u:
|
||||
return texture(u_TilesetTextures[1], coord);
|
||||
case 2:
|
||||
case 2u:
|
||||
return texture(u_TilesetTextures[2], coord);
|
||||
case 3:
|
||||
case 3u:
|
||||
return texture(u_TilesetTextures[3], coord);
|
||||
default:
|
||||
return vec4(1, 1, 1, 1);
|
||||
|
@ -8,33 +8,50 @@
|
||||
#include "tilesetshaderdata.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
#include "display/shader/shader.h"
|
||||
|
||||
shaderbuffer_t TILESET_SHADER_DATA_BUFFER;
|
||||
tilesetshaderdata_t TILESET_SHADER_DATA_DATA;
|
||||
GLuint TILESET_SHADER_DATA_TEXTURES[TILESET_SLOT_COUNT];
|
||||
|
||||
void tilesetShaderDataInit() {
|
||||
memoryZero(&TILESET_SHADER_DATA_DATA, sizeof(tilesetshaderdata_t));
|
||||
shaderBufferInit(&TILESET_SHADER_DATA_BUFFER, sizeof(tilesetshaderdata_t));
|
||||
|
||||
assertTrue(
|
||||
sizeof(tilesetshaderdata_t) == sizeof(uvec4_t) * TILESET_SLOT_COUNT,
|
||||
"Tileset Shader Data size mismatch"
|
||||
);
|
||||
|
||||
uint8_t i = 0;
|
||||
do {
|
||||
TILESET_SHADER_DATA_TEXTURES[i] = i;
|
||||
} while(++i < TILESET_SLOT_COUNT);
|
||||
}
|
||||
|
||||
void tilesetShaderDataUpdate() {
|
||||
uint8_t i = 0;
|
||||
do {
|
||||
if(TILESET_SLOTS[i] == TILESET_NULL) continue;
|
||||
tileset_t *tileset = &TILESETS[TILESET_SLOTS[i]];
|
||||
texture_t *texture = &TILESET_GL_TEXTURES[TILESET_SLOTS[i]];
|
||||
tilesetid_t id = TILESET_SLOTS[i];
|
||||
if(id == TILESET_NULL) continue;
|
||||
tileset_t *tileset = &TILESETS[id];
|
||||
texture_t *texture = &TILESET_GL_TEXTURES[i];
|
||||
tilesetshaderdatatileset_t *dest = &TILESET_SHADER_DATA_DATA.tilesets[i];
|
||||
|
||||
dest->columns = tileset->columns;
|
||||
dest->rows = tileset->rows;
|
||||
dest->width = texture->width;
|
||||
dest->height = texture->height;
|
||||
} while(++i < TILESET_COUNT);
|
||||
} while(++i < TILESET_SLOT_COUNT);
|
||||
|
||||
shaderBufferBind(&TILESET_SHADER_DATA_BUFFER);
|
||||
shaderBufferSetData(&TILESET_SHADER_DATA_BUFFER, &TILESET_SHADER_DATA_DATA);
|
||||
}
|
||||
|
||||
void tilesetShaderTexturesBind(const GLuint uniform) {
|
||||
shaderSetTextures(uniform, TILESET_SHADER_DATA_TEXTURES, TILESET_SLOT_COUNT);
|
||||
}
|
||||
|
||||
void tilesetShaderDataDispose() {
|
||||
shaderBufferDispose(&TILESET_SHADER_DATA_BUFFER);
|
||||
}
|
@ -9,22 +9,23 @@
|
||||
#include "display/shader/shaderbuffer.h"
|
||||
#include "display/tilesetgl.h"
|
||||
|
||||
#define TILESET_BLOCK_NAME "b_Tileset"
|
||||
#define TILESET_SHADER_DATA_BLOCK_NAME "b_Tilesets"
|
||||
#define TILESET_UNIFORM_TEXTURES_NAME "u_TilesetTextures"
|
||||
|
||||
typedef struct {
|
||||
int32_t columns;
|
||||
int32_t rows;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
uint32_t columns;
|
||||
uint32_t rows;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} tilesetshaderdatatileset_t;
|
||||
|
||||
typedef struct {
|
||||
tilesetshaderdatatileset_t tilesets[TILESET_COUNT];
|
||||
tilesetshaderdatatileset_t tilesets[TILESET_SLOT_COUNT];
|
||||
} tilesetshaderdata_t;
|
||||
|
||||
extern shaderbuffer_t TILESET_SHADER_DATA_BUFFER;
|
||||
extern tilesetshaderdata_t TILESET_SHADER_DATA_DATA;
|
||||
extern GLuint TILESET_SHADER_DATA_TEXTURES[];
|
||||
|
||||
/**
|
||||
* Initializes the tileset buffer and data.
|
||||
@ -36,6 +37,13 @@ void tilesetShaderDataInit();
|
||||
*/
|
||||
void tilesetShaderDataUpdate();
|
||||
|
||||
/**
|
||||
* Binds the tileset textures to the given uniform.
|
||||
*
|
||||
* @param uniform The uniform to bind the textures to.
|
||||
*/
|
||||
void tilesetShaderTexturesBind(const GLuint uniform);
|
||||
|
||||
/**
|
||||
* Destroys the tileset buffer.
|
||||
*/
|
||||
|
@ -14,6 +14,6 @@ in vec2 v_TextureCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
vec4 tColor = tilesetGetColor(0, v_TextureCoord);
|
||||
vec4 tColor = tilesetGetColor(uint(TILESET_SLOT_ENTITIES), v_TextureCoord);
|
||||
FragColor = vec4(1, 1, 1, 1) * tColor;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "../fragments/header.glsl"
|
||||
#include "../data/transforms.glsl"
|
||||
#include "../data/entities.glsl"
|
||||
#include "../data/tilesets.glsl"
|
||||
|
||||
// Outputs to fragment shader
|
||||
out vec2 v_TextureCoord;
|
||||
@ -14,8 +15,10 @@ void main() {
|
||||
uint instanceIndex = uint(gl_InstanceID);
|
||||
uint indiceIndex = quadGetIndiceIndex(gl_VertexID);
|
||||
|
||||
vec4 tilesetUVs = tilesetGetUVsByIndex(uint(TILESET_SLOT_ENTITIES), 1u);
|
||||
|
||||
vec2 vert = entityGetVertice(instanceIndex, indiceIndex);
|
||||
vec2 uv = quadGetTextureCoordinate(indiceIndex);
|
||||
vec2 uv = quadGetTextureCoordinate(indiceIndex, tilesetUVs);
|
||||
|
||||
gl_Position = transforms.projection * transforms.view * vec4(vert, 0.0, 1.0);
|
||||
v_TextureCoord = uv;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "entity_frag.glsl.h"
|
||||
#include "display/shader/data/transforms.h"
|
||||
#include "display/shader/data/entities.h"
|
||||
#include "display/shader/data/tilesetshaderdata.h"
|
||||
|
||||
entityshader_t ENTITY_SHADER;
|
||||
|
||||
@ -36,13 +37,26 @@ void entityShaderInit() {
|
||||
ENTITIES_BLOCK_NAME
|
||||
);
|
||||
|
||||
ENTITY_SHADER.tilesetsBlock = shaderGetBlock(
|
||||
&ENTITY_SHADER.shader,
|
||||
TILESET_SHADER_DATA_BLOCK_NAME
|
||||
);
|
||||
|
||||
// Uniforms
|
||||
ENTITY_SHADER.tilesetTexturesUniform = shaderGetUniform(
|
||||
&ENTITY_SHADER.shader,
|
||||
TILESET_UNIFORM_TEXTURES_NAME
|
||||
);
|
||||
}
|
||||
|
||||
void entityShaderUse() {
|
||||
shaderUse(&ENTITY_SHADER.shader);
|
||||
shaderBufferBindToBlock(&TRANSFORMS_BUFFER, ENTITY_SHADER.transformsBlock);
|
||||
shaderBufferBindToBlock(&ENTITIES_BUFFER, ENTITY_SHADER.entitiesBlock);
|
||||
shaderBufferBindToBlock(
|
||||
&TILESET_SHADER_DATA_BUFFER, ENTITY_SHADER.tilesetsBlock
|
||||
);
|
||||
tilesetShaderTexturesBind(ENTITY_SHADER.tilesetTexturesUniform);
|
||||
}
|
||||
|
||||
void entityShaderDispose() {
|
||||
|
@ -10,8 +10,12 @@
|
||||
|
||||
typedef struct {
|
||||
shader_t shader;
|
||||
|
||||
GLuint entitiesBlock;
|
||||
GLuint transformsBlock;
|
||||
GLuint tilesetsBlock;
|
||||
|
||||
GLuint tilesetTexturesUniform;
|
||||
} entityshader_t;
|
||||
|
||||
extern entityshader_t ENTITY_SHADER;
|
||||
|
@ -11,6 +11,10 @@ uint packedGetU8(uint position, uvec4 data) {
|
||||
return (subData >> (position * 8u)) & 0xFFu;
|
||||
}
|
||||
|
||||
uint packedGetU32(uint position, uvec4 data) {
|
||||
return data[position];
|
||||
}
|
||||
|
||||
int packedGetI8(uint position, uvec4 data) {
|
||||
uint subData = data[position / 4u];
|
||||
|
||||
|
@ -14,9 +14,9 @@ uint quadGetIndiceIndex(int vertexId) {
|
||||
vec2 quadGetVertice(uint indiceIndex) {
|
||||
vec2 vert = vec2(0, 0);
|
||||
|
||||
if(indiceIndex == 0u || indiceIndex == 4u) {
|
||||
/*if(indiceIndex == 0u || indiceIndex == 4u) {
|
||||
// vert = vec2(0, 0);
|
||||
} else if(indiceIndex == 1u) {
|
||||
} else*/ if(indiceIndex == 1u) {
|
||||
vert = vec2(1, 0);
|
||||
} else if(indiceIndex == 2u || indiceIndex == 5u) {
|
||||
vert = vec2(1, 1);
|
||||
@ -31,3 +31,9 @@ vec2 quadGetTextureCoordinate(uint indiceIndex) {
|
||||
vec2 vert = quadGetVertice(indiceIndex);
|
||||
return vert;
|
||||
}
|
||||
|
||||
vec2 quadGetTextureCoordinate(uint indiceIndex, vec4 uv) {
|
||||
vec2 vert = quadGetVertice(indiceIndex);
|
||||
vert.y = 1.0 - vert.y;
|
||||
return vec2(uv.x + (uv.z - uv.x) * vert.x, uv.y + (uv.w - uv.y) * vert.y);
|
||||
}
|
@ -120,6 +120,18 @@ GLuint shaderGetBlock(const shader_t *shader, const char *name) {
|
||||
return blockIndex;
|
||||
}
|
||||
|
||||
void shaderSetTextures(
|
||||
const GLuint uniform,
|
||||
const GLuint *textures,
|
||||
const uint8_t count
|
||||
) {
|
||||
assertNotNull(textures, "textures must not be NULL");
|
||||
assertTrue(count > 0, "count must be greater than 0");
|
||||
|
||||
glUniform1iv(uniform, count, textures);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void shaderDispose(shader_t *shader) {
|
||||
assertNotNull(shader, "shader must not be NULL");
|
||||
|
||||
|
@ -54,6 +54,19 @@ GLuint shaderGetUniform(const shader_t *shader, const char_t *name);
|
||||
*/
|
||||
GLuint shaderGetBlock(const shader_t *shader, const char_t *name);
|
||||
|
||||
/**
|
||||
* Sets texture uniforms to a shader.
|
||||
*
|
||||
* @param uniform The uniform to set.
|
||||
* @param textures The textures to set.
|
||||
* @param count The number of textures to set.
|
||||
*/
|
||||
void shaderSetTextures(
|
||||
const GLuint uniform,
|
||||
const GLuint *textures,
|
||||
const uint8_t count
|
||||
);
|
||||
|
||||
/**
|
||||
* Disposes of a shader.
|
||||
*
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
const char* TILESET_GL_TEXTURES_PATHS[TILESET_COUNT] = {
|
||||
NULL,
|
||||
"textures/bolder-8x8.png"
|
||||
"textures/8x8.png"
|
||||
};
|
||||
|
||||
texture_t TILESET_GL_TEXTURES[TILESET_SLOT_COUNT];
|
||||
|
Reference in New Issue
Block a user