video rendering
This commit is contained in:
parent
630d823591
commit
49271b4a5d
|
@ -75,9 +75,9 @@ void model_init() {
|
|||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[0].buffer_index = 0, /* position */
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[1].format = SG_VERTEXFORMAT_USHORT2N,
|
||||
[1].buffer_index = 1, /* tex coords */
|
||||
[2].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[2].format = SG_VERTEXFORMAT_UINT10_N2,
|
||||
[2].buffer_index = 2, /* normal */
|
||||
},
|
||||
},
|
||||
|
@ -107,6 +107,24 @@ cgltf_attribute *get_attr_type(cgltf_primitive p, cgltf_attribute_type t)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
unsigned short pack_short_texcoord(float c)
|
||||
{
|
||||
return c * USHRT_MAX;
|
||||
}
|
||||
|
||||
uint32_t pack_int10_n2(float *norm)
|
||||
{
|
||||
uint32_t ni[3];
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ni[i] = fabs(norm[i]) * 511.0 + 0.5;
|
||||
ni[i] = (ni[i] > 511) ? 511 : ni[i];
|
||||
ni[i] = ( norm[i] < 0.0 ) ? -ni[i] : ni[i];
|
||||
}
|
||||
|
||||
return (ni[0] & 0x3FF) | ( (ni[1] & 0x3FF) << 10) | ( (ni[2] & 0x3FF) << 20) | ( (0 & 0x3) << 30);
|
||||
}
|
||||
|
||||
struct model *MakeModel(const char *path) {
|
||||
YughWarn("Making the model from %s.", path);
|
||||
cgltf_options options = {0};
|
||||
|
@ -189,6 +207,9 @@ struct model *MakeModel(const char *path) {
|
|||
|
||||
cgltf_accessor_unpack_floats(attribute.data, vs, n);
|
||||
|
||||
uint32_t *packed_norms;
|
||||
unsigned short *packed_coords;
|
||||
|
||||
switch (attribute.type) {
|
||||
case cgltf_attribute_type_position:
|
||||
model->meshes[j].bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||
|
@ -198,25 +219,37 @@ struct model *MakeModel(const char *path) {
|
|||
|
||||
case cgltf_attribute_type_normal:
|
||||
has_norm = 1;
|
||||
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 = vs,
|
||||
.data.size = sizeof(float) * n});
|
||||
.data.ptr = packed_norms,
|
||||
.data.size = sizeof(uint32_t) * model->meshes[j].face_count});
|
||||
|
||||
free (packed_norms);
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_tangent:
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_texcoord:
|
||||
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(float) * n});
|
||||
.data.size = sizeof(unsigned short) * 2 * model->meshes[j].face_count});
|
||||
|
||||
free(packed_coords);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_norm) {
|
||||
YughWarn("Model does not have normals. Generating them.");
|
||||
float norms[3 * model->meshes[j].face_count];
|
||||
uint32_t norms[model->meshes[j].face_count];
|
||||
|
||||
|
||||
cgltf_attribute *pa = get_attr_type(primitive, cgltf_attribute_type_position);
|
||||
|
@ -224,24 +257,23 @@ struct model *MakeModel(const char *path) {
|
|||
float ps[n];
|
||||
cgltf_accessor_unpack_floats(pa->data,ps,n);
|
||||
|
||||
for (int i = 0; i < model->meshes[j].face_count/3; i++) {
|
||||
int o = i*9;
|
||||
for (int i = 0, face=0; i < model->meshes[j].face_count/3; i++, face+=9) {
|
||||
int o = face;
|
||||
HMM_Vec3 a = {ps[o], ps[o+1],ps[o+2]};
|
||||
o += 3;
|
||||
HMM_Vec3 b = {ps[o], ps[o+1],ps[o+2]};
|
||||
o += 3;
|
||||
HMM_Vec3 c = {ps[o], ps[o+1],ps[o+2]};
|
||||
HMM_Vec3 norm = HMM_NormV3(HMM_Cross(HMM_SubV3(b,a), HMM_SubV3(c,a)));
|
||||
for (int j = 0; j < 3; j++) {
|
||||
norms[i*9+j*3+0] = norm.X;
|
||||
norms[i*9+j*3+1] = norm.Y;
|
||||
norms[i*9+j*3+2] = norm.Z;
|
||||
}
|
||||
|
||||
uint32_t packed_norm = pack_int10_n2(norm.Elements);
|
||||
for (int j = 0; j < 3; j++)
|
||||
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(float) * model->meshes[j].face_count * 3
|
||||
.data.size = sizeof(uint32_t) * model->meshes[j].face_count
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,24 +14,26 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct shader *vid_shader;
|
||||
#include "sokol/sokol_gfx.h"
|
||||
|
||||
sg_shader vid_shader;
|
||||
sg_pipeline vid_pipeline;
|
||||
sg_bindings vid_bind;
|
||||
|
||||
|
||||
static void ds_update_texture(uint32_t unit, uint32_t texture, plm_plane_t *plane) {
|
||||
/*
|
||||
glActiveTexture(unit);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, plane->width, plane->height, 0, GL_RED, GL_UNSIGNED_BYTE, plane->data);
|
||||
*/
|
||||
}
|
||||
|
||||
static void render_frame(plm_t *mpeg, plm_frame_t *frame, void *user) {
|
||||
struct datastream *ds = user;
|
||||
shader_use(ds->shader);
|
||||
/*
|
||||
ds_update_texture(GL_TEXTURE0, ds->texture_y, &frame->y);
|
||||
ds_update_texture(GL_TEXTURE1, ds->texture_cb, &frame->cb);
|
||||
ds_update_texture(GL_TEXTURE2, ds->texture_cr, &frame->cr);
|
||||
*/
|
||||
uint8_t rgb[frame->height*frame->width*4];
|
||||
plm_frame_to_rgba(frame, rgb, frame->width*4);
|
||||
sg_image_data imgd;
|
||||
sg_range ir = {
|
||||
.ptr = rgb,
|
||||
.size = frame->height*frame->width*4*sizeof(uint8_t)
|
||||
};
|
||||
|
||||
imgd.subimage[0][0] = ir;
|
||||
sg_update_image(ds->img, &imgd);
|
||||
}
|
||||
|
||||
static void render_audio(plm_t *mpeg, plm_samples_t *samples, void *user) {
|
||||
|
@ -44,16 +46,6 @@ static void render_audio(plm_t *mpeg, plm_samples_t *samples, void *user) {
|
|||
}
|
||||
}
|
||||
|
||||
struct Texture *ds_maketexture(struct datastream *ds) {
|
||||
/*
|
||||
struct Texture *new = malloc(sizeof(*new));
|
||||
new->id = ds->texture_cb;
|
||||
new->width = 500;
|
||||
new->height = 500;
|
||||
return new;
|
||||
*/
|
||||
}
|
||||
|
||||
void ds_openvideo(struct datastream *ds, const char *video, const char *adriver) {
|
||||
// ds_stop(ds);
|
||||
char buf[MAXPATH] = {'\0'};
|
||||
|
@ -64,6 +56,11 @@ void ds_openvideo(struct datastream *ds, const char *video, const char *adriver)
|
|||
YughLog(0, 0, "Couldn't open %s", video);
|
||||
}
|
||||
|
||||
ds->img = sg_make_image(&(sg_image_desc){
|
||||
.width = plm_get_width(ds->plm),
|
||||
.height = plm_get_height(ds->plm)
|
||||
});
|
||||
|
||||
YughLog(0, 0, "Opened %s - framerate: %f, samplerate: %d, audio streams: %i, duration: %f",
|
||||
video,
|
||||
plm_get_framerate(ds->plm),
|
||||
|
@ -107,37 +104,14 @@ void ds_openvideo(struct datastream *ds, const char *video, const char *adriver)
|
|||
}
|
||||
|
||||
struct datastream *MakeDatastream() {
|
||||
struct datastream *newds = malloc(sizeof(*newds));
|
||||
/*
|
||||
if (!vid_shader) vid_shader = MakeShader("videovert.glsl", "videofrag.glsl");
|
||||
|
||||
newds->shader = vid_shader;
|
||||
shader_use(newds->shader);
|
||||
glGenTextures(1, &newds->texture_y);
|
||||
glBindTexture(GL_TEXTURE_2D, newds->texture_y);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
shader_setint(newds->shader, "texture_y", 0);
|
||||
|
||||
glGenTextures(1, &newds->texture_cb);
|
||||
glBindTexture(GL_TEXTURE_2D, newds->texture_cb);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
shader_setint(newds->shader, "texture_cb", 1);
|
||||
|
||||
glGenTextures(1, &newds->texture_cr);
|
||||
glBindTexture(GL_TEXTURE_2D, newds->texture_cr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
shader_setint(newds->shader, "texture_cr", 2);
|
||||
*/
|
||||
return newds;
|
||||
vid_shader = sg_make_shader(&(sg_shader_desc){
|
||||
.vs.source = slurp_text("shaders/videovert.glsl"),
|
||||
.fs.source = slurp_text("shaders/videofrag.glsl"),
|
||||
.fs.images[0] = {
|
||||
.name = "video",
|
||||
.image_type = SG_IMAGETYPE_2D,
|
||||
.sampler_type = SG_SAMPLERTYPE_FLOAT
|
||||
}});
|
||||
}
|
||||
|
||||
void ds_advance(struct datastream *ds, double s) {
|
||||
|
|
|
@ -4,24 +4,23 @@
|
|||
#include <pl_mpeg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sokol/sokol_gfx.h"
|
||||
|
||||
struct soundstream;
|
||||
|
||||
struct datastream {
|
||||
plm_t *plm;
|
||||
struct shader *shader;
|
||||
double last_time;
|
||||
int playing;
|
||||
int audio_device;
|
||||
uint32_t texture_y;
|
||||
uint32_t texture_cb;
|
||||
uint32_t texture_cr;
|
||||
sg_image img;
|
||||
int width;
|
||||
int height;
|
||||
struct soundstream *astream;
|
||||
};
|
||||
|
||||
struct Texture;
|
||||
|
||||
extern struct shader *vid_shader;
|
||||
|
||||
struct datastream *MakeDatastream();
|
||||
void ds_openvideo(struct datastream *ds, const char *path, const char *adriver);
|
||||
struct Texture *ds_maketexture(struct datastream *);
|
||||
|
|
|
@ -215,7 +215,7 @@ void text_flush() {
|
|||
if (curchar == 0) return;
|
||||
sg_apply_pipeline(pipe_text);
|
||||
sg_apply_bindings(&bind_text);
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(projection));
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj));
|
||||
|
||||
sg_range verts;
|
||||
verts.ptr = text_buffer;
|
||||
|
|
|
@ -40,6 +40,7 @@ float gridOpacity = 0.3f;
|
|||
|
||||
mfloat_t proj[16];
|
||||
|
||||
|
||||
// Debug render modes
|
||||
bool renderGizmos = false;
|
||||
bool showGrid = true;
|
||||
|
@ -233,6 +234,7 @@ float cam_zoom() { return zoom; }
|
|||
void add_zoom(float val) { zoom = val; }
|
||||
|
||||
mfloat_t projection[16] = {0.f};
|
||||
float hudproj[16] = {0.f};
|
||||
|
||||
HMM_Vec3 dirl_pos = {4, 100, 20};
|
||||
|
||||
|
@ -281,8 +283,7 @@ void openglRender(struct window *window) {
|
|||
pos.y - zoom * window->height / 2,
|
||||
pos.y + zoom * window->height / 2, -1.f, 1.f);
|
||||
|
||||
mfloat_t ui_projection[16] = {0.f};
|
||||
mat4_ortho(ui_projection, 0, window->width, 0, window->height, -1.f, 1.f);
|
||||
mat4_ortho(hudproj, 0, window->width, 0, window->height, -1.f, 1.f);
|
||||
|
||||
sprite_draw_all();
|
||||
sprite_flush();
|
||||
|
|
|
@ -19,6 +19,7 @@ extern int renderMode;
|
|||
extern HMM_Vec3 dirl_pos;
|
||||
|
||||
extern float projection[16];
|
||||
extern float hudproj[16];
|
||||
|
||||
extern float gridScale;
|
||||
extern float smallGridUnit;
|
||||
|
|
|
@ -217,15 +217,15 @@ void sprite_setframe(struct sprite *sprite, struct glrect *frame) {
|
|||
}
|
||||
|
||||
void video_draw(struct datastream *stream, mfloat_t position[2], mfloat_t size[2], float rotate, mfloat_t color[3]) {
|
||||
shader_use(vid_shader);
|
||||
// shader_use(vid_shader);
|
||||
|
||||
static mfloat_t model[16];
|
||||
memcpy(model, UNITMAT4, sizeof(UNITMAT4));
|
||||
mat4_translate_vec2(model, position);
|
||||
mat4_scale_vec2(model, size);
|
||||
|
||||
shader_setmat4(vid_shader, "model", model);
|
||||
shader_setvec3(vid_shader, "spriteColor", color);
|
||||
// shader_setmat4(vid_shader, "model", model);
|
||||
// shader_setvec3(vid_shader, "spriteColor", color);
|
||||
/*
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, stream->texture_y);
|
||||
|
|
Loading…
Reference in a new issue