summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--assets/fragment.glsl6
-rw-r--r--assets/vertex.glsl24
m---------linmath.h0
-rw-r--r--meson.build5
-rw-r--r--src/hacks.h81
-rw-r--r--src/main.c149
7 files changed, 243 insertions, 25 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..1d0fe9b
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "linmath.h"]
+ path = linmath.h
+ url = https://github.com/datenwolf/linmath.h
diff --git a/assets/fragment.glsl b/assets/fragment.glsl
index d6a6b52..a189112 100644
--- a/assets/fragment.glsl
+++ b/assets/fragment.glsl
@@ -1,12 +1,12 @@
#version 430 core
-in vec2 texCoords;
+in vec2 fTexCoords;
-out vec4 outColor;
+out vec4 oColor;
uniform sampler2D texture0;
void main()
{
- outColor = texture(texture0, texCoords);
+ oColor = texture(texture0, fTexCoords);
}
diff --git a/assets/vertex.glsl b/assets/vertex.glsl
index 15140cf..ec8c0b6 100644
--- a/assets/vertex.glsl
+++ b/assets/vertex.glsl
@@ -1,11 +1,27 @@
#version 430 core
-layout(location = 0) in vec2 vertexPosition;
+layout(location = 0) in vec4 vPos;
+layout(location = 1) in vec2 vTexCoord;
+//layout(location = 1) in vec3 vNormal;
-out vec2 texCoords;
+//out vec3 fPos;
+//out vec3 fNormal;
+out vec2 fTexCoords;
+
+uniform mat4 model;
+uniform mat4 viewProj;
+
+/*
+uniform mat4 viewProj;
+uniform mat3 normalTransform;*/
void main()
{
- gl_Position = vec4(vertexPosition, 0.0, 1.0);
- texCoords = vertexPosition + vec2(0.5);
+ vec4 pos = vPos;
+ pos = model * pos;
+ pos.w = pos.w + 2.0;
+ gl_Position = viewProj * (pos / pos.w);
+
+ //gl_Position = viewProj * model * vec4(vPos.xyz, 1.0);
+ fTexCoords = vTexCoord;
}
diff --git a/linmath.h b/linmath.h
new file mode 160000
+Subproject 3eef82841046507e16a0f6194a61cee2eadd34b
diff --git a/meson.build b/meson.build
index 96ed03b..a9e41c6 100644
--- a/meson.build
+++ b/meson.build
@@ -2,9 +2,12 @@ project('juxtapos', 'c', default_options: ['warning_level=2'])
add_project_arguments('-DGLEW_NO_GLU', language: 'c')
+cc = meson.get_compiler('c')
+
gl = dependency('gl')
glfw = dependency('glfw3')
glew = dependency('glew')
+m = cc.find_library('m', required: false)
embed = generator(find_program('python3'),
output: '@PLAINNAME@.h',
@@ -23,7 +26,7 @@ juxtapos = executable('juxtapos',
'assets/fragment.glsl',
]),
],
- dependencies: [glfw, glew],
+ dependencies: [glfw, glew, m],
install: true,
)
diff --git a/src/hacks.h b/src/hacks.h
new file mode 100644
index 0000000..4846fd1
--- /dev/null
+++ b/src/hacks.h
@@ -0,0 +1,81 @@
+#define NONE(...)
+#define ID(X, ...) X
+#define CALL(F, ...) F(__VA_ARGS__)
+#define EXPAND(...) __VA_ARGS__
+#define BRACE(...) (__VA_ARGS__)
+
+#define IF_0(t, f) f
+#define IF_1(t, f) t
+#define IF_(cond) IF_##cond
+#define IF(cond, t, f) IF_(cond)(t, f)
+
+// add more iterations as needed
+#define FOLD_(F, init, x0, x1, x2, x3, x4, x5, x6, x7, ...) \
+ F(F(F(F(F(F(F(F(init, x0), x1), x2), x3), x4), x5), x6), x7)
+#define FOLD(NIL,...) FOLD_(__VA_ARGS__,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL)
+
+#define GET1(x, ...) x
+#define GET2(x, ...) GET1(__VA_ARGS__)
+#define GET3(x, ...) GET2(__VA_ARGS__)
+
+// add more EQUALS_X_X as needed
+#define EQUALS_0_0 ~, 1
+#define EQUALS_1_1 ~, 1
+#define EQUALS_2_2 ~, 1
+#define EQUALS(X, Y) ID(GET2 BRACE(EQUALS_##X##_##Y, 0))
+
+/*
+#define COMMA(...) ,
+#define HAS_COMMA(...) HAS_COMMA_1(__VA_ARGS__, COMMA(), ~)
+#define HAS_COMMA_1(A, B, ...) HAS_COMMA_2(B, 0, 1, ~)
+#define HAS_COMMA_2(A, B, C, ...) C
+
+#define TRUE(...) 1
+#define FALSE(...) 0
+#define NOT(X) IF(X, 0, 1)
+#define OR(A, B) IF(A, 1, B)
+#define AND(A, B) IF(A, B, 0)
+
+#define IS_CALL(X, ...) HAS_COMMA(ID(COMMA X))
+
+#define AND3(A, B, C) AND(A, AND(B, C))
+
+#define IS_EMPTY(...) AND3( \
+ NOT(HAS_COMMA(__VA_ARGS__)), \
+ NOT(IS_CALL(__VA_ARGS__)), \
+ HAS_COMMA(COMMA __VA_ARGS__ ()))
+*/
+
+#define T_BYTE (1, GLbyte, GL_BYTE)
+#define T_UBYTE (1, GLubyte, GL_UNSIGNED_BYTE)
+#define T_SHORT (1, GLshort, GL_SHORT)
+#define T_USHORT (1, GLushort, GL_UNSIGNED_SHORT)
+#define T_INT (1, GLint, GL_INT)
+#define T_UINT (1, GLuint, GL_UNSIGNED_INT)
+#define T_FIXED (1, GLfixed, GL_FIXED)
+#define T_HALF (1, GLhalf, GL_HALF_FLOAT)
+#define T_FLOAT (1, GLfloat, GL_FLOAT)
+#define T_DOUBLE (1, GLdouble, GL_DOUBLE)
+
+#define T_PRESENT(x) ID(GET1 x)
+#define T_TYPE(x) ID(GET2 x)
+#define T_CONST(x) ID(GET3 x)
+
+#define VERTEX_DEF_FOLD(struct_name, buf_struct, buf_func, index, type, name, count, ...) ( \
+ struct_name, \
+ buf_struct T_TYPE(type) name IF(EQUALS(count, 1),,[count]);, \
+ buf_func \
+ glVertexAttribPointer(index, count, T_CONST(type), \
+ GL_FALSE, sizeof(struct struct_name), (GLvoid *) offsetof(struct struct_name, name)); \
+ glEnableVertexAttribArray(index);, \
+ (1 + index))
+
+#define VERTEX_DEF_FOLD_WRAP(buf, attr) \
+ IF(T_PRESENT(GET1 attr), CALL(VERTEX_DEF_FOLD, EXPAND buf, EXPAND attr, 1), buf)
+
+#define VERTEX_DEF_EMIT(name, buf_struct, buf_func, _) \
+ struct name { buf_struct }; \
+ void name ## _configure_vao() { buf_func };
+
+#define VERTEX_DEF(name, ...) ID(VERTEX_DEF_EMIT FOLD(((0, ~, ~), ~, 0), VERTEX_DEF_FOLD_WRAP, \
+ (name,,, 0), __VA_ARGS__))
diff --git a/src/main.c b/src/main.c
index 1e1ea8e..b806e39 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4,6 +4,7 @@
#include <GL/glew.h>
#include <GL/gl.h>
#include <GLFW/glfw3.h>
+#include "../linmath.h/linmath.h"
static void opengl_error(GLenum err, const char *file, int line)
{
@@ -33,12 +34,22 @@ struct shader {
size_t len;
};
+int win_width, win_height;
+
static void framebuffer_size_callback(GLFWwindow *handle, int width, int height)
{
(void) handle;
glViewport(0, 0, width, height);
+ win_width = width;
+ win_height = height;
}
+#define glUniform(loc, x) _Generic((x), \
+ GLfloat: glUniform1f, \
+ GLint: glUniform1i, \
+ GLuint: glUniform1ui \
+ )(loc, x)
+
GLuint shader_program_create(const char *name, struct shader *shaders, size_t num_shaders)
{
GLuint prog_id = glCreateProgram();
@@ -83,6 +94,13 @@ GLuint shader_program_create(const char *name, struct shader *shaders, size_t nu
#define GL_DEBUG opengl_debug(__FILE__, __LINE__);
+#include "hacks.h"
+
+VERTEX_DEF(vertex,
+ (T_FLOAT, pos, 4),
+ (T_FLOAT, texCoord, 2)
+)
+
int main()
{
if (!glfwInit()) {
@@ -90,17 +108,23 @@ int main()
exit(EXIT_FAILURE);
}
+ //FST(FLOAT) x = 0.0;
+ //MEOW(int) a = 0;
+ //int a = MEW();
+ //int a = CALL(_1, PAIR(1,2));
+ //int b = CALL(_2, FLOAT);
+
atexit(glfwTerminate);
- // glfwWindowHint(GLFW_SAMPLES, 8);
+ glfwWindowHint(GLFW_SAMPLES, 8);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- int win_w = 1000;
- int win_h = 1000;
+ win_width = 1025;
+ win_height = 750;
- GLFWwindow *window = glfwCreateWindow(win_w, win_h, "Juxtapos", NULL, NULL);
+ GLFWwindow *window = glfwCreateWindow(win_width, win_height, "Juxtapos", NULL, NULL);
if (window == NULL) {
fprintf(stderr, "[error] failed to create window\n");
exit(EXIT_FAILURE);
@@ -113,11 +137,11 @@ int main()
exit(EXIT_FAILURE);
}
- glViewport(0, 0, win_w, win_h);
+ glViewport(0, 0, win_width, win_height);
glfwSetFramebufferSizeCallback(window, &framebuffer_size_callback);
// dimensions of the image
- int tex_w = 1000, tex_h = 1000;
+ int tex_w = 480, tex_h = 480;
GLuint wood_texture;
glGenTextures(1, &wood_texture);
@@ -167,44 +191,135 @@ int main()
{ "fragment", GL_FRAGMENT_SHADER, fragment_shader_src, sizeof fragment_shader_src },
}, 2);
- GLfloat quad[4][2] = {
- { -0.5, +0.5 },
- { -0.5, -0.5 },
- { +0.5, +0.5 },
- { +0.5, -0.5 },
- };
+ GLint loc_model = glGetUniformLocation(main_shader, "model");
+ GLint loc_viewProj = glGetUniformLocation(main_shader, "viewProj");
+
+ /*struct vertex cube[3][2][2][2];
+ for (int i = 0; i < 3; i++)
+ // for those, i noticed i can replace them with a single loop and use bit manipulation
+ for (int a = 0; a <= 1; a++)
+ for (int b = 0; b <= 1; b++)
+ for (int c = 0; c <= 1; c++) {
+ struct vertex *v = &cube[i][a][b][c];
+ // this simply turned into a loop over k
+ v->pos[(i+0)%3] = a * 2.0 - 1.0;
+ v->pos[(i+1)%3] = b * 2.0 - 1.0;
+ v->pos[(i+2)%3] = c * 2.0 - 1.0;
+ }*/
+
+/*#define DIM 3
+ struct vertex vertices[DIM][1 << DIM] = { 0 };
+ for (int i = 0; i < DIM; i++)
+ for (int j = 0; j < 1 << DIM; j++)
+ for (int k = 0; k < DIM; k++)
+ vertices[i][j].pos[(i+k)%DIM] = ((j >> k) & 1) * 2.0 - 1.0;
+*/
+
+ /*GLuint indices[DIM][1 << DIM][2];
+ for (int i = 0; i < DIM; i++)
+ for (int j = 0; j < 1 << DIM; j++)
+ indices[i][j][1] = (indices[i][j][0] = j) ^ (1 << i);*/
+
+#define DIM 0
+ struct vertex vertices[1 << DIM] = { 0 };
+ for (int j = 0; j < 1 << DIM; j++)
+ for (int k = 0; k < DIM; k++)
+ vertices[j].pos[k] = ((j >> k) & 1) * 2.0 - 1.0;
+
+#define BITS_FROM(x, i) ((x) & ((~0U) << (i))) // select all bits above and including bit
+#define BITS_TO(x, i) ((x) & ~((~0U) << (i))) // select all bits below bit i
+
+ GLuint indices[DIM][1 << (DIM-1)][2];
+ for (unsigned int i = 0; i < DIM; i++)
+ for (unsigned int j = 0; j < 1 << (DIM-1); j++)
+ indices[i][j][1] = (indices[i][j][0] = (
+ BITS_FROM(j, i) << 1 | BITS_TO(j, i)
+ )) | (1 << i);
+
+ //for ()
+
+ /*GLuint indices[ CUBE_LEN/4 ][8];
+ for (int i = 0; i < CUBE_LEN/4; i++) {
+ for (int j = 0; j < 8; j++)
+ indices[i][j] = i*4 + (((j+1) % 8) / 2);
+ }*/
+
+ /*
+ GLuint indices[6][6];
+ for (int i = 0; i < 6; i++) {
+ GLuint quad[6] = { 0, 1, 2, 2, 3, 1 };
+ for (int j = 0; j < 6; j++)
+ indices[i][j] = i*4 + quad[j];
+ }*/
- GLuint vao, vbo;
+ /*
+ struct vertex_quad quad[4] = {
+ {{ -0.5, +0.5, +0.0 }},
+ {{ -0.5, -0.5, +0.0 }},
+ {{ +0.5, +0.5, +0.0 }},
+ {{ +0.5, -0.5, +0.0 }},
+ };*/
+
+ GLuint vao, vbo, ebo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
+ glGenBuffers(1, &ebo);
glBindVertexArray(vao);
+
glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW);
- glBufferData(GL_ARRAY_BUFFER, sizeof quad, quad, GL_STATIC_DRAW);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof indices, indices, GL_STATIC_DRAW);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof *quad, 0);
- glEnableVertexAttribArray(0);
+ vertex_configure_vao();
unsigned int skyblue = 0x87ceeb;
glClearColor(
((skyblue >> 16) & 0xff) / 255.0,
((skyblue >> 8) & 0xff) / 255.0,
((skyblue >> 0) & 0xff) / 255.0, 1.0);
+ glPointSize(5.0);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
+
+ glfwSetTime(0.0);
while (!glfwWindowShouldClose(window)) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, GLFW_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_DEPTH_TEST);
// preview wood texture
glUseProgram(main_shader);
+
+ mat4x4 proj;
+ mat4x4_perspective(proj, 90.0, (float) win_width / (float) win_height, 0.1, 100.0);
+
+ vec3 up;
+ vec3_norm(up, (vec3) { 0.0, 1.0, -1.0 });
+
+ mat4x4 view;
+ mat4x4_look_at(view, (vec3) { 0.0, 2.0, 2.0 }, (vec3) { 0, 0, 0 }, up);
+
+ mat4x4 view_proj;
+ mat4x4_mul(view_proj, proj, view);
+
+ mat4x4 id;
+ mat4x4_identity(id);
+ mat4x4 model;
+ mat4x4_rotate_Y(model, id, glfwGetTime() * M_PI * 0.1);
+
+ glUniformMatrix4fv(loc_model, 1, GL_FALSE, &model[0][0]);
+ glUniformMatrix4fv(loc_viewProj, 1, GL_FALSE, &view_proj[0][0]);
+
glBindVertexArray(vao);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, wood_texture);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ //glDrawArrays(GL_POINTS, 0, sizeof vertices / sizeof(struct vertex));
+ glDrawElements(GL_LINES, sizeof indices / sizeof(GLuint), GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();