Started working on default rendering shader.

master
Martin Felis 2020-10-18 22:03:42 +02:00
parent e8553fff6c
commit b4729fada4
4 changed files with 338 additions and 87 deletions

View File

@ -0,0 +1,9 @@
#version 330
out vec4 fragColor;
smooth in vec4 ioFragColor;
void main()
{
fragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

View File

@ -0,0 +1,19 @@
#version 330
in vec4 inCoord;
in vec3 inNormal;
in vec2 inUV;
in vec4 inColor;
uniform mat4 uModelMatrix;
uniform mat4 uViewMatrix;
uniform mat4 uProjectionMatrix;
smooth out vec4 ioFragColor;
void main()
{
ioFragColor = inColor;
gl_Position = (uProjectionMatrix * uViewMatrix * uModelMatrix * inCoord);
}

View File

@ -20,73 +20,222 @@ typedef struct srview {
GLuint mColorTexture;
GLuint mDepthTexture;
simd4x4f proj;
simd4x4f view;
simd4x4f proj;
simd4x4f view;
} srview;
typedef struct srcmdbuf {
int ncmds;
int idx;
srcmd* cmds;
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];
};
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;
int nvertices;
int nindices;
srvrtxdata *vertices;
int *indices;
GLuint vertex_buffer_id;
GLuint index_buffer_id;
} srmeshdata;
static srmeshdata gCoordFrameMesh = {0};
void init_debug_meshes () {
assert (gCoordFrameMesh.nvertices == 0);
typedef struct srshader {
const char* vert_fname;
const char* frag_fname;
gCoordFrameMesh.nvertices = 6;
GLuint program_id;
GLuint vert_shader_id;
GLuint frag_shader_id;
} srshader;
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 },
static srshader gDefaultShader = {"default_vert.glsl", "default_frag.glsl", 0, 0, 0};
{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},
bool srshader_compile (GLuint shader_id, const char* shader_src) {
glShaderSource (shader_id, 1, &shader_src, 0);
glCompileShader (shader_id);
{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
};
// Check Vertex Shader
GLint result = GL_FALSE;
int log_length = 0;
glGetShaderiv(shader_id, GL_COMPILE_STATUS, &result);
glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &log_length);
if ( log_length > 0 ){
char* err_msg = calloc (log_length, sizeof(char));
assert (err_msg);
glGetShaderInfoLog(shader_id, log_length, NULL, err_msg);
gLog("%s", err_msg);
free (err_msg);
gCoordFrameMesh.vertices = malloc (sizeof(coord_frame_vertices));
memcpy (gCoordFrameMesh.vertices, coord_frame_vertices, sizeof(coord_frame_vertices));
return false;
}
gCoordFrameMesh.indices = malloc (sizeof(coord_frame_indices));
memcpy (gCoordFrameMesh.indices, coord_frame_indices, sizeof (coord_frame_indices));
return true;
}
bool srshader_load (srshader* shader, const char* vert_src, const char* frag_src) {
shader->vert_shader_id = glCreateShader(GL_VERTEX_SHADER);
if (!srshader_compile(shader->vert_shader_id, vert_src)) {
gLog("Error compiling vertex shader!");
return false;
}
shader->frag_shader_id = glCreateShader(GL_FRAGMENT_SHADER);
if (!srshader_compile(shader->frag_shader_id, frag_src)) {
gLog("Error compiling fragment shader!");
return false;
}
shader->program_id = glCreateProgram();
glAttachShader(shader->program_id, shader->vert_shader_id);
glAttachShader(shader->program_id, shader->frag_shader_id);
// Bind attribute locations
glBindAttribLocation(shader->program_id, 0, "inCoord");
glBindAttribLocation(shader->program_id, 1, "inNormal");
glBindAttribLocation(shader->program_id, 2, "inUV");
glBindAttribLocation(shader->program_id, 3, "inColor");
glLinkProgram(shader->program_id);
GLint result = GL_FALSE;
int log_length = 0;
glGetProgramiv(shader->program_id, GL_LINK_STATUS, &result);
glGetProgramiv(shader->program_id, GL_INFO_LOG_LENGTH, &log_length);
if ( log_length > 0 ){
char* err_msg = calloc (log_length, sizeof(char));
assert (err_msg);
glGetProgramInfoLog(shader->program_id, log_length, NULL, err_msg);
gLog("%s", err_msg);
free (err_msg);
gLog("Error linking shader program!");
return false;
}
return true;
}
bool try_read_file (const char* dir, const char* filename, char** buf) {
assert (*buf == NULL);
int path_len = strlen(dir) + strlen(filename) + 1;
char* path_buffer = calloc (path_len, sizeof(char));
snprintf (path_buffer, path_len, "%s%s", dir, filename);
long file_length = 0;
FILE* file = NULL;
file = fopen(path_buffer, "rb");
if (file) {
fseek(file, 0, SEEK_END);
file_length = ftell(file);
fseek(file, 0, SEEK_SET);
*buf = calloc(file_length, sizeof(char));
assert (*buf);
fread (*buf, 1, file_length, file);
fclose(file);
return true;
}
return false;
}
void init_shaders() {
static const char* shader_search_paths[] = {
"./data/shaders/",
"../data/shaders/",
NULL};
bool found = false;
int search_index = 0;
char* frag_buffer = NULL;
char* vert_buffer = NULL;
while (shader_search_paths[search_index] != NULL) {
const char* dir = shader_search_paths[search_index];
static char path_buf[1024];
long length;
if (vert_buffer == NULL) {
try_read_file (dir, gDefaultShader.vert_fname, &vert_buffer);
}
if (frag_buffer == NULL) {
try_read_file (dir, gDefaultShader.frag_fname, &frag_buffer);
}
if ((vert_buffer != NULL) && (frag_buffer != NULL)) {
srshader_load (&gDefaultShader, vert_buffer, frag_buffer);
free (vert_buffer);
vert_buffer = NULL;
free (frag_buffer);
frag_buffer = NULL;
break;
}
search_index++;
}
if (gDefaultShader.program_id == 0) {
gLog ("Error: could not load default shader!");
}
}
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};
glGenBuffers(1, &gCoordFrameMesh.vertex_buffer_id);
glBindBuffer(GL_ARRAY_BUFFER, gCoordFrameMesh.vertex_buffer_id);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(coord_frame_vertices),
coord_frame_vertices,
GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &gCoordFrameMesh.index_buffer_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gCoordFrameMesh.index_buffer_id);
glBufferData(
GL_ELEMENT_ARRAY_BUFFER,
sizeof(coord_frame_indices),
coord_frame_indices,
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
};
//
@ -95,7 +244,8 @@ void init_debug_meshes () {
srndr* srndr_create() {
srndr* result = calloc(1, sizeof(srndr));
init_debug_meshes();
init_shaders();
init_debug_meshes();
return result;
}
@ -109,13 +259,9 @@ 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_proj(srview* sv, simd4x4f proj) { sv->proj = proj; }
void srview_set_view(srview* sv, simd4x4f view) {
sv->view = view;
}
void srview_set_view(srview* sv, simd4x4f view) { sv->view = view; }
void srview_update_framebuffer(srview* sv) {
glGenFramebuffers(1, &sv->mFrameBufferId);
@ -202,15 +348,11 @@ void srview_set_size(srview* sv, int width, int 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() {
@ -225,12 +367,86 @@ void srview_destroy(srview* sv) {
free(sv);
}
void srndr_run_frame_command(const srcmd* cmd) {
glBindBuffer(GL_ARRAY_BUFFER, gCoordFrameMesh.vertex_buffer_id);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
4,
GL_FLOAT,
GL_FALSE,
(sizeof(srvrtxdata)),
(void*)0
);
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
3,
GL_FLOAT,
GL_FALSE,
(sizeof(srvrtxdata)),
(void*)(sizeof(float) * 4)
);
// Attribute 2: texture coordinates
glEnableVertexAttribArray(2);
glVertexAttribPointer(
2,
2,
GL_FLOAT,
GL_FALSE,
(sizeof(srvrtxdata)),
(void*)(sizeof(float) * 7)
);
// Attribute 3: color
glEnableVertexAttribArray(3);
glVertexAttribPointer(
3,
4,
GL_UNSIGNED_BYTE,
GL_TRUE,
(sizeof(srvrtxdata)),
(void*)(sizeof(float) * 9)
);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gCoordFrameMesh.index_buffer_id);
glDrawElements(GL_LINES, 6, GL_UNSIGNED_INT, (void*)0);
}
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);
glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(gDefaultShader.program_id);
GLint view_mat_loc = glGetUniformLocation(gDefaultShader.program_id, "uViewMatrix");
assert (view_mat_loc != -1);
glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, &sview->view);
GLint proj_mat_loc = glGetUniformLocation(gDefaultShader.program_id, "uProjectionMatrix");
assert (proj_mat_loc != -1);
glUniformMatrix4fv(proj_mat_loc, 1, GL_FALSE, &sview->proj);
GLint model_mat_loc = glGetUniformLocation(gDefaultShader.program_id, "uModelMatrix");
assert (model_mat_loc != -1);
for (int i = 0; i < scmdbuf->ncmds; i++) {
const srcmd* cmd = &scmdbuf->cmds[i];
glUniformMatrix4fv(model_mat_loc, 1, GL_FALSE, &cmd->mat);
switch (cmd->type) {
case SRndrCmdTypeFrame:
srndr_run_frame_command(cmd);
break;
default:
gLog("Invalid command type %d at index %d", cmd->type, i);
break;
}
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
@ -238,23 +454,21 @@ void srndr_render(srndr* srndr, srview* sview, srcmdbuf* scmdbuf) {
//
// 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);
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;
return result;
}
void srcmdbuf_clear (srcmdbuf* cmdbuf) {
cmdbuf->idx = 0;
}
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++]);
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++]);
}

