Created
May 9, 2013 18:43
-
-
Save jsimmons/c7f76de823d5d58829d8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <stddef.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <time.h> | |
#include <math.h> | |
#ifndef M_PI | |
#define M_PI 3.14159265358979323846264338327 | |
#endif | |
#include "sgl.h" | |
#include "jsb_chrono.h" | |
#include "jsb_vec.h" | |
#include "jsb_mat.h" | |
#include "gl_core_3_3.h" | |
static const char *vert_shader_src = | |
"#version 150\n" | |
"uniform mat4 clip_from_model;" | |
"layout(location = 0) in vec3 position;" | |
"layout(location = 1) in vec3 color;" | |
"layout(location = 2) out vec3 vert_color;" | |
"out gl_PerVertex" | |
"{" | |
" vec4 gl_Position;" | |
" float gl_PointSize;" | |
"};" | |
"void main() {" | |
" vert_color = color;" | |
" gl_Position = clip_from_model * vec4(position, 1.0);" | |
" gl_PointSize = 2.0;" | |
"}"; | |
static const char *frag_shader_src = | |
"#version 150\n" | |
"layout(location = 2) in vec3 color;" | |
"layout(location = 0) out vec3 frag_color;" | |
"void main() {" | |
" frag_color = color;" | |
"}"; | |
static unsigned vao, vbo; | |
static unsigned vert, frag, pipe; | |
static int clip_from_model_uniform; | |
static struct jsb_mat4 view_from_world = {.mat={0}}, clip_from_view = {.mat={0}}, clip_from_model = {.mat={0}}; | |
static void check_program(unsigned program) | |
{ | |
int linked; | |
glGetProgramiv(program, GL_LINK_STATUS, &linked); | |
if(linked == GL_FALSE) | |
{ | |
int info_log_size; | |
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_size); | |
char *info_log = malloc(info_log_size); | |
glGetProgramInfoLog(program, info_log_size, NULL, info_log); | |
fprintf(stderr, "error compiling shader program:\n%s", info_log); | |
free(info_log); | |
exit(1); | |
} | |
} | |
static void check_pipeline(unsigned pipeline) | |
{ | |
int validated; | |
glValidateProgramPipeline(pipeline); | |
glGetProgramPipelineiv(pipeline, GL_VALIDATE_STATUS, &validated); | |
if(validated == GL_FALSE) | |
{ | |
int info_log_size; | |
glGetProgramPipelineiv(pipeline, GL_INFO_LOG_LENGTH, &info_log_size); | |
char *info_log = malloc(info_log_size); | |
glGetProgramPipelineInfoLog(pipeline, info_log_size, NULL, info_log); | |
fprintf(stderr, "error validating program pipeline:\n%s", info_log); | |
free(info_log); | |
exit(1); | |
} | |
} | |
static struct jsb_vec3 hello_cube[] = { | |
{.xyz={ 1.0f, 1.0f, 1.0f}}, {.xyz={1.0f, 0.0f, 0.0f}}, {.xyz={-1.0f, 1.0f, 1.0f}}, {.xyz={1.0f, 0.0f, 0.0f}}, {.xyz={-1.0f,-1.0f, 1.0f}}, {.xyz={1.0f, 0.0f, 0.0f}}, // v0-v1-v2 (front) | |
{.xyz={-1.0f,-1.0f, 1.0f}}, {.xyz={1.0f, 0.0f, 0.0f}}, {.xyz={ 1.0f,-1.0f, 1.0f}}, {.xyz={1.0f, 0.0f, 0.0f}}, {.xyz={ 1.0f, 1.0f, 1.0f}}, {.xyz={1.0f, 0.0f, 0.0f}}, // v2-v3-v0 | |
{.xyz={ 1.0f, 1.0f, 1.0f}}, {.xyz={0.0f, 1.0f, 0.0f}}, {.xyz={ 1.0f,-1.0f, 1.0f}}, {.xyz={0.0f, 1.0f, 0.0f}}, {.xyz={ 1.0f,-1.0f,-1.0f}}, {.xyz={0.0f, 1.0f, 0.0f}}, // v0-v3-v4 (right) | |
{.xyz={ 1.0f,-1.0f,-1.0f}}, {.xyz={0.0f, 1.0f, 0.0f}}, {.xyz={ 1.0f, 1.0f,-1.0f}}, {.xyz={0.0f, 1.0f, 0.0f}}, {.xyz={ 1.0f, 1.0f, 1.0f}}, {.xyz={0.0f, 1.0f, 0.0f}}, // v4-v5-v0 | |
{.xyz={ 1.0f, 1.0f, 1.0f}}, {.xyz={0.0f, 0.0f, 1.0f}}, {.xyz={ 1.0f, 1.0f,-1.0f}}, {.xyz={0.0f, 0.0f, 1.0f}}, {.xyz={-1.0f, 1.0f,-1.0f}}, {.xyz={0.0f, 0.0f, 1.0f}}, // v0-v5-v6 (top) | |
{.xyz={-1.0f, 1.0f,-1.0f}}, {.xyz={0.0f, 0.0f, 1.0f}}, {.xyz={-1.0f, 1.0f, 1.0f}}, {.xyz={0.0f, 0.0f, 1.0f}}, {.xyz={ 1.0f, 1.0f, 1.0f}}, {.xyz={0.0f, 0.0f, 1.0f}}, // v6-v1-v0 | |
{.xyz={-1.0f, 1.0f, 1.0f}}, {.xyz={1.0f, 1.0f, 0.0f}}, {.xyz={-1.0f, 1.0f,-1.0f}}, {.xyz={1.0f, 1.0f, 0.0f}}, {.xyz={-1.0f,-1.0f,-1.0f}}, {.xyz={1.0f, 1.0f, 0.0f}}, // v1-v6-v7 (left) | |
{.xyz={-1.0f,-1.0f,-1.0f}}, {.xyz={1.0f, 1.0f, 0.0f}}, {.xyz={-1.0f,-1.0f, 1.0f}}, {.xyz={1.0f, 1.0f, 0.0f}}, {.xyz={-1.0f, 1.0f, 1.0f}}, {.xyz={1.0f, 1.0f, 0.0f}}, // v7-v2-v1 | |
{.xyz={-1.0f,-1.0f,-1.0f}}, {.xyz={0.0f, 1.0f, 1.0f}}, {.xyz={ 1.0f,-1.0f,-1.0f}}, {.xyz={0.0f, 1.0f, 1.0f}}, {.xyz={ 1.0f,-1.0f, 1.0f}}, {.xyz={0.0f, 1.0f, 1.0f}}, // v7-v4-v3 (bottom) | |
{.xyz={ 1.0f,-1.0f, 1.0f}}, {.xyz={0.0f, 1.0f, 1.0f}}, {.xyz={-1.0f,-1.0f, 1.0f}}, {.xyz={0.0f, 1.0f, 1.0f}}, {.xyz={-1.0f,-1.0f,-1.0f}}, {.xyz={0.0f, 1.0f, 1.0f}}, // v3-v2-v7 | |
{.xyz={ 1.0f,-1.0f,-1.0f}}, {.xyz={1.0f, 1.0f, 1.0f}}, {.xyz={-1.0f,-1.0f,-1.0f}}, {.xyz={1.0f, 1.0f, 1.0f}}, {.xyz={-1.0f, 1.0f,-1.0f}}, {.xyz={1.0f, 1.0f, 1.0f}}, // v4-v7-v6 (back) | |
{.xyz={-1.0f, 1.0f,-1.0f}}, {.xyz={1.0f, 1.0f, 1.0f}}, {.xyz={ 1.0f, 1.0f,-1.0f}}, {.xyz={1.0f, 1.0f, 1.0f}}, {.xyz={ 1.0f,-1.0f,-1.0f}}, {.xyz={1.0f, 1.0f, 1.0f}} // v6-v5-v4 | |
}; | |
struct point_set | |
{ | |
size_t num_points; | |
struct jsb_vec3 *points; | |
}; | |
static struct point_set ps; | |
static inline float random_float(float min, float max) | |
{ | |
return min + (float)rand() / ((float)RAND_MAX / (max - min)); | |
} | |
static void build_point_set(struct point_set *self, size_t num_points) | |
{ | |
srand((unsigned)time(0)); | |
self->num_points = num_points; | |
self->points = malloc(sizeof(struct jsb_vec3) * num_points); | |
for(size_t i = 0; i < num_points; i++) | |
{ | |
// comma operatorrrr | |
float x = random_float(-100.0f, 100.0f), y = random_float(-100.0f, 100.0f), z = random_float(-100.0f, 100.0f); | |
self->points[i].xyz[0] = x; | |
self->points[i].xyz[1] = y; | |
self->points[i].xyz[2] = z; | |
} | |
} | |
static void turn_setup(void) | |
{ | |
(void)hello_cube; // unused | |
glGenProgramPipelines(1, &pipe); | |
glBindProgramPipeline(pipe); | |
vert = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vert_shader_src); | |
check_program(vert); | |
glUseProgramStages(pipe, GL_VERTEX_SHADER_BIT, vert); | |
frag = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &frag_shader_src); | |
check_program(frag); | |
glUseProgramStages(pipe, GL_FRAGMENT_SHADER_BIT, frag); | |
check_pipeline(pipe); | |
clip_from_model_uniform = glGetUniformLocation(vert, "clip_from_model"); | |
uint64_t build_point_set_begin = jsb_chrono_monotonic(); | |
build_point_set(&ps, 16384); | |
uint64_t build_point_set_end = jsb_chrono_monotonic(); | |
printf("build point set took %zuµs\n", build_point_set_end - build_point_set_begin); | |
glGenBuffers(1, &vbo); | |
glBindBuffer(GL_ARRAY_BUFFER, vbo); | |
glNamedBufferDataEXT(vbo, ps.num_points * sizeof(struct jsb_vec3), ps.points, GL_STATIC_DRAW); | |
glGenVertexArrays(1, &vao); | |
glBindVertexArray(vao); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); | |
//glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); | |
glEnableVertexAttribArray(0); | |
//glEnableVertexAttribArray(1); | |
jsb_mat4_perspective(clip_from_view.mat, M_PI * 0.5, 1366.0f / 768.0f, 0.5, 500.0f); | |
} | |
struct jsb_vec3 eye = {.xyz = {100.0f, 100.0f, 100.0f}}; | |
static float accum = 0.0f; | |
static void turn_draw(void) | |
{ | |
accum += 0.0025; | |
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); | |
glClear(GL_COLOR_BUFFER_BIT); | |
struct jsb_vec3 at = {.xyz = {0.0f, 0.0f, 0.0f}}; | |
struct jsb_vec3 up = {.xyz = {0.0f, 0.0f, 1.0f}}; | |
jsb_mat4_look_at(view_from_world.mat, eye.xyz, at.xyz, up.xyz); | |
struct jsb_mat4 world_from_model; | |
struct jsb_vec3 rotation_axis = {.xyz={0.0f, 0.0f, 1.0f}}; | |
jsb_mat4_rotate(world_from_model.mat, JSB_MAT4_IDENTITY.mat, accum, rotation_axis.xyz); | |
struct jsb_mat4 clip_from_world; | |
jsb_mat4_mul(clip_from_world.mat, clip_from_view.mat, view_from_world.mat); | |
jsb_mat4_mul(clip_from_model.mat, clip_from_world.mat, world_from_model.mat); | |
glProgramUniformMatrix4fvEXT(vert, clip_from_model_uniform, 1, false, clip_from_model.mat); | |
glEnable(GL_CULL_FACE); | |
glEnable(GL_PROGRAM_POINT_SIZE); | |
glDrawArrays(GL_POINTS, 0, ps.num_points); | |
} | |
static void turn_entry(void) | |
{ | |
jsb_chrono_startup(); | |
sgl_startup(); | |
struct sgl_window_options window_options = { | |
.x = 0, | |
.y = 0, | |
.width = 800, | |
.height = 600, | |
.colour_bits = 32, | |
.depth_bits = 24, | |
.stencil_bits = 8, | |
.msaa_samples = 4, | |
.double_buffer = true, | |
.vertical_sync = true, | |
.stereo = false | |
}; | |
struct sgl_window *window = sgl_window_create(&window_options); | |
assert(window); | |
sgl_window_set_title(window, "TURN"); | |
sgl_window_set_cursor_visible(window, false); | |
sgl_window_set_fullscreen(window, true); | |
sgl_window_set_monitors(window, 0, 0, 0, 0); | |
struct sgl_context_options context_options = { | |
.version_major = 3, | |
.version_minor = 3, | |
.core_profile = true, /* core profile */ | |
.forward_compatible = true, /* forward compatibility */ | |
.debug = true, /* enable context debugging */ | |
.share = NULL /* pass a struct sgl_context * to share | |
data between contexts */ | |
}; | |
struct sgl_context *context = sgl_context_create(window, &context_options); | |
assert(context); | |
sgl_context_bind(window, context); | |
gl_core_load(); | |
turn_setup(); | |
struct sgl_event event; | |
for(;;) | |
{ | |
while(sgl_event_read(window, &event)) | |
{ | |
switch(event.type) | |
{ | |
case SGL_EVENT_GEOMETRY: | |
break; | |
case SGL_EVENT_LEAVE: | |
case SGL_EVENT_FOCUS_OUT: | |
break; | |
case SGL_EVENT_ENTER: | |
case SGL_EVENT_FOCUS_IN: | |
break; | |
case SGL_EVENT_BUTTON_PRESS: | |
break; | |
case SGL_EVENT_BUTTON_RELEASE: | |
break; | |
case SGL_EVENT_KEY_PRESS: | |
switch(event.device.unicode) | |
{ | |
case 'w': | |
eye.xyz[1] -= 10.0; | |
break; | |
case 's': | |
eye.xyz[1] += 10.0; | |
break; | |
case 'a': | |
eye.xyz[0] -= 10.0; | |
break; | |
case 'd': | |
eye.xyz[0] += 10.0; | |
break; | |
case 'z': | |
eye.xyz[2] += 10.0; | |
break; | |
case 'x': | |
eye.xyz[2] -= 10.0; | |
break; | |
case '\x1B': | |
goto shutdown; | |
default: | |
break; | |
} | |
break; | |
case SGL_EVENT_KEY_RELEASE: | |
break; | |
case SGL_EVENT_MOTION: | |
break; | |
case SGL_EVENT_RAW_MOTION: | |
break; | |
case SGL_EVENT_CLOSE: | |
printf("shutting down!\n"); | |
goto shutdown; | |
break; | |
default: | |
break; | |
} | |
} | |
turn_draw(); | |
sgl_window_swap(window); | |
} | |
shutdown: | |
sgl_context_unbind(); | |
sgl_context_destroy(context); | |
sgl_window_destroy(window); | |
sgl_cleanup(); | |
} | |
int main(int argc, const char **argv) | |
{ | |
(void)argc; | |
(void)argv; | |
turn_entry(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment