commit 6377884c65418b193716b320c274f489ca5a69ef
Author: Brian Swetland <swetland@frotz.net>
Date: Sun, 13 Jan 2013 18:32:16 -0800
initial commit
Diffstat:
A | .gitignore | | | 2 | ++ |
A | Makefile | | | 26 | ++++++++++++++++++++++++++ |
A | cube-texture.png | | | 0 | |
A | cube-texture.xcf | | | 0 | |
A | extensions.c | | | 58 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | glue.h | | | 35 | +++++++++++++++++++++++++++++++++++ |
A | loadfile.c | | | 57 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | loadpng.c | | | 107 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | sdlglue.c | | | 146 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | test1.c | | | 109 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | test1.fragment.glsl | | | 6 | ++++++ |
A | test1.vertex.glsl | | | 10 | ++++++++++ |
A | test2.c | | | 158 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | texture1.png | | | 0 | |
A | util.c | | | 141 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | util.h | | | 56 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
16 files changed, 911 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
+*.o
+.*.swp
diff --git a/Makefile b/Makefile
@@ -0,0 +1,26 @@
+
+SDLCFG := sdl-config
+#SDLCFG := /work/sdl/bin/sdl2-config
+
+SDLFLAGS := $(shell $(SDLCFG) --cflags)
+SDLLIBS := $(shell $(SDLCFG) --libs)
+
+CFLAGS := $(SDLFLAGS) -DWITH_SDL2=0 -Wall
+LIBS := $(SDLLIBS) -lGL -lm -lpng
+
+COMMONOBJS := util.o sdlglue.o loadpng.o loadfile.o
+
+all: test1 test2
+
+TEST1OBJS := test1.o $(COMMONOBJS)
+
+test1: $(TEST1OBJS)
+ $(CC) -o test1 $(TEST1OBJS) $(LIBS)
+
+TEST2OBJS := test2.o $(COMMONOBJS)
+
+test2: $(TEST2OBJS)
+ $(CC) -o test2 $(TEST2OBJS) $(LIBS)
+
+clean::
+ rm -f test1 test2 *.o
diff --git a/cube-texture.png b/cube-texture.png
Binary files differ.
diff --git a/cube-texture.xcf b/cube-texture.xcf
Binary files differ.
diff --git a/extensions.c b/extensions.c
@@ -0,0 +1,58 @@
+
+/* not needed for linux */
+
+static PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
+static PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
+static PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
+static PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
+static PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
+static PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
+static PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
+static PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
+static PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
+static PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
+static PFNGLUNIFORM1IARBPROC glUniform1iARB;
+static PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
+
+#define EFUNC(n) { (void**) &n, #n }
+
+#if !WITH_SDL2
+int SDL_GL_ExtensionSupported(const char *name) {
+ if (strstr((char*)glGetString(GL_EXTENSIONS), name))
+ return 1;
+ else
+ return 0;
+}
+#endif
+
+struct {
+ void **func;
+ const char *name;
+} fntb[] = {
+ EFUNC(glAttachObjectARB),
+ EFUNC(glCompileShaderARB),
+ EFUNC(glCreateProgramObjectARB),
+ EFUNC(glCreateShaderObjectARB),
+ EFUNC(glDeleteObjectARB),
+ EFUNC(glGetInfoLogARB),
+ EFUNC(glGetObjectParameterivARB),
+ EFUNC(glGetUniformLocationARB),
+ EFUNC(glLinkProgramARB),
+ EFUNC(glShaderSourceARB),
+ EFUNC(glUniform1iARB),
+ EFUNC(glUseProgramObjectARB),
+};
+
+void glsl_init(void) {
+ int n;
+ if (!SDL_GL_ExtensionSupported("GL_ARB_shader_objects") ||
+ !SDL_GL_ExtensionSupported("GL_ARB_shading_language_100") ||
+ !SDL_GL_ExtensionSupported("GL_ARB_vertex_shader") ||
+ !SDL_GL_ExtensionSupported("GL_ARB_fragment_shader"))
+ die("missing glsl extensions");
+ for (n = 0; n < sizeof(fntb)/sizeof(fntb[0]); n++) {
+ *fntb[n].func = SDL_GL_GetProcAddress(fntb[n].name);
+ if (!(*fntb[n].func))
+ die("cannot find func '%s'", fntb[n].name);
+ }
+}
diff --git a/glue.h b/glue.h
@@ -0,0 +1,35 @@
+/* Copyright 2013 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _SDL_GLUE_H_
+#define _SDL_GLUE_H_
+
+#define GL_GLEXT_PROTOTYPES 1
+
+#include <SDL_opengl.h>
+
+struct ctxt {
+ unsigned width;
+ unsigned height;
+ void *data;
+};
+
+int scene_init(struct ctxt *c);
+int scene_draw(struct ctxt *c);
+
+int shader_compile(const char *vshader, const char *fshader,
+ GLuint *pgm, GLuint *vshd, GLuint *fshd);
+
+#endif
diff --git a/loadfile.c b/loadfile.c
@@ -0,0 +1,57 @@
+/* Copyright 2013 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+void *load_file(const char *fn, unsigned *_sz) {
+ void *data = 0;
+ long sz;
+ FILE *fp;
+
+ if(!(fp = fopen(fn, "rb")))
+ goto exit;
+
+ if (fseek(fp, 0, SEEK_END))
+ goto close_and_exit;
+
+ if ((sz = ftell(fp)) < 0)
+ goto close_and_exit;
+
+ if (fseek(fp, 0, SEEK_SET))
+ goto close_and_exit;
+
+ if (!(data = malloc(sz + 1)))
+ goto close_and_exit;
+
+ if (fread(data, sz, 1, fp) != 1) {
+ free(data);
+ data = 0;
+ } else {
+ ((char*) data)[sz] = 0;
+ if (_sz)
+ *_sz = sz;
+ }
+
+close_and_exit:
+ fclose(fp);
+exit:
+ if (!data)
+ fprintf(stderr, "failed to load '%s'\n", fn);
+ return data;
+}
diff --git a/loadpng.c b/loadpng.c
@@ -0,0 +1,107 @@
+/* Copyright 2013 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <png.h>
+
+#include "util.h"
+
+void *load_png_rgba(const char *fn, unsigned *_width, unsigned *_height) {
+ png_structp png;
+ png_infop info;
+ png_uint_32 w, h;
+ int depth, ctype, itype, i;
+ png_byte *data = 0;
+ png_byte **rows = 0;
+ FILE *fp;
+
+ if ((fp = fopen(fn, "rb")) == NULL)
+ goto exit;
+
+ if (!(png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0)))
+ goto close_and_exit;
+
+ if (!(info = png_create_info_struct(png))) {
+ png_destroy_read_struct(&png, NULL, NULL);
+ goto destroy_and_exit;
+ }
+
+ if (setjmp(png->jmpbuf)) {
+ if (data) {
+ free(data);
+ data = 0;
+ }
+ goto destroy_and_exit;
+ }
+
+ png_init_io(png, fp);
+
+ png_read_info(png, info);
+
+ png_get_IHDR(png, info, &w, &h, &depth, &ctype, &itype, NULL, NULL);
+
+ if (depth < 8)
+ png_set_packing(png);
+
+ if (depth > 8)
+ png_set_strip_16(png);
+
+ if (ctype == PNG_COLOR_TYPE_PALETTE)
+ png_set_expand(png);
+
+ if ((ctype == PNG_COLOR_TYPE_GRAY) && (depth < 8))
+ png_set_expand(png);
+
+ if (png_get_valid(png, info, PNG_INFO_tRNS))
+ png_set_expand(png);
+
+ if ((ctype == PNG_COLOR_TYPE_RGB) ||
+ (ctype == PNG_COLOR_TYPE_GRAY))
+ png_set_add_alpha(png, 0xFF, PNG_FILLER_AFTER);
+
+ if ((ctype == PNG_COLOR_TYPE_GRAY) ||
+ (ctype == PNG_COLOR_TYPE_GRAY_ALPHA))
+ png_set_gray_to_rgb(png);
+
+
+ data = malloc(w * h * 4);
+ rows = malloc(h * sizeof(png_byte*));
+
+ if (!data || !rows)
+ png_error(png, "cannot allocate image buffer");
+
+ for (i = 0; i < h; i++)
+ rows[h-i-1] = data + (i * w * 4);
+
+ png_read_image(png, rows);
+
+ *_width = w;
+ *_height = h;
+
+destroy_and_exit:
+ if (rows)
+ free(rows);
+ png_destroy_read_struct(&png, &info, NULL);
+
+close_and_exit:
+ fclose(fp);
+exit:
+ if (!data)
+ fprintf(stderr,"failed to load '%s'\n", fn);
+ return data;
+}
diff --git a/sdlglue.c b/sdlglue.c
@@ -0,0 +1,146 @@
+/* Copyright 2013 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <SDL.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "glue.h"
+
+void die(const char *fmt, ...) {
+ fprintf(stderr,"ERROR: %s\n", fmt);
+ exit(-1);
+}
+
+int shader_compile(const char *vshader, const char *fshader,
+ GLuint *_pgm, GLuint *_vshd, GLuint *_fshd) {
+ GLint r;
+ GLuint pgm, vshd, fshd;
+
+ pgm = glCreateProgram();
+ vshd = glCreateShader(GL_VERTEX_SHADER);
+ fshd = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(vshd, 1, &vshader, NULL);
+ glShaderSource(fshd, 1, &fshader, NULL);
+ glCompileShader(vshd);
+ glCompileShader(fshd);
+ glAttachShader(pgm, vshd);
+ glAttachShader(pgm, fshd);
+// glBindAttribLocation(pgm, 0, "vPosition");
+ glLinkProgram(pgm);
+
+ glGetProgramiv(pgm, GL_LINK_STATUS, &r);
+
+ if (!r) {
+ GLint len;
+ char *buf;
+ glGetProgramiv(pgm, GL_INFO_LOG_LENGTH, &len);
+ buf = malloc(len + 1);
+ memset(buf, 0, len);
+ if (buf != 0) {
+ glGetProgramInfoLog(pgm, len, &len, buf);
+ buf[len] = 0;
+ fprintf(stderr,"<< Shader Compiler Error >>\n%s\n",buf);
+ free(buf);
+ }
+ return -1;
+ } else {
+ *_pgm = pgm;
+ *_vshd = vshd;
+ *_fshd = fshd;
+ return 0;
+ }
+}
+
+void handle_events(void) {
+ SDL_Event ev;
+
+ while (SDL_PollEvent(&ev)) {
+ switch (ev.type) {
+ case SDL_KEYDOWN:
+ case SDL_QUIT:
+ SDL_Quit();
+ exit(0);
+ }
+ }
+}
+
+int main(int argc, char **argv) {
+ struct ctxt c;
+#if WITH_SDL2
+ SDL_Window *w;
+ SDL_GLContext gc;
+#endif
+
+ c.width = 640;
+ c.height = 480;
+ c.data = 0;
+
+ if (SDL_Init(SDL_INIT_VIDEO))
+ die("sdl video init failed");
+
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
+ SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
+
+#if 0
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 8);
+
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2);
+#endif
+
+#if WITH_SDL2
+ if (!(w = SDL_CreateWindow("Test", 0, 0, c.width, c.height,
+ SDL_WINDOW_OPENGL)))
+ die("sdl cannot create window");
+
+ if (!(gc = SDL_GL_CreateContext(w)))
+ die("sdl cannot create gl context");
+#else
+ if (SDL_SetVideoMode(c.width, c.height, 32,
+ SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER | SDL_OPENGL) == NULL)
+ die("sdl cannot set mode");
+#endif
+
+ if (scene_init(&c))
+ return -1;
+
+ for (;;) {
+ handle_events();
+
+ if (scene_draw(&c))
+ return -1;
+
+#if WITH_SDL2
+ SDL_GL_SwapWindow(w);
+#else
+ SDL_GL_SwapBuffers();
+#endif
+ }
+
+ return 0;
+}
+
diff --git a/test1.c b/test1.c
@@ -0,0 +1,109 @@
+/* Copyright 2013 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "glue.h"
+
+void *texdata;
+unsigned texw, texh;
+
+const char *vert_src, *frag_src;
+
+GLuint pgm, vshd, fshd, tex0;
+GLuint _vPosition, _vUV;
+GLuint _uMVP, _uSampler;
+
+mat4 MVP;
+
+GLfloat verts[] = {
+ -0.5f, -0.5f, 0.0f,
+ -0.5f, 0.5f, 0.0f,
+ 0.5f, -0.5f, 0.0f,
+ 0.5f, 0.5f, 0.0f,
+};
+
+GLfloat texcoords[] = {
+ 0.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+ 1.0, 1.0,
+};
+
+int scene_init(struct ctxt *c) {
+ if (!(texdata = load_png_rgba("texture1.png", &texw, &texh)))
+ return -1;
+ if (!(vert_src = load_file("test1.vertex.glsl", 0)))
+ return -1;
+ if (!(frag_src = load_file("test1.fragment.glsl", 0)))
+ return -1;
+
+ mtx_identity(MVP);
+ mtx_ortho(MVP, -2.66, 2.66, -2, 2, 1, -1);
+
+ glViewport(0, 0, c->width, c->height);
+ glClearColor(0, 0, 0, 0);
+ glClearDepth(1.0f);
+
+ if (shader_compile(vert_src, frag_src, &pgm, &vshd, &fshd))
+ return -1;
+
+ _vPosition = glGetAttribLocation(pgm, "vPosition");
+ _vUV = glGetAttribLocation(pgm, "vUV");
+ _uMVP = glGetUniformLocation(pgm, "uMVP");
+ _uSampler = glGetUniformLocation(pgm, "uSampler");
+
+ if(glGetError() != GL_NO_ERROR) fprintf(stderr,"OOPS!\n");
+
+ glEnable(GL_TEXTURE_2D);
+// glEnable(GL_BLEND);
+// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ glGenTextures(1, &tex0);
+
+ glBindTexture(GL_TEXTURE_2D, tex0);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texw, texh, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, texdata);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ return 0;
+}
+
+int scene_draw(struct ctxt *c) {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glLoadIdentity();
+ glUseProgram(pgm);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, tex0);
+
+ glUniformMatrix4fv(_uMVP, 1, GL_FALSE, (void*) MVP);
+ glUniform1i(_uSampler, 0);
+
+ glVertexAttribPointer(_vPosition, 3, GL_FLOAT, GL_FALSE, 0, verts);
+ glEnableVertexAttribArray(_vPosition);
+
+ glVertexAttribPointer(_vUV, 2, GL_FLOAT, GL_FALSE, 0, texcoords);
+ glEnableVertexAttribArray(_vUV);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ return 0;
+}
+
diff --git a/test1.fragment.glsl b/test1.fragment.glsl
@@ -0,0 +1,6 @@
+uniform sampler2D uSampler;
+varying vec2 fUV;
+
+void main() {
+ gl_FragColor = texture2D(uSampler, fUV);
+}
diff --git a/test1.vertex.glsl b/test1.vertex.glsl
@@ -0,0 +1,10 @@
+uniform mat4 uMVP;
+attribute vec4 vPosition;
+attribute vec2 vUV;
+varying vec2 fUV;
+
+void main() {
+ gl_Position = uMVP * vPosition;
+ fUV = vUV;
+}
+
diff --git a/test2.c b/test2.c
@@ -0,0 +1,158 @@
+/* Copyright 2013 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "util.h"
+#include "glue.h"
+
+#include <math.h>
+
+void *texdata;
+unsigned texw, texh;
+
+const char *vert_src, *frag_src;
+
+GLuint pgm, vshd, fshd, tex0;
+GLuint _vPosition, _vUV;
+GLuint _uMVP, _uSampler;
+
+mat4 perspective;
+mat4 MVP;
+
+float a = 0.0;
+
+GLfloat data[] = {
+ -0.5f, 0.5f, 0.5f, 0.25, 0.75,
+ -0.5f, -0.5f, 0.5f, 0.25, 0.50,
+ 0.5f, -0.5f, 0.5f, 0.50, 0.50,
+ 0.5f, 0.5f, 0.5f, 0.50, 0.75,
+
+ 0.5f, 0.5f, 0.5f, 0.50, 0.75,
+ 0.5f, -0.5f, 0.5f, 0.50, 0.50,
+ 0.5f, -0.5f, -0.5f, 0.75, 0.50,
+ 0.5f, 0.5f, -0.5f, 0.75, 0.75,
+
+ 0.5f, 0.5f, -0.5f, 0.75, 0.75,
+ 0.5f, -0.5f, -0.5f, 0.75, 0.50,
+ -0.5f, -0.5f, -0.5f, 1.00, 0.50,
+ -0.5f, 0.5f, -0.5f, 1.00, 0.75,
+
+ -0.5f, 0.5f, -0.5f, 0.00, 0.75,
+ -0.5f, -0.5f, -0.5f, 0.00, 0.50,
+ -0.5f, -0.5f, 0.5f, 0.25, 0.50,
+ -0.5f, 0.5f, 0.5f, 0.25, 0.75,
+
+ -0.5f, 0.5f, -0.5f, 0.25, 1.00,
+ -0.5f, 0.5f, 0.5f, 0.25, 0.75,
+ 0.5f, 0.5f, 0.5f, 0.50, 0.75,
+ 0.5f, 0.5f, -0.5f, 0.50, 1.00,
+
+ -0.5f, -0.5f, 0.5f, 0.25, 0.50,
+ -0.5f, -0.5f, -0.5f, 0.25, 0.25,
+ 0.5f, -0.5f, -0.5f, 0.50, 0.25,
+ 0.5f, -0.5f, 0.5f, 0.50, 0.50,
+};
+
+GLubyte indices[] = {
+ 0, 1, 2, 3, 0, 2,
+ 4, 5, 6, 7, 4, 6,
+ 8, 9, 10, 11, 8, 10,
+ 12, 13, 14, 15, 12, 14,
+ 16, 17, 18, 19, 16, 18,
+ 20, 21, 22, 23, 20, 22,
+};
+
+int scene_init(struct ctxt *c) {
+ float aspect = ((float) c->width) / ((float) c->height);
+
+ if (!(texdata = load_png_rgba("cube-texture.png", &texw, &texh)))
+ return -1;
+ if (!(vert_src = load_file("test1.vertex.glsl", 0)))
+ return -1;
+ if (!(frag_src = load_file("test1.fragment.glsl", 0)))
+ return -1;
+
+ mtx_identity(MVP);
+ mtx_perspective(perspective, 60.0, aspect, 1.0, 10.0);
+
+ glViewport(0, 0, c->width, c->height);
+ glClearColor(0, 0, 0, 0);
+ glClearDepth(1.0f);
+
+ if (shader_compile(vert_src, frag_src, &pgm, &vshd, &fshd))
+ return -1;
+
+ _vPosition = glGetAttribLocation(pgm, "vPosition");
+ _vUV = glGetAttribLocation(pgm, "vUV");
+ _uMVP = glGetUniformLocation(pgm, "uMVP");
+ _uSampler = glGetUniformLocation(pgm, "uSampler");
+
+ if(glGetError() != GL_NO_ERROR) fprintf(stderr,"OOPS!\n");
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ glFrontFace(GL_CCW);
+// glEnable(GL_BLEND);
+// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ glGenTextures(1, &tex0);
+
+ glBindTexture(GL_TEXTURE_2D, tex0);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texw, texh, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, texdata);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ return 0;
+}
+
+int scene_draw(struct ctxt *c) {
+ mat4 camera;
+
+ mtx_identity(camera);
+ mtx_translate(camera, 0, 0, -3.0);
+ mtx_rotate_y(camera, a);
+ mtx_rotate_x(camera, 25.0);
+
+ mtx_mul_unsafe(MVP, camera, perspective);
+
+ a += 1.0;
+ if (a > 360.0) a = 0.0;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glUseProgram(pgm);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, tex0);
+
+ glUniformMatrix4fv(_uMVP, 1, GL_FALSE, (void*) MVP);
+ glUniform1i(_uSampler, 0);
+
+ glVertexAttribPointer(_vPosition, 3, GL_FLOAT, GL_FALSE, 5*4, data);
+ glEnableVertexAttribArray(_vPosition);
+
+ glVertexAttribPointer(_vUV, 2, GL_FLOAT, GL_FALSE, 5*4, data + 3);
+ glEnableVertexAttribArray(_vUV);
+
+ glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices);
+
+ return 0;
+}
+
diff --git a/texture1.png b/texture1.png
Binary files differ.
diff --git a/util.c b/util.c
@@ -0,0 +1,141 @@
+/* Copyright 2013 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include "util.h"
+
+void mtx_mul_unsafe(mat4 m, mat4 a, mat4 b) {
+ int i;
+ for (i = 0; i < 4; i++) {
+ m[i][0] = (a[i][0] * b[0][0]) +
+ (a[i][1] * b[1][0]) +
+ (a[i][2] * b[2][0]) +
+ (a[i][3] * b[3][0]);
+ m[i][1] = (a[i][0] * b[0][1]) +
+ (a[i][1] * b[1][1]) +
+ (a[i][2] * b[2][1]) +
+ (a[i][3] * b[3][1]);
+ m[i][2] = (a[i][0] * b[0][2]) +
+ (a[i][1] * b[1][2]) +
+ (a[i][2] * b[2][2]) +
+ (a[i][3] * b[3][2]);
+ m[i][3] = (a[i][0] * b[0][3]) +
+ (a[i][1] * b[1][3]) +
+ (a[i][2] * b[2][3]) +
+ (a[i][3] * b[3][3]);
+ }
+}
+
+void mtx_mul(mat4 m, mat4 a, mat4 b) {
+ mat4 t;
+ mtx_mul_unsafe(t, a, b);
+ memcpy(m, t, sizeof(mat4));
+}
+
+void mtx_identity(mat4 m) {
+ memset(m, 0, sizeof(mat4));
+ m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
+}
+
+void mtx_translate(mat4 m, float x, float y, float z) {
+ m[3][0] += (m[0][0] * x + m[1][0] * y + m[2][0] * z);
+ m[3][1] += (m[0][1] * x + m[1][1] * y + m[2][1] * z);
+ m[3][2] += (m[0][2] * x + m[1][2] * y + m[2][2] * z);
+ m[3][3] += (m[0][3] * x + m[1][3] * y + m[2][3] * z);
+}
+
+void mtx_rotate_x(mat4 m, float angle) {
+ mat4 r;
+ float sa,ca;
+ angle = angle * M_PI / 180.0;
+ sa = sinf(angle);
+ ca = cosf(angle);
+ memset(r, 0, sizeof(mat4));
+ r[0][0] = 1;
+ r[1][1] = ca;
+ r[1][2] = -sa;
+ r[2][1] = sa;
+ r[2][2] = ca;
+ r[3][3] = 1;
+ mtx_mul(m, r, m);
+}
+
+void mtx_rotate_y(mat4 m, float angle) {
+ mat4 r;
+ float sa,ca;
+ angle = angle * M_PI / 180.0;
+ sa = sinf(angle);
+ ca = cosf(angle);
+ memset(r, 0, sizeof(mat4));
+ r[0][0] = ca;
+ r[0][2] = sa;
+ r[1][1] = 1;
+ r[2][0] = -sa;
+ r[2][2] = ca;
+ r[3][3] = 1;
+ mtx_mul(m, r, m);
+}
+
+void mtx_rotate_z(mat4 m, float angle) {
+ mat4 r;
+ float sa,ca;
+ angle = angle * M_PI / 180.0;
+ sa = sinf(angle);
+ ca = cosf(angle);
+ memset(r, 0, sizeof(mat4));
+ r[0][0] = ca;
+ r[0][1] = -sa;
+ r[1][0] = sa;
+ r[1][1] = ca;
+ r[2][2] = 1;
+ r[3][3] = 1;
+ mtx_mul(m, r, m);
+}
+
+void mtx_frustum(mat4 m, float left, float right, float bottom, float top, float znear, float zfar) {
+ float znear2 = 2.0 * znear;
+ float width = right - left;
+ float height = top - bottom;
+ float depth = zfar - znear;
+ memset(m, 0, sizeof(mat4));
+ m[0][0] = znear2 / width;
+ m[1][1] = znear2 / height;
+ m[2][0] = (right + left) / width;
+ m[2][1] = (top + bottom) / height;
+ m[2][2] = (-zfar - znear) / depth;
+ m[2][3] = -1.0;
+ m[3][2] = (-znear2 * zfar) / depth;
+}
+
+void mtx_perspective(mat4 m, float fov, float aspect, float znear, float zfar) {
+ float ymax, xmax;
+ ymax = znear * tanf(fov * M_PI / 360.0);
+ xmax = ymax * aspect;
+ mtx_frustum(m, -xmax, xmax, -ymax, ymax, znear, zfar);
+}
+
+void mtx_ortho(mat4 m, float l, float r, float b, float t, float n, float f) {
+ memset(m, 0, sizeof(mat4));
+ m[0][0] = 2.0 / (r - l);
+ m[1][1] = 2.0 / (t - b);
+ m[2][2] = -2.0 / (f - n);
+ m[3][0] = -((r + l) / (r - l));
+ m[3][1] = -((t + b) / (t - b));
+ m[3][2] = -((f + n) / (f - n));
+ m[3][3] = 1.0;
+}
+
diff --git a/util.h b/util.h
@@ -0,0 +1,56 @@
+/* Copyright 2013 Brian Swetland <swetland@frotz.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UTIL_H_
+#define _UTIL_H_
+
+typedef float mat4[4][4];
+typedef float vec4[4];
+
+/* load the identity matrix */
+void mtx_identity(mat4 out);
+
+/* out = left * right */
+void mtx_mul(mat4 out, mat4 left, mat4 right);
+
+/* avoids a copy, but out and left may not be the same */
+void mtx_mul_unsafe(mat4 out, mat4 left, mat4 right);
+
+/* applies the transform to out */
+void mtx_translate(mat4 out, float x, float y, float z);
+void mtx_rotate_x(mat4 out, float angle);
+void mtx_rotate_y(mat4 out, float angle);
+void mtx_rotate_z(mat4 out, float angle);
+
+/* GLU-style perspective matrix helper functions */
+void mtx_ortho(mat4 out,
+ float left, float right,
+ float bottom, float top,
+ float near, float far);
+
+void mtx_frustum(mat4 out,
+ float left, float right, float bottom, float top,
+ float znear, float zfar);
+
+void mtx_perspective(mat4 out,
+ float fov_degrees, float aspect_ratio,
+ float znear, float zfar);
+
+/* file io helpers */
+void *load_png_rgba(const char *fn, unsigned *width, unsigned *height);
+void *load_file(const char *fn, unsigned *sz);
+
+#endif
+