View File

@ -56,9 +56,12 @@ static void opengl_error_callback(
GLsizei length,
const GLchar* message,
const void* userParam) {
gLog ("OpenGL Error: %s type %0x%x, severity = 0x%x, message = %s",
( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
type, severity, message );
gLog(
"OpenGL Error: %s type %0x%x, severity = 0x%x, message = %s",
(type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""),
type,
severity,
message);
}
static void
@ -156,26 +159,31 @@ void DoRender() {
// Render Output
ImGui::Begin("Render Output");
// Update the view
// Update the view
const ImVec2 content_avail = ImGui::GetContentRegionAvail();
srview_set_size(gView, content_avail.x, content_avail.y);
simd4x4f view;
simd4x4f proj;
simd4x4f_identity (&view);
simd4x4f_identity (&proj);
srview_set_view(gView, view);
srview_set_view(gView, proj);
simd4x4f view;
simd4x4f proj;
simd4x4f_translation(&view, 0.1f, 0.1f, -0.1f);
simd4x4f_lookat(
&view,
simd4f_create(1.f, 1.f, 1.f, 1.f),
simd4f_create(0.f, 0.f, 0.f, 1.f),
simd4f_create(0.f, 1.f, 0.f, 1.f));
simd4x4f_ortho(&proj, -5.0f, 5.0f, -5.0f, 5.0f, -5.0f, 5.0f);
srview_set_view(gView, view);
srview_set_proj(gView, proj);
// Populate render commands
srcmdbuf_clear(gRndrCmds);
srcmd* cmd = srcmd_create (gRndrCmds);
cmd->type = SRndrCmdTypeFrame;
simd4x4f_identity(&cmd->mat);
cmd->color = simd4f_create (1.f, 1.f, 1.f, 1.f);
// Populate render commands
srcmdbuf_clear(gRndrCmds);
srcmd* cmd = srcmd_create(gRndrCmds);
cmd->type = SRndrCmdTypeFrame;
simd4x4f_identity(&cmd->mat);
cmd->color = simd4f_create(1.f, 1.f, 1.f, 1.f);
// Perform the actual render
// Perform the actual render
srndr_render(gRndr, gView, gRndrCmds);
GLuint view_texture;
GLuint view_texture;
srview_get_output_texture(gView, &view_texture);
ImGui::Image(
@ -267,6 +275,7 @@ int main(void) {
gRndr = srndr_create();
gView = srview_create();
gRndrCmds = srcmdbuf_create(1024);
while (!glfwWindowShouldClose(gWindow)) {
frame_counter++;