Skip to content

Commit

Permalink
library: render3d viewmatrix + projectionmatrix
Browse files Browse the repository at this point in the history
  • Loading branch information
Adamcake committed Nov 24, 2024
1 parent d81de0e commit 4e09d70
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 12 deletions.
20 changes: 20 additions & 0 deletions src/library/doc.texi
Original file line number Diff line number Diff line change
Expand Up @@ -2114,6 +2114,26 @@ local worldpoint = modelpoint:transform(modelmatrix)
@end verbatim
@end example

@node render3d-viewmatrix
@subsection viewmatrix

Returns the @ref{objects-transform,,Transform object} representing the
view matrix of the model being rendered. Unless you understand the
difference between a view matrix and a projection matrix, this probably
isn't useful to you; @ref{render3d-viewprojmatrix,,viewprojmatrix} can
be used to more efficiently get a transform from world coordinates to
pixel coordinates.

@node render3d-projectionmatrix
@subsection projectionmatrix

Returns the @ref{objects-transform,,Transform object} representing the
projection matrix of the model being rendered. Unless you understand the
difference between a view matrix and a projection matrix, this probably
isn't useful to you; @ref{render3d-viewprojmatrix,,viewprojmatrix} can
be used to more efficiently get a transform from world coordinates to
pixel coordinates.

@node render3d-viewprojmatrix
@subsection viewprojmatrix

