3d rendering
This commit is contained in:
parent
a854764636
commit
366a20e7ed
|
@ -104,6 +104,15 @@ component.sprite.impl = {
|
|||
|
||||
Object.freeze(sprite);
|
||||
|
||||
component.model = Object.copy(component, {
|
||||
path:"",
|
||||
_enghook: make_model,
|
||||
});
|
||||
component.model.impl = {
|
||||
set path(x) { cmd(149, this.id, x); },
|
||||
draw() { cmd(150, this.id); },
|
||||
};
|
||||
|
||||
var sprite = component.sprite;
|
||||
|
||||
sprite.doc = {
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
#include "stb_ds.h"
|
||||
#include "font.h"
|
||||
#include "window.h"
|
||||
#include "gameobject.h"
|
||||
#include "libgen.h"
|
||||
|
||||
#include "diffuse.sglsl.h"
|
||||
//#include "diffuse.sglsl.h"
|
||||
#include "unlit.sglsl.h"
|
||||
|
||||
#include "render.h"
|
||||
|
||||
|
@ -39,18 +42,14 @@ static sg_shader model_shader;
|
|||
static sg_pipeline model_pipe;
|
||||
|
||||
void model_init() {
|
||||
model_shader = sg_make_shader(diffuse_shader_desc(sg_query_backend()));
|
||||
/* model_shader = sg_make_shader(diffuse_shader_desc(sg_query_backend()));
|
||||
|
||||
model_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = model_shader,
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[0].buffer_index = 0, /* position */
|
||||
[1].format = SG_VERTEXFORMAT_USHORT2N,
|
||||
[1].buffer_index = 1, /* tex coords */
|
||||
[2].format = SG_VERTEXFORMAT_UINT10_N2,
|
||||
[2].buffer_index = 2, /* normal */
|
||||
},
|
||||
},
|
||||
.index_type = SG_INDEXTYPE_UINT16,
|
||||
|
@ -58,6 +57,24 @@ void model_init() {
|
|||
.depth.write_enabled = true,
|
||||
.depth.compare = SG_COMPAREFUNC_LESS_EQUAL
|
||||
});
|
||||
*/
|
||||
|
||||
model_shader = sg_make_shader(unlit_shader_desc(sg_query_backend()));
|
||||
|
||||
model_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = model_shader,
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[1].format = SG_VERTEXFORMAT_USHORT2N,
|
||||
[1].buffer_index = 1,
|
||||
},
|
||||
},
|
||||
.index_type = SG_INDEXTYPE_UINT16,
|
||||
.cull_mode = SG_CULLMODE_FRONT,
|
||||
.depth.write_enabled = true,
|
||||
.depth.compare = SG_COMPAREFUNC_LESS_EQUAL
|
||||
});
|
||||
}
|
||||
|
||||
struct model *GetExistingModel(const char *path) {
|
||||
|
@ -118,6 +135,7 @@ struct model *MakeModel(const char *path) {
|
|||
struct model *model = calloc(1, sizeof(*model));
|
||||
/* TODO: Optimize by grouping by material. One material per draw. */
|
||||
YughWarn("Model has %d materials.", data->materials_count);
|
||||
const char *dir = dirname(path);
|
||||
|
||||
float vs[65535*3];
|
||||
uint16_t idxs[65535];
|
||||
|
@ -156,19 +174,21 @@ struct model *MakeModel(const char *path) {
|
|||
}
|
||||
|
||||
if (primitive.material->has_pbr_metallic_roughness && primitive.material->pbr_metallic_roughness.base_color_texture.texture) {
|
||||
// YughWarn("Texture is %s.", primitive.material->pbr_metallic_roughness.base_color_texture.texture->image->uri);
|
||||
const char *imp = seprint("%s/%s", dir, primitive.material->pbr_metallic_roughness.base_color_texture.texture->image->uri);
|
||||
YughInfo("Texture is %s.", imp);
|
||||
|
||||
model->meshes[j].bind.fs.images[0] = texture_pullfromfile(primitive.material->pbr_metallic_roughness.base_color_texture.texture->image->uri)->id;
|
||||
model->meshes[j].bind.fs.images[0] = texture_pullfromfile(imp)->id;
|
||||
free(imp);
|
||||
} else
|
||||
model->meshes[j].bind.fs.images[0] = texture_pullfromfile("k")->id;
|
||||
|
||||
cgltf_texture *tex;
|
||||
if (tex = primitive.material->normal_texture.texture) {
|
||||
model->meshes[j].bind.fs.images[1] = texture_pullfromfile(tex->image->uri)->id;
|
||||
} else
|
||||
model->meshes[j].bind.fs.images[1] = texture_pullfromfile("k")->id;
|
||||
model->meshes[j].bind.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){});
|
||||
|
||||
model->meshes[j].bind.fs.images[2] = ddimg;
|
||||
cgltf_texture *tex;
|
||||
// if (tex = primitive.material->normal_texture.texture) {
|
||||
// model->meshes[j].bind.fs.images[1] = texture_pullfromfile(tex->image->uri)->id;
|
||||
// }// else
|
||||
// model->meshes[j].bind.fs.images[1] = texture_pullfromfile("k")->id;
|
||||
|
||||
int has_norm = 0;
|
||||
|
||||
|
@ -184,6 +204,7 @@ struct model *MakeModel(const char *path) {
|
|||
|
||||
switch (attribute.type) {
|
||||
case cgltf_attribute_type_position:
|
||||
|
||||
model->meshes[j].bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = vs,
|
||||
.data.size = sizeof(float) * n});
|
||||
|
@ -194,10 +215,10 @@ struct model *MakeModel(const char *path) {
|
|||
packed_norms = malloc(model->meshes[j].face_count * sizeof(uint32_t));;
|
||||
for (int i = 0; i < model->meshes[j].face_count; i++)
|
||||
packed_norms[i] = pack_int10_n2(vs + i*3);
|
||||
|
||||
model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = packed_norms,
|
||||
.data.size = sizeof(uint32_t) * model->meshes[j].face_count});
|
||||
|
||||
// model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
||||
// .data.ptr = packed_norms,
|
||||
// .data.size = sizeof(uint32_t) * model->meshes[j].face_count});
|
||||
|
||||
free (packed_norms);
|
||||
break;
|
||||
|
@ -209,7 +230,7 @@ struct model *MakeModel(const char *path) {
|
|||
packed_coords = malloc(model->meshes[j].face_count * 2 * sizeof(unsigned short));
|
||||
for (int i = 0; i < model->meshes[j].face_count*2; i++)
|
||||
packed_coords[i] = pack_short_texcoord(vs[i]);
|
||||
|
||||
|
||||
model->meshes[j].bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = vs,
|
||||
.data.size = sizeof(unsigned short) * 2 * model->meshes[j].face_count});
|
||||
|
@ -243,10 +264,10 @@ struct model *MakeModel(const char *path) {
|
|||
norms[i*3+j] = packed_norm;
|
||||
}
|
||||
|
||||
model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data.ptr = norms,
|
||||
.data.size = sizeof(uint32_t) * model->meshes[j].face_count
|
||||
});
|
||||
// model->meshes[j].bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
||||
// .data.ptr = norms,
|
||||
// .data.size = sizeof(uint32_t) * model->meshes[j].face_count
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +277,7 @@ struct model *MakeModel(const char *path) {
|
|||
|
||||
HMM_Vec3 eye = {50,10,5};
|
||||
|
||||
void draw_model(struct model *model, HMM_Mat4 amodel, HMM_Mat4 lsm) {
|
||||
void draw_model(struct model *model, HMM_Mat4 amodel) {
|
||||
HMM_Mat4 proj = HMM_Perspective_RH_ZO(45, (float)mainwin.width / mainwin.height, 0.1, 10000);
|
||||
HMM_Vec3 center = {0.f, 0.f, 0.f};
|
||||
HMM_Vec3 up = {0.f, 1.f, 0.f};
|
||||
|
@ -268,23 +289,13 @@ void draw_model(struct model *model, HMM_Mat4 amodel, HMM_Mat4 lsm) {
|
|||
HMM_Vec3 lp = {1, 1, 1};
|
||||
HMM_Vec3 dir_dir = HMM_NormV3(HMM_SubV3(center, dirl_pos));
|
||||
|
||||
HMM_Mat4 m2[4];
|
||||
m2[0] = view;
|
||||
m2[1] = amodel;
|
||||
m2[2] = proj;
|
||||
m2[3] = lsm;
|
||||
|
||||
HMM_Vec3 f_ubo[5];
|
||||
f_ubo[0] = lp;
|
||||
f_ubo[1] = dir_dir;
|
||||
f_ubo[2] = eye;
|
||||
f_ubo[3] = eye;
|
||||
f_ubo[4] = eye;
|
||||
vs_p_t vs_p;
|
||||
memcpy(vs_p.vp, view.Elements, sizeof(float)*16);
|
||||
memcpy(vs_p.model, amodel.Elements, sizeof(float)*16);
|
||||
memcpy(vs_p.proj, proj.Elements, sizeof(float)*16);
|
||||
|
||||
sg_apply_pipeline(model_pipe);
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(m2));
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, SG_RANGE_REF(f_ubo));
|
||||
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_p, SG_RANGE_REF(vs_p));
|
||||
|
||||
for (int i = 0; i < arrlen(model->meshes); i++) {
|
||||
sg_apply_bindings(&model->meshes[i].bind);
|
||||
|
@ -292,3 +303,32 @@ void draw_model(struct model *model, HMM_Mat4 amodel, HMM_Mat4 lsm) {
|
|||
}
|
||||
}
|
||||
|
||||
struct drawmodel *make_drawmodel(int go)
|
||||
{
|
||||
struct drawmodel *dm = malloc(sizeof(struct drawmodel));
|
||||
dm->model = NULL;
|
||||
dm->amodel = HMM_M4D(1.f);
|
||||
dm->go = go;
|
||||
return dm;
|
||||
}
|
||||
|
||||
void draw_drawmodel(struct drawmodel *dm)
|
||||
{
|
||||
if (!dm->model) return;
|
||||
struct gameobject *go = id2go(dm->go);
|
||||
cpVect pos = cpBodyGetPosition(go->body);
|
||||
HMM_Mat4 scale = HMM_Scale(id2go(dm->go)->scale3);
|
||||
HMM_Mat4 trans = HMM_M4D(1.f);
|
||||
trans.Elements[3][2] = -pos.x;
|
||||
trans.Elements[3][1] = pos.y;
|
||||
HMM_Mat4 rot = HMM_Rotate_RH(cpBodyGetAngle(go->body), vUP);
|
||||
/* model matrix = trans * rot * scale */
|
||||
|
||||
draw_model(dm->model, HMM_MulM4(trans, HMM_MulM4(rot, scale)));
|
||||
}
|
||||
|
||||
void free_drawmodel(struct drawmodel *dm)
|
||||
{
|
||||
free(dm);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,15 +8,24 @@
|
|||
extern HMM_Vec3 eye;
|
||||
struct shader;
|
||||
|
||||
/* A single mesh */
|
||||
struct mesh {
|
||||
sg_bindings bind;
|
||||
uint32_t face_count;
|
||||
};
|
||||
|
||||
/* A collection of meshes which create a full figure */
|
||||
struct model {
|
||||
struct mesh *meshes;
|
||||
};
|
||||
|
||||
/* A model with draw information */
|
||||
struct drawmodel {
|
||||
struct model *model;
|
||||
HMM_Mat4 amodel;
|
||||
int go;
|
||||
};
|
||||
|
||||
/* Get the model at a path, or create and return if it doesn't exist */
|
||||
struct model *GetExistingModel(const char *path);
|
||||
|
||||
|
@ -28,7 +37,11 @@ void loadmodel(struct model *model);
|
|||
|
||||
void model_init();
|
||||
|
||||
void draw_model(struct model *model, HMM_Mat4 amodel, HMM_Mat4 lsm);
|
||||
void draw_model(struct model *model, HMM_Mat4 amodel);
|
||||
void draw_models(struct model *model, struct shader *shader);
|
||||
|
||||
struct drawmodel *make_drawmodel(int go);
|
||||
void draw_drawmodel(struct drawmodel *dm);
|
||||
void free_drawmodel(struct drawmodel *dm);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -542,6 +542,11 @@ static inline HMM_Vec3 HMM_V3(float X, float Y, float Z) {
|
|||
return Result;
|
||||
}
|
||||
|
||||
static inline HMM_Vec3 HMM_V3i(float i)
|
||||
{
|
||||
return (HMM_Vec3){i,i,i};
|
||||
}
|
||||
|
||||
static inline HMM_Vec4 HMM_V4(float X, float Y, float Z, float W) {
|
||||
|
||||
HMM_Vec4 Result;
|
||||
|
|
|
@ -650,6 +650,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
|
||||
case 36:
|
||||
id2go(js2int(argv[1]))->scale = js2number(argv[2]);
|
||||
id2go(js2int(argv[1]))->scale3 = HMM_V3i(js2number(argv[2]));
|
||||
gameobject_apply(id2go(js2int(argv[1])));
|
||||
cpSpaceReindexShapesForBody(space, id2go(js2int(argv[1]))->body);
|
||||
break;
|
||||
|
@ -1123,6 +1124,14 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
case 148:
|
||||
ret = color2js(id2sprite(js2int(argv[1]))->color);
|
||||
break;
|
||||
case 149:
|
||||
((struct drawmodel *)js2ptr(argv[1]))->model = GetExistingModel(js2str(argv[2]));
|
||||
break;
|
||||
|
||||
case 150:
|
||||
draw_drawmodel(js2ptr(argv[1]));
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (str)
|
||||
|
@ -1491,6 +1500,15 @@ JSValue duk_make_circle2d(JSContext *js, JSValueConst this, int argc, JSValueCon
|
|||
return circleval;
|
||||
}
|
||||
|
||||
JSValue duk_make_model(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||
{
|
||||
int go = js2int(argv[0]);
|
||||
struct drawmodel *dm = make_drawmodel(go);
|
||||
JSValue ret = JS_NewObject(js);
|
||||
js_setprop_str(ret, "id", ptr2js(dm));
|
||||
return ret;
|
||||
}
|
||||
|
||||
JSValue duk_cmd_circle2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
|
||||
int cmd = js2int(argv[0]);
|
||||
struct phys2d_circle *circle = js2ptr(argv[1]);
|
||||
|
@ -1675,6 +1693,7 @@ void ffi_load() {
|
|||
DUK_FUNC(cmd_poly2d, 6)
|
||||
DUK_FUNC(make_edge2d, 3)
|
||||
DUK_FUNC(cmd_edge2d, 6)
|
||||
DUK_FUNC(make_model,2);
|
||||
DUK_FUNC(make_timer, 3)
|
||||
|
||||
DUK_FUNC(cmd_points, 5);
|
||||
|
|
|
@ -144,6 +144,7 @@ static void gameobject_setpickcolor(struct gameobject *go) {
|
|||
int MakeGameobject() {
|
||||
struct gameobject go = {
|
||||
.scale = 1.f,
|
||||
.scale3 = (HMM_Vec3){1.f,1.f,1.f},
|
||||
.bodytype = CP_BODY_TYPE_STATIC,
|
||||
.mass = 1.f,
|
||||
.next = -1,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "quickjs/quickjs.h"
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
struct shader;
|
||||
struct sprite;
|
||||
|
@ -16,6 +17,7 @@ struct gameobject {
|
|||
cpBodyType bodytype;
|
||||
int next;
|
||||
float scale;
|
||||
HMM_Vec3 scale3;
|
||||
float mass;
|
||||
float f; /* friction */
|
||||
float e; /* elasticity */
|
||||
|
|
44
source/engine/thirdparty/sokol/sokol_app.h
vendored
44
source/engine/thirdparty/sokol/sokol_app.h
vendored
|
@ -3471,6 +3471,50 @@ _SOKOL_PRIVATE void _sapp_macos_run(const sapp_desc* desc) {
|
|||
// set the application dock icon as early as possible, otherwise
|
||||
// the dummy icon will be visible for a short time
|
||||
sapp_set_icon(&_sapp.desc.icon);
|
||||
|
||||
NSMenu* menu_bar = [[NSMenu alloc] init];
|
||||
NSMenuItem* app_menu_item = [[NSMenuItem alloc] init];
|
||||
[menu_bar addItem:app_menu_item];
|
||||
NSApp.mainMenu = menu_bar;
|
||||
NSMenu* app_menu = [[NSMenu alloc] init];
|
||||
NSString* window_title_as_nsstring = [NSString stringWithUTF8String:desc->window_title];
|
||||
|
||||
NSString* quit_title = [@"Quit " stringByAppendingString:window_title_as_nsstring];
|
||||
NSMenuItem* quit_menu_item = [[NSMenuItem alloc]
|
||||
initWithTitle:quit_title
|
||||
action:@selector(terminate:)
|
||||
keyEquivalent:@"q"];
|
||||
|
||||
NSString* hide_title = [@"Hide " stringByAppendingString:window_title_as_nsstring];
|
||||
NSMenuItem* hide_menu_item = [[NSMenuItem alloc]
|
||||
initWithTitle:hide_title
|
||||
action:@selector(hide:)
|
||||
keyEquivalent:@"h"];
|
||||
|
||||
NSMenuItem* hide_others_item = [[NSMenuItem alloc]
|
||||
initWithTitle:@"Hide Others"
|
||||
action:@selector(hideOtherApplications:)
|
||||
keyEquivalent:@"h"];
|
||||
|
||||
[hide_others_item setKeyEquivalentModifierMask: NSEventModifierFlagOption];
|
||||
|
||||
NSMenuItem* show_all_item = [[NSMenuItem alloc]
|
||||
initWithTitle:@"Show All"
|
||||
action:@selector(unhideAllApplications:)
|
||||
keyEquivalent:@""];
|
||||
|
||||
[app_menu addItem:hide_menu_item];
|
||||
[app_menu addItem:hide_others_item];
|
||||
[app_menu addItem:show_all_item];
|
||||
[app_menu addItem:[NSMenuItem separatorItem]];
|
||||
[app_menu addItem:quit_menu_item];
|
||||
app_menu_item.submenu = app_menu;
|
||||
|
||||
_SAPP_OBJC_RELEASE(window_title_as_nsstring);
|
||||
_SAPP_OBJC_RELEASE(app_menu);
|
||||
_SAPP_OBJC_RELEASE(app_menu_item);
|
||||
_SAPP_OBJC_RELEASE(menu_bar);
|
||||
|
||||
_sapp.macos.app_dlg = [[_sapp_macos_app_delegate alloc] init];
|
||||
NSApp.delegate = _sapp.macos.app_dlg;
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ out vec3 normal;
|
|||
out vec3 frag_pos;
|
||||
out vec4 frag_pos_light;
|
||||
|
||||
|
||||
uniform vs_p {
|
||||
uniform mat4 vp;
|
||||
uniform mat4 model;
|
||||
|
|
Loading…
Reference in a new issue