261 lines
5.5 KiB
C
261 lines
5.5 KiB
C
// clang-format off
|
|
#include <glad/gl.h>
|
|
// clang-format on
|
|
|
|
#include "srender.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
typedef struct srndr {
|
|
} srndr;
|
|
|
|
typedef struct srview {
|
|
GLuint width;
|
|
GLuint height;
|
|
|
|
GLuint mFrameBufferId;
|
|
GLuint mColorTexture;
|
|
GLuint mDepthTexture;
|
|
|
|
simd4x4f proj;
|
|
simd4x4f view;
|
|
} srview;
|
|
|
|
typedef struct srcmdbuf {
|
|
int ncmds;
|
|
int idx;
|
|
srcmd* cmds;
|
|
} srcmdbuf;
|
|
|
|
//
|
|
// Vertex Data
|
|
//
|
|
typedef union srvrtxdata {
|
|
struct {
|
|
float x, y, z, w;
|
|
float nx, ny, nz;
|
|
float s, t;
|
|
GLubyte r,g,b,a;
|
|
};
|
|
struct {
|
|
float pos[4];
|
|
float n[4];
|
|
float uv[2];
|
|
GLubyte color[4];
|
|
};
|
|
} srvrtxdata;
|
|
|
|
//
|
|
// Simple Mesh Data
|
|
//
|
|
typedef struct srmeshdata {
|
|
int nvertices;
|
|
int nindices;
|
|
|
|
srvrtxdata *vertices;
|
|
int *indices;
|
|
} srmeshdata;
|
|
|
|
static srmeshdata gCoordFrameMesh = {0};
|
|
|
|
void init_debug_meshes () {
|
|
assert (gCoordFrameMesh.nvertices == 0);
|
|
|
|
gCoordFrameMesh.nvertices = 6;
|
|
|
|
srvrtxdata coord_frame_vertices[] = {
|
|
{0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 255, 0, 0, 255 },
|
|
{1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 255, 0, 0, 255 },
|
|
|
|
{0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, 255, 0, 255},
|
|
{0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, 255, 0, 255},
|
|
|
|
{0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, 0, 255, 255},
|
|
{0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, 0, 255, 255}
|
|
};
|
|
GLuint coord_frame_indices[] = {
|
|
0, 1,
|
|
1, 2,
|
|
3, 4
|
|
};
|
|
|
|
gCoordFrameMesh.vertices = malloc (sizeof(coord_frame_vertices));
|
|
memcpy (gCoordFrameMesh.vertices, coord_frame_vertices, sizeof(coord_frame_vertices));
|
|
|
|
gCoordFrameMesh.indices = malloc (sizeof(coord_frame_indices));
|
|
memcpy (gCoordFrameMesh.indices, coord_frame_indices, sizeof (coord_frame_indices));
|
|
};
|
|
|
|
//
|
|
// Renderer
|
|
//
|
|
srndr* srndr_create() {
|
|
srndr* result = calloc(1, sizeof(srndr));
|
|
|
|
init_debug_meshes();
|
|
|
|
return result;
|
|
}
|
|
|
|
void srndr_destroy(srndr* sr) { free(sr); }
|
|
|
|
//
|
|
// View
|
|
//
|
|
void srview_get_output_texture(srview* sv, GLuint* texture) {
|
|
*texture = sv->mColorTexture;
|
|
}
|
|
|
|
void srview_set_proj(srview* sv, simd4x4f proj) {
|
|
sv->proj = proj;
|
|
}
|
|
|
|
void srview_set_view(srview* sv, simd4x4f view) {
|
|
sv->view = view;
|
|
}
|
|
|
|
void srview_update_framebuffer(srview* sv) {
|
|
glGenFramebuffers(1, &sv->mFrameBufferId);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, sv->mFrameBufferId);
|
|
|
|
// Color Texture
|
|
glGenTextures(1, &sv->mColorTexture);
|
|
glBindTexture(GL_TEXTURE_2D, sv->mColorTexture);
|
|
|
|
glTexImage2D(
|
|
GL_TEXTURE_2D,
|
|
0,
|
|
GL_RGB,
|
|
sv->width,
|
|
sv->height,
|
|
0,
|
|
GL_RGB,
|
|
GL_UNSIGNED_BYTE,
|
|
0);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
glFramebufferTexture2D(
|
|
GL_FRAMEBUFFER,
|
|
GL_COLOR_ATTACHMENT0,
|
|
GL_TEXTURE_2D,
|
|
sv->mColorTexture,
|
|
0);
|
|
|
|
// Depth Texture
|
|
glGenTextures(1, &sv->mDepthTexture);
|
|
glBindTexture(GL_TEXTURE_2D, sv->mDepthTexture);
|
|
|
|
glTexImage2D(
|
|
GL_TEXTURE_2D,
|
|
0,
|
|
GL_DEPTH_COMPONENT,
|
|
sv->width,
|
|
sv->height,
|
|
0,
|
|
GL_DEPTH_COMPONENT,
|
|
GL_FLOAT,
|
|
0);
|
|
|
|
// Set parameters so that we can set a shadow2DSampler
|
|
glTexParameteri(
|
|
GL_TEXTURE_2D,
|
|
GL_TEXTURE_COMPARE_MODE,
|
|
GL_COMPARE_REF_TO_TEXTURE);
|
|
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_BORDER);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
float border_color[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
|
|
|
|
glFramebufferTexture2D(
|
|
GL_FRAMEBUFFER,
|
|
GL_DEPTH_ATTACHMENT,
|
|
GL_TEXTURE_2D,
|
|
sv->mDepthTexture,
|
|
0);
|
|
}
|
|
|
|
void srview_cleanup_framebuffer(srview* sv) {
|
|
if (glIsFramebuffer(sv->mFrameBufferId)) {
|
|
glDeleteFramebuffers(1, &sv->mFrameBufferId);
|
|
}
|
|
|
|
if (sv->mColorTexture != -1) {
|
|
glDeleteTextures(1, &sv->mColorTexture);
|
|
sv->mColorTexture = -1;
|
|
}
|
|
|
|
if (sv->mDepthTexture != -1) {
|
|
glDeleteTextures(1, &sv->mDepthTexture);
|
|
sv->mDepthTexture = -1;
|
|
}
|
|
}
|
|
|
|
void srview_set_size(srview* sv, int width, int height) {
|
|
if (sv->width == width && sv->height == height) {
|
|
return;
|
|
}
|
|
|
|
gLog("Setting size to %d, %d", width, height);
|
|
|
|
sv->width = width;
|
|
sv->height = height;
|
|
|
|
srview_cleanup_framebuffer(sv);
|
|
srview_update_framebuffer(sv);
|
|
|
|
gLog("Color texture = %d", sv->mColorTexture);
|
|
}
|
|
|
|
srview* srview_create() {
|
|
srview* result = calloc(1, sizeof(srview));
|
|
|
|
return result;
|
|
}
|
|
|
|
void srview_destroy(srview* sv) {
|
|
srview_cleanup_framebuffer(sv);
|
|
|
|
free(sv);
|
|
}
|
|
|
|
void srndr_render(srndr* srndr, srview* sview, srcmdbuf* scmdbuf) {
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, sview->mFrameBufferId);
|
|
|
|
glViewport(0, 0, sview->width, sview->height);
|
|
glClearColor(1.f, 0.f, 1.f, 1.f);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
|
}
|
|
|
|
//
|
|
// Render Commands
|
|
//
|
|
srcmdbuf* srcmdbuf_create (unsigned int size_max) {
|
|
srcmdbuf* result = malloc (sizeof (srcmdbuf));
|
|
result->ncmds = size_max;
|
|
result->idx = 0;
|
|
result->cmds = calloc (sizeof (srcmd), size_max);
|
|
|
|
return result;
|
|
}
|
|
|
|
void srcmdbuf_clear (srcmdbuf* cmdbuf) {
|
|
cmdbuf->idx = 0;
|
|
}
|
|
|
|
srcmd* srcmd_create (srcmdbuf* cmdbuf) {
|
|
if (cmdbuf->idx == cmdbuf->ncmds) {
|
|
gLog ("Warning: number of render commands maxed out!");
|
|
return NULL;
|
|
}
|
|
return &(cmdbuf->cmds[cmdbuf->idx++]);
|
|
}
|