library: lots of API additions and improvement

This commit is contained in:
Adam
2024-02-20 23:47:28 +00:00
parent 83d0960cf0
commit cf54f74efa
5 changed files with 213 additions and 21 deletions

View File

@@ -1,6 +1,8 @@
#include "gl.h"
#include "plugin.h"
#include "rwlock.h"
#include <math.h>
#include <stdio.h>
#include <string.h>
@@ -156,7 +158,7 @@ uint8_t _bolt_get_attr_binding(struct GLContext* c, const struct GLAttrBinding*
return 1;
}
uint8_t _bolt_get_attr_binding_int(struct GLContext* c, const struct GLAttrBinding* binding, size_t index, size_t num_out, uint32_t* out) {
uint8_t _bolt_get_attr_binding_int(struct GLContext* c, const struct GLAttrBinding* binding, size_t index, size_t num_out, int32_t* out) {
struct GLArrayBuffer* buffer = binding->buffer;
if (!buffer || !buffer->data) return 0;
uintptr_t buf_offset = binding->offset + (binding->stride * index);
@@ -165,22 +167,22 @@ uint8_t _bolt_get_attr_binding_int(struct GLContext* c, const struct GLAttrBindi
if (!binding->normalise) {
switch (binding->type) {
case GL_UNSIGNED_BYTE:
for (size_t i = 0; i < num_out; i += 1) out[i] = (uint32_t)*(uint8_t*)(ptr + i);
for (size_t i = 0; i < num_out; i += 1) out[i] = (int32_t)*(uint8_t*)(ptr + i);
break;
case GL_UNSIGNED_SHORT:
for (size_t i = 0; i < num_out; i += 1) out[i] = (uint32_t)*(uint16_t*)(ptr + (i * 2));
for (size_t i = 0; i < num_out; i += 1) out[i] = (int32_t)*(uint16_t*)(ptr + (i * 2));
break;
case GL_UNSIGNED_INT:
for (size_t i = 0; i < num_out; i += 1) out[i] = (uint32_t)*(uint32_t*)(ptr + (i * 4));
for (size_t i = 0; i < num_out; i += 1) out[i] = (int32_t)*(uint32_t*)(ptr + (i * 4));
break;
case GL_BYTE:
for (size_t i = 0; i < num_out; i += 1) out[i] = (uint32_t)*(int8_t*)(ptr + i);
for (size_t i = 0; i < num_out; i += 1) out[i] = (int32_t)*(int8_t*)(ptr + i);
break;
case GL_SHORT:
for (size_t i = 0; i < num_out; i += 1) out[i] = (uint32_t)*(int16_t*)(ptr + (i * 2));
for (size_t i = 0; i < num_out; i += 1) out[i] = (int32_t)*(int16_t*)(ptr + (i * 2));
break;
case GL_INT:
for (size_t i = 0; i < num_out; i += 1) out[i] = (uint32_t)*(int32_t*)(ptr + (i * 4));
for (size_t i = 0; i < num_out; i += 1) out[i] = (int32_t)*(int32_t*)(ptr + (i * 4));
break;
default:
return 0;
@@ -314,10 +316,56 @@ struct GLVertexArray* _bolt_context_get_vao(struct GLContext* c, unsigned int in
return ret;
}
void _bolt_mul_vec4_mat4(const float x, const float y, const float z, const float w, const float* mat4, float* out_vec4) {
out_vec4[0] = (mat4[0] * x) + (mat4[4] * y) + (mat4[8] * z) + (mat4[12] * w);
out_vec4[1] = (mat4[1] * x) + (mat4[5] * y) + (mat4[9] * z) + (mat4[13] * w);
out_vec4[2] = (mat4[2] * x) + (mat4[6] * y) + (mat4[10] * z) + (mat4[14] * w);
out_vec4[3] = (mat4[3] * x) + (mat4[7] * y) + (mat4[11] * z) + (mat4[15] * w);
void _bolt_gl_plugin_drawelements_xy(const struct RenderBatch2D* batch, size_t index, void* userdata, int32_t* out) {
struct GLPluginDrawElementsUserData* data = userdata;
if (!_bolt_get_attr_binding_int(data->c, data->position, index, 2, out)) {
float pos[2];
_bolt_get_attr_binding(data->c, data->position, index, 2, pos);
out[0] = (int32_t)roundf(pos[0]);
out[1] = (int32_t)roundf(pos[1]);
}
}
void _bolt_gl_plugin_drawelements_atlas_xy(const struct RenderBatch2D* batch, size_t index, void* userdata, int32_t* out) {
struct GLPluginDrawElementsUserData* data = userdata;
float xy[2];
_bolt_get_attr_binding(data->c, data->atlas_min, index, 2, xy);
// these are negative for some reason
out[0] = -(int32_t)roundf(xy[0] * data->atlas->width);
out[1] = -(int32_t)roundf(xy[1] * data->atlas->height);
}
void _bolt_gl_plugin_drawelements_atlas_wh(const struct RenderBatch2D* batch, size_t index, void* userdata, int32_t* out) {
struct GLPluginDrawElementsUserData* data = userdata;
float wh[2];
_bolt_get_attr_binding(data->c, data->atlas_size, index, 2, wh);
// these are negative for some reason
out[0] = -(int32_t)roundf(wh[0] * data->atlas->width);
out[1] = -(int32_t)roundf(wh[1] * data->atlas->height);
}
void _bolt_gl_plugin_drawelements_uv(const struct RenderBatch2D* batch, size_t index, void* userdata, double* out) {
struct GLPluginDrawElementsUserData* data = userdata;
float uv[2];
_bolt_get_attr_binding(data->c, data->tex_uv, index, 2, uv);
out[0] = (double)uv[0];
out[1] = (double)uv[1];
}
void _bolt_gl_plugin_drawelements_colour(const struct RenderBatch2D* batch, size_t index, void* userdata, double* out) {
struct GLPluginDrawElementsUserData* data = userdata;
float colour[4];
_bolt_get_attr_binding(data->c, data->colour, index, 4, colour);
// these are ABGR for some reason
out[0] = (double)colour[3];
out[1] = (double)colour[2];
out[2] = (double)colour[1];
out[3] = (double)colour[0];
}
//void _bolt_mul_vec4_mat4(const float x, const float y, const float z, const float w, const float* mat4, float* out_vec4) {
// out_vec4[0] = (mat4[0] * x) + (mat4[4] * y) + (mat4[8] * z) + (mat4[12] * w);
// out_vec4[1] = (mat4[1] * x) + (mat4[5] * y) + (mat4[9] * z) + (mat4[13] * w);
// out_vec4[2] = (mat4[2] * x) + (mat4[6] * y) + (mat4[10] * z) + (mat4[14] * w);
// out_vec4[3] = (mat4[3] * x) + (mat4[7] * y) + (mat4[11] * z) + (mat4[15] * w);
//}

View File

@@ -7,6 +7,7 @@
#include "../../modules/hashmap/hashmap.h"
#include "rwlock.h"
struct hashmap;
struct RenderBatch2D;
/* consts used from libgl */
#define GL_TEXTURE 5890
@@ -146,9 +147,26 @@ void _bolt_make_context_current(void*);
void _bolt_destroy_context(void*);
void _bolt_set_attr_binding(struct GLContext*, struct GLAttrBinding*, unsigned int, int, const void*, unsigned int, uint32_t, uint8_t);
uint8_t _bolt_get_attr_binding(struct GLContext*, const struct GLAttrBinding*, size_t, size_t, float*);
uint8_t _bolt_get_attr_binding_int(struct GLContext*, const struct GLAttrBinding*, size_t, size_t, uint32_t*);
uint8_t _bolt_get_attr_binding_int(struct GLContext*, const struct GLAttrBinding*, size_t, size_t, int32_t*);
uint32_t _bolt_binding_for_buffer(uint32_t);
void _bolt_mul_vec4_mat4(const float x, const float y, const float z, const float w, const float* mat4, float* out_vec4);
/* plugin library interop stuff */
struct GLPluginDrawElementsUserData {
struct GLContext* c;
unsigned short* indices;
struct GLTexture2D* atlas;
struct GLAttrBinding* position;
struct GLAttrBinding* atlas_min;
struct GLAttrBinding* atlas_size;
struct GLAttrBinding* tex_uv;
struct GLAttrBinding* colour;
};
void _bolt_gl_plugin_drawelements_xy(const struct RenderBatch2D*, size_t index, void* userdata, int32_t* out);
void _bolt_gl_plugin_drawelements_atlas_xy(const struct RenderBatch2D*, size_t index, void* userdata, int32_t* out);
void _bolt_gl_plugin_drawelements_atlas_wh(const struct RenderBatch2D*, size_t index, void* userdata, int32_t* out);
void _bolt_gl_plugin_drawelements_uv(const struct RenderBatch2D*, size_t index, void* userdata, double* out);
void _bolt_gl_plugin_drawelements_colour(const struct RenderBatch2D*, size_t index, void* userdata, double* out);
#endif

View File

@@ -45,9 +45,19 @@ void _bolt_plugin_init() {
lua_pushstring(state, BATCH2D_META_REGISTRYNAME);
lua_newtable(state);
lua_pushstring(state, "__index");
lua_newtable(state);
lua_createtable(state, 0, 8);
API_ADD_SUB(vertexcount, batch2d)
API_ADD_SUB(verticesperimage, batch2d)
API_ADD_SUB(vertexxy, batch2d)
API_ADD_SUB(vertexatlasxy, batch2d)
API_ADD_SUB(vertexatlaswh, batch2d)
API_ADD_SUB(vertexuv, batch2d)
API_ADD_SUB(vertexcolour, batch2d)
lua_pushstring(state, "vertexcolor");
lua_pushcfunction(state, api_batch2d_vertexcolour);
lua_settable(state, -3);
lua_settable(state, -3);
lua_settable(state, LUA_REGISTRYINDEX);
@@ -86,7 +96,12 @@ void _bolt_plugin_close() {
uint64_t _bolt_plugin_add(const char* lua) {
// load the user-provided string as a lua function, putting that function on the stack
luaL_loadstring(state, lua);
if (luaL_loadstring(state, lua)) {
const char* e = lua_tolstring(state, -1, 0);
printf("plugin load error: %s\n", e);
lua_pop(state, 1);
return 0;
}
// create a new env for this plugin, and store it as registry["bolt"][i] where `i` is a unique ID
const uint64_t plugin_id = next_plugin_id;
@@ -276,3 +291,60 @@ static int api_batch2d_verticesperimage(lua_State* state) {
lua_pushinteger(state, batch->vertices_per_icon);
return 1;
}
static int api_batch2d_vertexxy(lua_State* state) {
_bolt_check_argc(state, 2, "batch2d_vertexxy");
struct RenderBatch2D* batch = lua_touserdata(state, 1);
const lua_Integer index = lua_tointeger(state, 2);
int32_t xy[2];
batch->functions.xy(batch, index - 1, batch->functions.userdata, xy);
lua_pushinteger(state, xy[0]);
lua_pushinteger(state, xy[1]);
return 2;
}
static int api_batch2d_vertexatlasxy(lua_State* state) {
_bolt_check_argc(state, 2, "batch2d_vertexatlasxy");
struct RenderBatch2D* batch = lua_touserdata(state, 1);
const lua_Integer index = lua_tointeger(state, 2);
int32_t xy[2];
batch->functions.atlas_xy(batch, index - 1, batch->functions.userdata, xy);
lua_pushinteger(state, xy[0]);
lua_pushinteger(state, xy[1]);
return 2;
}
static int api_batch2d_vertexatlaswh(lua_State* state) {
_bolt_check_argc(state, 2, "batch2d_vertexatlaswh");
struct RenderBatch2D* batch = lua_touserdata(state, 1);
const lua_Integer index = lua_tointeger(state, 2);
int32_t wh[2];
batch->functions.atlas_wh(batch, index - 1, batch->functions.userdata, wh);
lua_pushinteger(state, wh[0]);
lua_pushinteger(state, wh[1]);
return 2;
}
static int api_batch2d_vertexuv(lua_State* state) {
_bolt_check_argc(state, 2, "batch2d_vertexuv");
struct RenderBatch2D* batch = lua_touserdata(state, 1);
const lua_Integer index = lua_tointeger(state, 2);
double uv[2];
batch->functions.uv(batch, index - 1, batch->functions.userdata, uv);
lua_pushnumber(state, uv[0]);
lua_pushnumber(state, uv[1]);
return 2;
}
static int api_batch2d_vertexcolour(lua_State* state) {
_bolt_check_argc(state, 4, "batch2d_vertexcolour");
struct RenderBatch2D* batch = lua_touserdata(state, 1);
const lua_Integer index = lua_tointeger(state, 2);
double colour[4];
batch->functions.colour(batch, index - 1, batch->functions.userdata, colour);
lua_pushnumber(state, colour[0]);
lua_pushnumber(state, colour[1]);
lua_pushnumber(state, colour[2]);
lua_pushnumber(state, colour[3]);
return 4;
}

View File

@@ -1,15 +1,41 @@
#ifndef _BOLT_LIBRARY_PLUGIN_H_
#define _BOLT_LIBRARY_PLUGIN_H_
#include <stddef.h>
#include <stdint.h>
struct RenderBatch2D;
/// Struct containing callbacks for general-purpose accessing of vertex info from any backend.
/// Functions will be called with four params: batch pointer, index, the specified userdata,
/// and an output pointer, which must be able to index the returned number of items.
struct Vertex2DFunctions {
/// Userdata which will be passed to the functions contained in this struct.
void* userdata;
/// Returns the vertex X and Y, in screen coordinates.
void (*xy)(const struct RenderBatch2D*, size_t index, void* userdata, int32_t* out);
/// Returns the X and Y of the texture image associated with this vertex, in pixel coordinates.
void (*atlas_xy)(const struct RenderBatch2D*, size_t index, void* userdata, int32_t* out);
/// Returns the W and H of the texture image associated with this vertex, in pixel coordinates.
void (*atlas_wh)(const struct RenderBatch2D*, size_t index, void* userdata, int32_t* out);
/// Returns the U and V of this vertex in pixel coordinates, normalised from 0.0 to 1.0 within
/// the sub-image specified by atlas xy and wh.
void (*uv)(const struct RenderBatch2D*, size_t index, void* userdata, double* out);
/// Returns the RGBA colour of this vertex, each one normalised from 0.0 to 1.0.
void (*colour)(const struct RenderBatch2D*, size_t index, void* userdata, double* out);
};
struct RenderBatch2D {
uint16_t* indices;
uint8_t* texture;
uint32_t tex_width;
uint32_t tex_height;
uint32_t atlas_width;
uint32_t atlas_height;
uint32_t index_count;
uint32_t vertices_per_icon;
struct Vertex2DFunctions functions;
};
/// Init the plugin library. Call _bolt_plugin_close at the end of execution, and don't double-init.

View File

@@ -105,3 +105,31 @@ static int api_batch2d_vertexcount(lua_State*);
/// to draw a solid rectangle, e.g. using GL_TRIANGLE_STRIP), then that will be indicated here, so
/// it's recommended to use this function instead of hard-coding the number 6.
static int api_batch2d_verticesperimage(lua_State*);
/// [-2, +2, -]
/// Given an index of a vertex in a batch, returns its X and Y in screen coordinates.
static int api_batch2d_vertexxy(lua_State*);
/// [-2, +2, -]
/// Given an index of a vertex in a batch, returns the X and Y of its associated image in the
/// batch's texture atlas, in pixel coordinates.
static int api_batch2d_vertexatlasxy(lua_State*);
/// [-2, +2, -]
/// Given an index of a vertex in a batch, returns the width and height of its associated image in
/// the batch's texture atlas, in pixel coordinates.
static int api_batch2d_vertexatlaswh(lua_State*);
/// [-2, +2, -]
/// Given an index of a vertex in a batch, returns the vertex's associated "UV" coordinates.
///
/// The values will be floating-point numbers in the range 0.0 - 1.0. They are relative to the
/// position of the overall image in the texture atlas, queried by vertexatlasxy and vertexatlaswh.
static int api_batch2d_vertexuv(lua_State*);
/// [-2, +4, -]
/// Given an index of a vertex in a batch, returns the red, green, blue and alpha values for that
/// vertex, in that order. All four values will be floating-point numbers in the range 0.0 - 1.0.
///
/// Also aliased as "vertexcolor" to keep the Americans happy.
static int api_batch2d_vertexcolour(lua_State*);