Expand Down
52 changes: 41 additions & 11 deletions src/library/gl.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ static void _bolt_gl_plugin_drawelements_vertex3d_colour(size_t index, void* use
static uint8_t _bolt_gl_plugin_drawelements_vertex3d_boneid(size_t index, void* userdata);
static void _bolt_gl_plugin_drawelements_vertex3d_transform(size_t vertex, void* userdata, struct Transform3D* out);
static void _bolt_gl_plugin_matrix3d_model(void* userdata, struct Transform3D* out);
static void _bolt_gl_plugin_matrix3d_view(void* userdata, struct Transform3D* out);
static void _bolt_gl_plugin_matrix3d_proj(void* userdata, struct Transform3D* out);
static void _bolt_gl_plugin_matrix3d_viewproj(void* userdata, struct Transform3D* out);
static size_t _bolt_gl_plugin_texture_id(void* userdata);
static void _bolt_gl_plugin_texture_size(void* userdata, size_t* out);
Expand Down Expand Up @@ -704,6 +706,8 @@ static GLuint _bolt_glCreateProgram() {
program->loc_sSceneHDRTex = -1;
program->block_index_ViewTransforms = -1;
program->offset_uCameraPosition = -1;
program->offset_uViewMatrix = -1;
program->offset_uProjectionMatrix = -1;
program->offset_uViewProjMatrix = -1;
program->is_2d = 0;
program->is_3d = 0;
Expand Down Expand Up @@ -765,22 +769,24 @@ static void _bolt_glLinkProgram(GLuint program) {
p->loc_uBoneTransforms = gl.GetUniformLocation(program, "uBoneTransforms");
p->loc_uSmoothSkinning = gl.GetUniformLocation(program, "uSmoothSkinning");

const GLchar* view_var_names[] = {"uCameraPosition", "uViewProjMatrix"};
const GLchar* view_var_names[] = {"uCameraPosition", "uViewMatrix", "uProjectionMatrix", "uViewProjMatrix"};
const GLuint block_index_ViewTransforms = gl.GetUniformBlockIndex(program, "ViewTransforms");
GLuint ubo_indices[2];
GLint view_offsets[2];
GLuint ubo_indices[4];
GLint view_offsets[4];
GLint viewport_offset;
if ((GLint)block_index_ViewTransforms != -1) {
gl.GetUniformIndices(program, 2, view_var_names, ubo_indices);
gl.GetActiveUniformsiv(program, 2, ubo_indices, GL_UNIFORM_OFFSET, view_offsets);
gl.GetUniformIndices(program, 4, view_var_names, ubo_indices);
gl.GetActiveUniformsiv(program, 4, ubo_indices, GL_UNIFORM_OFFSET, view_offsets);
}

if (loc_uModelMatrix != -1 && loc_uGridSize != -1 && block_index_ViewTransforms != -1) {
p->loc_uModelMatrix = loc_uModelMatrix;
p->loc_uGridSize = loc_uGridSize;
p->block_index_ViewTransforms = block_index_ViewTransforms;
p->offset_uCameraPosition = view_offsets[0];
p->offset_uViewProjMatrix = view_offsets[1];
p->offset_uViewMatrix = view_offsets[1];
p->offset_uProjectionMatrix = view_offsets[2];
p->offset_uViewProjMatrix = view_offsets[3];
p->is_minimap = 1;
}
if (p && p->loc_aVertexPosition2D != -1 && p->loc_aVertexColour != -1 && p->loc_aTextureUV != -1 && p->loc_aTextureUVAtlasMin != -1 && p->loc_aTextureUVAtlasExtents != -1 && uDiffuseMap != -1 && uProjectionMatrix != -1) {
Expand All @@ -796,7 +802,9 @@ static void _bolt_glLinkProgram(GLuint program) {
p->loc_uVertexScale = loc_uVertexScale;
p->block_index_ViewTransforms = block_index_ViewTransforms;
p->offset_uCameraPosition = view_offsets[0];
p->offset_uViewProjMatrix = view_offsets[1];
p->offset_uViewMatrix = view_offsets[1];
p->offset_uProjectionMatrix = view_offsets[2];
p->offset_uViewProjMatrix = view_offsets[3];
p->is_3d = 1;
}
LOG("glLinkProgram end\n");
Expand Down Expand Up @@ -1473,7 +1481,6 @@ void _bolt_gl_onDrawElements(GLenum mode, GLsizei count, GLenum type, const void
struct GLTexture2D* tex_settings = c->texture_units[settings_atlas];
gl.GetActiveUniformBlockiv(c->bound_program->id, c->bound_program->block_index_ViewTransforms, GL_UNIFORM_BLOCK_BINDING, &ubo_binding);
gl.GetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, ubo_binding, &ubo_view_index);
const float* view_proj_matrix = (float*)((uint8_t*)(_bolt_context_get_buffer(c, ubo_view_index)->data) + c->bound_program->offset_uViewProjMatrix);

struct GLPluginDrawElementsVertex3DUserData vertex_userdata;
vertex_userdata.c = c;
Expand All @@ -1492,8 +1499,11 @@ void _bolt_gl_onDrawElements(GLenum mode, GLsizei count, GLenum type, const void
tex_userdata.tex = tex;

struct GLPlugin3DMatrixUserData matrix_userdata;
gl.GetUniformfv(c->bound_program->id, c->bound_program->loc_uModelMatrix, matrix_userdata.model_matrix);
memcpy(matrix_userdata.viewproj_matrix, view_proj_matrix, 16 * sizeof(float));
matrix_userdata.program = c->bound_program;
const uint8_t* ubo_view_buf = (uint8_t*)_bolt_context_get_buffer(c, ubo_view_index)->data;
matrix_userdata.view_matrix = (float*)(ubo_view_buf + c->bound_program->offset_uViewMatrix);
matrix_userdata.proj_matrix = (float*)(ubo_view_buf + c->bound_program->offset_uProjectionMatrix);
matrix_userdata.viewproj_matrix = (float*)(ubo_view_buf + c->bound_program->offset_uViewProjMatrix);

struct Render3D render;
render.vertex_count = count;
Expand All @@ -1512,6 +1522,8 @@ void _bolt_gl_onDrawElements(GLenum mode, GLsizei count, GLenum type, const void
render.texture_functions.data = _bolt_gl_plugin_texture_data;
render.matrix_functions.userdata = &matrix_userdata;
render.matrix_functions.model_matrix = _bolt_gl_plugin_matrix3d_model;
render.matrix_functions.view_matrix = _bolt_gl_plugin_matrix3d_view;
render.matrix_functions.proj_matrix = _bolt_gl_plugin_matrix3d_proj;
render.matrix_functions.viewproj_matrix = _bolt_gl_plugin_matrix3d_viewproj;

_bolt_plugin_handle_render3d(&render);
Expand Down Expand Up @@ -1829,12 +1841,30 @@ static void _bolt_gl_plugin_drawelements_vertex3d_transform(size_t vertex, void*
}

static void _bolt_gl_plugin_matrix3d_model(void* userdata, struct Transform3D* out) {
const struct GLPlugin3DMatrixUserData* data = userdata;
struct GLPlugin3DMatrixUserData* data = userdata;
if (data->program) {
gl.GetUniformfv(data->program->id, data->program->loc_uModelMatrix, data->model_matrix);
data->program = NULL;
}
for (size_t i = 0; i < 16; i += 1) {
out->matrix[i] = (double)data->model_matrix[i];
}
}

static void _bolt_gl_plugin_matrix3d_view(void* userdata, struct Transform3D* out) {
const struct GLPlugin3DMatrixUserData* data = userdata;
for (size_t i = 0; i < 16; i += 1) {
out->matrix[i] = (double)data->view_matrix[i];
}
}

static void _bolt_gl_plugin_matrix3d_proj(void* userdata, struct Transform3D* out) {
const struct GLPlugin3DMatrixUserData* data = userdata;
for (size_t i = 0; i < 16; i += 1) {
out->matrix[i] = (double)data->proj_matrix[i];
}
}

static void _bolt_gl_plugin_matrix3d_viewproj(void* userdata, struct Transform3D* out) {
const struct GLPlugin3DMatrixUserData* data = userdata;
for (size_t i = 0; i < 16; i += 1) {
Expand Down
7 changes: 6 additions & 1 deletion src/library/gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ struct GLProgram {
GLint loc_sBlurFarTex;
GLuint block_index_ViewTransforms;
GLint offset_uCameraPosition;
GLint offset_uViewMatrix;
GLint offset_uProjectionMatrix;
GLint offset_uViewProjMatrix;
uint8_t is_minimap;
uint8_t is_2d;
Expand Down Expand Up @@ -352,7 +354,10 @@ struct GLPluginDrawElementsVertex3DUserData {

struct GLPlugin3DMatrixUserData {
float model_matrix[16];
float viewproj_matrix[16];
const struct GLProgram* program;
const float* view_matrix;
const float* proj_matrix;
const float* viewproj_matrix;
};

struct GLPluginTextureUserData {
Expand Down
6 changes: 6 additions & 0 deletions src/library/plugin/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ struct Render3DMatrixFunctions {
/// Gets the model matrix for this render.
void (*model_matrix)(void* userdata, struct Transform3D* out);

/// Gets the view matrix for this render.
void (*view_matrix)(void* userdata, struct Transform3D* out);

/// Gets the projection matrix for this render.
void (*proj_matrix)(void* userdata, struct Transform3D* out);

/// Gets the combined view-projection matrix for this render.
void (*viewproj_matrix)(void* userdata, struct Transform3D* out);
};
Expand Down
20 changes: 20 additions & 0 deletions src/library/plugin/plugin_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,24 @@ static int api_render3d_modelmatrix(lua_State* state) {
return 1;
}

static int api_render3d_viewmatrix(lua_State* state) {
const struct Render3D* render = require_self_userdata(state, "viewmatrix");
struct Transform3D* transform = lua_newuserdata(state, sizeof(struct Transform3D));
render->matrix_functions.view_matrix(render->matrix_functions.userdata, transform);
lua_getfield(state, LUA_REGISTRYINDEX, "transformmeta");
lua_setmetatable(state, -2);
return 1;
}

static int api_render3d_projectionmatrix(lua_State* state) {
const struct Render3D* render = require_self_userdata(state, "projectionmatrix");
struct Transform3D* transform = lua_newuserdata(state, sizeof(struct Transform3D));
render->matrix_functions.proj_matrix(render->matrix_functions.userdata, transform);
lua_getfield(state, LUA_REGISTRYINDEX, "transformmeta");
lua_setmetatable(state, -2);
return 1;
}

static int api_render3d_viewprojmatrix(lua_State* state) {
const struct Render3D* render = require_self_userdata(state, "viewprojmatrix");
struct Transform3D* transform = lua_newuserdata(state, sizeof(struct Transform3D));
Expand Down Expand Up @@ -1493,6 +1511,8 @@ static struct ApiFuncTemplate render3d_functions[] = {
BOLTFUNC(vertexcount, render3d),
BOLTFUNC(vertexxyz, render3d),
BOLTFUNC(modelmatrix, render3d),
BOLTFUNC(viewmatrix, render3d),
BOLTFUNC(projectionmatrix, render3d),
BOLTFUNC(viewprojmatrix, render3d),
BOLTFUNC(vertexmeta, render3d),
BOLTFUNC(atlasxywh, render3d),
Expand Down

0 comments on commit 4e09d70

Please sign in to comment.