summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2019-09-15 14:21:43 +0200
committerLudovic Pouzenc <ludovic@pouzenc.fr>2019-09-15 14:21:43 +0200
commit00ff773ea10dba1fd4c1a2bb09c1ec811a798af3 (patch)
tree9c000214d6b2d2b0cc93f598341aa51c45a7d32f
parentb6ab2f2c62e593edb50508e0b911a01fe773122f (diff)
downloaddemoscene-eo-00ff773ea10dba1fd4c1a2bb09c1ec811a798af3.tar.gz
demoscene-eo-00ff773ea10dba1fd4c1a2bb09c1ec811a798af3.tar.bz2
demoscene-eo-00ff773ea10dba1fd4c1a2bb09c1ec811a798af3.zip
WIP: utils.c for factoring opengl tedious tasks, switch to OpenGL 3.3HEADmaster
For now, it display nothing, shaders changed without updating client code.
-rw-r--r--res/scene01_fs_colorfultest.glsl5
-rw-r--r--res/scene01_vs_basic.glsl12
-rw-r--r--src/Makefile.am2
-rw-r--r--src/demoscene-eo.c6
-rw-r--r--src/scene01.c80
-rw-r--r--src/utils.c114
-rw-r--r--src/utils.h13
7 files changed, 165 insertions, 67 deletions
diff --git a/res/scene01_fs_colorfultest.glsl b/res/scene01_fs_colorfultest.glsl
new file mode 100644
index 0000000..15e33a1
--- /dev/null
+++ b/res/scene01_fs_colorfultest.glsl
@@ -0,0 +1,5 @@
+#version 330 core
+out vec3 color;
+void main(){
+ color = vec3(1,0,0);
+}
diff --git a/res/scene01_vs_basic.glsl b/res/scene01_vs_basic.glsl
new file mode 100644
index 0000000..6f7c56f
--- /dev/null
+++ b/res/scene01_vs_basic.glsl
@@ -0,0 +1,12 @@
+#version 330 core
+
+// Input vertex data, different for all executions of this shader.
+layout(location = 0) in vec3 vertexPosition_modelspace;
+
+// Values that stay constant for the whole mesh.
+uniform mat4 MVP;
+
+void main(){
+ // Output position of the vertex, in clip space : MVP * position
+ gl_Position = MVP * vec4(vertexPosition_modelspace,1);
+}
diff --git a/src/Makefile.am b/src/Makefile.am
index d9f8a72..b7acbeb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
bin_PROGRAMS = demoscene-eo
-demoscene_eo_SOURCES = demoscene-eo.c scene00.c scene01.c scene02.c
+demoscene_eo_SOURCES = demoscene-eo.c utils.c scene00.c scene01.c scene02.c
server-local: demoscene-eo
xterm -e $(SHELL) -c "sleep 1; nc -v localhost 51914; exec $(SHELL)" &
diff --git a/src/demoscene-eo.c b/src/demoscene-eo.c
index ed6fe1b..1c532be 100644
--- a/src/demoscene-eo.c
+++ b/src/demoscene-eo.c
@@ -159,7 +159,7 @@ int parent() {
case 2: res = scene02_init_caca(&shm->ge, &shm->s02e); break;
}
// If scene init fail, skip to the next one
- if (res) SCENE_NEXT; else lastscene = shm->scene;
+ if (res) { printf("scene%02i_init_caca() returned %i\n", shm->scene, res); SCENE_NEXT; } else lastscene = shm->scene;
}
shm->ge.sdl_ticks = SDL_GetTicks(); // This value wraps if the program runs for more than ~49 days
@@ -288,7 +288,7 @@ int worker_sdl() {
case 2: res = scene02_init_sdl(&shm->ge, &shm->s02e); break;
}
// If scene init fail, skip to the next one
- if (res) SCENE_NEXT; else lastscene = shm->scene;
+ if (res) { printf("scene%02i_init_sdl() returned %i\n", shm->scene, res); SCENE_NEXT; } else lastscene = shm->scene;
}
// Compute current scene frame (sdl part)
switch(shm->scene) {
@@ -413,7 +413,7 @@ int worker_gl() {
case 2: res = scene02_init_gl(&shm->ge, &shm->s02e); break;
}
// If scene init fail, skip to the next one
- if (res) SCENE_NEXT; else lastscene = shm->scene;
+ if (res) { printf("scene%02i_init_gl() returned %i\n", shm->scene, res); SCENE_NEXT; } else lastscene = shm->scene;
}
// Compute current scene frame (gl part)
diff --git a/src/scene01.c b/src/scene01.c
index a93aa3d..05457bc 100644
--- a/src/scene01.c
+++ b/src/scene01.c
@@ -18,55 +18,9 @@
* along with demoscene-eo. If not, see <http://www.gnu.org/licenses/>
*/
#include "scene01.h"
+#include "utils.h"
// Mostly inspired by CC0 https://gist.github.com/koute/7391344
-typedef float t_mat4x4[16];
-
-static inline void mat4x4_ortho(t_mat4x4 out, float left, float right, float bottom, float top, float znear, float zfar)
-{
- #define T(a, b) (a * 4 + b)
-
- out[T(0,0)] = 2.0f / (right - left);
- out[T(0,1)] = 0.0f;
- out[T(0,2)] = 0.0f;
- out[T(0,3)] = 0.0f;
-
- out[T(1,1)] = 2.0f / (top - bottom);
- out[T(1,0)] = 0.0f;
- out[T(1,2)] = 0.0f;
- out[T(1,3)] = 0.0f;
-
- out[T(2,2)] = -2.0f / (zfar - znear);
- out[T(2,0)] = 0.0f;
- out[T(2,1)] = 0.0f;
- out[T(2,3)] = 0.0f;
-
- out[T(3,0)] = -(right + left) / (right - left);
- out[T(3,1)] = -(top + bottom) / (top - bottom);
- out[T(3,2)] = -(zfar + znear) / (zfar - znear);
- out[T(3,3)] = 1.0f;
-
- #undef T
-}
-
-static const char * vertex_shader =
- "#version 130\n"
- "in vec2 i_position;\n"
- "in vec4 i_color;\n"
- "out vec4 v_color;\n"
- "uniform mat4 u_projection_matrix;\n"
- "void main() {\n"
- " v_color = i_color;\n"
- " gl_Position = u_projection_matrix * vec4(i_position, 0.0, 1.0);\n"
- "}\n";
-
-static const char * fragment_shader =
- "#version 130\n"
- "in vec4 v_color;\n"
- "out vec4 o_color;\n"
- "void main() {\n"
- " o_color = v_color;\n"
- "}\n";
typedef enum t_attrib_id
{
@@ -81,29 +35,29 @@ int scene01_init_gl(graphical_env_t *ge, scene01_env_t *se) {
TRACE("call");
vs = glCreateShader(GL_VERTEX_SHADER);
- fs = glCreateShader(GL_FRAGMENT_SHADER);
+ status = gl_compile_shader_from_file(vs, "res/scene01_vs_basic.glsl"); if (status) return 40+status;
- int length = strlen(vertex_shader);
- glShaderSource(vs, 1, (const GLchar **)&vertex_shader, &length);
- glCompileShader(vs);
-
- glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
- if(status == GL_FALSE) return 40;
-
- length = strlen(fragment_shader);
- glShaderSource(fs, 1, (const GLchar **)&fragment_shader, &length);
- glCompileShader(fs);
-
- glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
- if(status == GL_FALSE) return 41;
+ fs = glCreateShader(GL_FRAGMENT_SHADER);
+ status = gl_compile_shader_from_file(fs, "res/scene01_fs_colorfultest.glsl"); if (status) return 50+status;
program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
-
glBindAttribLocation(program, attrib_position, "i_position");
glBindAttribLocation(program, attrib_color, "i_color");
+
glLinkProgram(program);
+ glGetProgramiv(program, GL_LINK_STATUS, &status);
+
+ glDetachShader(program, vs);
+ glDetachShader(program, fs);
+ glDeleteShader(vs);
+ glDeleteShader(fs);
+
+ if(status == GL_FALSE) {
+ gl_trace_shader_or_program_log(program);
+ return 60;
+ }
glUseProgram(program);
@@ -171,7 +125,7 @@ int scene01_init_gl(graphical_env_t *ge, scene01_env_t *se) {
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
t_mat4x4 projection_matrix;
- mat4x4_ortho(projection_matrix, 0.0f, (float)FBUF_W, (float)FBUF_H, 0.0f, 0.0f, 100.0f);
+ gl_mat4x4_ortho(projection_matrix, 0.0f, (float)FBUF_W, (float)FBUF_H, 0.0f, 0.0f, 100.0f);
glUniformMatrix4fv(glGetUniformLocation(program, "u_projection_matrix"), 1, GL_FALSE, projection_matrix);
diff --git a/src/utils.c b/src/utils.c
new file mode 100644
index 0000000..a3c878e
--- /dev/null
+++ b/src/utils.c
@@ -0,0 +1,114 @@
+#include "utils.h"
+
+// Mostly inspired by CC0 https://gist.github.com/koute/7391344
+void gl_mat4x4_ortho(t_mat4x4 out, float left, float right, float bottom, float top, float znear, float zfar)
+{
+ #define T(a, b) (a * 4 + b)
+
+ out[T(0,0)] = 2.0f / (right - left);
+ out[T(0,1)] = 0.0f;
+ out[T(0,2)] = 0.0f;
+ out[T(0,3)] = 0.0f;
+
+ out[T(1,1)] = 2.0f / (top - bottom);
+ out[T(1,0)] = 0.0f;
+ out[T(1,2)] = 0.0f;
+ out[T(1,3)] = 0.0f;
+
+ out[T(2,2)] = -2.0f / (zfar - znear);
+ out[T(2,0)] = 0.0f;
+ out[T(2,1)] = 0.0f;
+ out[T(2,3)] = 0.0f;
+
+ out[T(3,0)] = -(right + left) / (right - left);
+ out[T(3,1)] = -(top + bottom) / (top - bottom);
+ out[T(3,2)] = -(zfar + znear) / (zfar - znear);
+ out[T(3,3)] = 1.0f;
+
+ #undef T
+}
+
+// Mostly inspired from https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_02
+
+// Store all the file's contents in memory, useful to pass shaders source code to OpenGL.
+const GLchar* gl_shaderfile_read(const char* path, Sint64 *out_fsize) {
+ GLchar *buf, *cursor;
+ SDL_RWops *rw;
+ Sint64 fsize;
+ size_t read;
+
+ rw = SDL_RWFromFile(path, "rb"); if (rw == NULL) return NULL;
+ fsize = SDL_RWsize(rw); if (fsize == -1) return NULL;
+ buf = malloc(fsize+1); if (buf == NULL) return NULL;
+
+ cursor = buf;
+ read = 0;
+ do {
+ cursor += read;
+ // Read at most to the end of buf
+ read = SDL_RWread(rw, cursor, 1, (fsize - (cursor-buf)));
+ } while ( read > 0 );
+ *cursor = '\0'; // Where the +1 is used from malloc() call
+
+ SDL_RWclose(rw);
+
+ // Check if we have read the whole thing
+ if ( (cursor-buf) != fsize) {
+ free(buf);
+ return NULL;
+ }
+
+ if (out_fsize != NULL) *out_fsize = fsize;
+ return buf;
+}
+
+/**
+ * Display compilation errors from the OpenGL shader compiler
+ */
+void gl_trace_shader_or_program_log(GLuint object) {
+ GLint log_length = 0;
+ char *log;
+
+ if (glIsShader(object)) {
+ glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
+ } else if (glIsProgram(object)) {
+ glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length);
+ } else {
+ TRACE("not a shader or a program");
+ return;
+ }
+
+ log = (char*)malloc(log_length);
+ if ( log == NULL ) {
+ TRACE("malloc failed");
+ return;
+ }
+
+ if (glIsShader(object))
+ glGetShaderInfoLog(object, log_length, NULL, log);
+ else if (glIsProgram(object))
+ glGetProgramInfoLog(object, log_length, NULL, log);
+
+ TRACE(log);
+ free(log);
+}
+
+GLint gl_compile_shader_from_file(GLuint shader, const char* path) {
+ Sint64 fsize;
+ GLint gl_fsize, status;
+
+ const GLchar *source = gl_shaderfile_read(path, &fsize);
+ if (source == NULL) return 1;
+
+ gl_fsize = (GLint) fsize;
+ glShaderSource(shader, 1, &source, &gl_fsize);
+ glCompileShader(shader);
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+ if(status == GL_FALSE) {
+ gl_trace_shader_or_program_log(shader);
+ return 2;
+ }
+
+ return 0;
+}
+
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 0000000..586e152
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,13 @@
+#ifndef UTILS_H_INCLUDED
+#define UTILS_H_INCLUDED
+
+#include "main.h"
+
+typedef float t_mat4x4[16];
+void gl_mat4x4_ortho(t_mat4x4 out, float left, float right, float bottom, float top, float znear, float zfar);
+
+const GLchar* gl_shaderfile_read(const char* path, Sint64 *out_fsize);
+void gl_trace_shader_or_program_log(GLuint object);
+GLint gl_compile_shader_from_file(GLuint shader, const char* path);
+
+#endif