testing compressed cubemaps master
authorEleni Maria Stea <estea@igalia.com>
Tue, 6 Nov 2018 11:01:04 +0000 (13:01 +0200)
committerEleni Maria Stea <estea@igalia.com>
Tue, 6 Nov 2018 11:20:34 +0000 (13:20 +0200)
Makefile [new file with mode: 0644]
data/back.tex [new file with mode: 0644]
data/down.tex [new file with mode: 0644]
data/front.tex [new file with mode: 0644]
data/left.tex [new file with mode: 0644]
data/right.tex [new file with mode: 0644]
data/up.tex [new file with mode: 0644]
src/main.cc [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..d266bea
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,41 @@
+# -- options --
+PREFIX = /usr/local
+opt = -O3
+dbg = -g
+# -------------
+
+src = $(wildcard src/*.cc)
+obj = $(src:.cc=.o)
+dep = $(obj:.o=.d)
+bin = cubetest
+
+CXXFLAGS = -pedantic -Wall $(opt) $(dbg) $(inc)
+LDFLAGS = -lGL -lGLU -lglut
+
+$(bin): $(obj)
+       $(CXX) -o $@ $(obj) $(LDFLAGS)
+
+-include $(dep)
+
+%.d: %.c
+       @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
+
+%.d: %.cc
+       @$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@
+
+.PHONY: clean
+clean:
+       rm -f $(obj) $(bin)
+
+.PHONY: cleandep
+cleandep:
+       rm -f $(dep)
+
+.PHONY: install
+install: $(bin)
+       mkdir -p $(DESTDIR)$(PREFIX)/bin
+       cp $(bin) $(DESTDIR)$(PREFIX)/bin/$(bin)
+
+.PHONY: uninstall
+uninstall:
+       rm -f $(DESTDIR)$(PREFIX)/bin/$(bin)
diff --git a/data/back.tex b/data/back.tex
new file mode 100644 (file)
index 0000000..5aa4b22
Binary files /dev/null and b/data/back.tex differ
diff --git a/data/down.tex b/data/down.tex
new file mode 100644 (file)
index 0000000..93451b9
Binary files /dev/null and b/data/down.tex differ
diff --git a/data/front.tex b/data/front.tex
new file mode 100644 (file)
index 0000000..3cefd65
Binary files /dev/null and b/data/front.tex differ
diff --git a/data/left.tex b/data/left.tex
new file mode 100644 (file)
index 0000000..224d7db
Binary files /dev/null and b/data/left.tex differ
diff --git a/data/right.tex b/data/right.tex
new file mode 100644 (file)
index 0000000..a40d554
Binary files /dev/null and b/data/right.tex differ
diff --git a/data/up.tex b/data/up.tex
new file mode 100644 (file)
index 0000000..1aa400f
Binary files /dev/null and b/data/up.tex differ
diff --git a/src/main.cc b/src/main.cc
new file mode 100644 (file)
index 0000000..d176b42
--- /dev/null
@@ -0,0 +1,214 @@
+#include <GL/glut.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static bool init();
+static void cleanup();
+static unsigned int load_cubemap();
+
+static void display();
+static void reshape(int x, int y);
+static void keyboard(unsigned char key, int x, int y);
+static void mouse(int bn, int state, int x, int y);
+static void motion(int x, int y);
+
+struct Texture {
+       unsigned int id;
+       int width;
+       int height;
+       unsigned int format;
+       unsigned int size;
+       unsigned char *data;
+};
+
+struct Header {
+       char magic[8];
+       uint32_t glfmt;
+       uint16_t flags;
+       uint16_t levels;
+       uint32_t width, height;
+       struct {
+               uint32_t offset, size;
+       } datadesc[20];
+       char unused[8];
+};
+
+static unsigned int cubemap;
+static float cam_phi, cam_theta;
+
+int main(int argc, char **argv)
+{
+       glutInit(&argc, argv);
+       glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
+       glutInitWindowSize(1024, 768);
+       glutCreateWindow("cubetest");
+
+       glutDisplayFunc(display);
+       glutReshapeFunc(reshape);
+       glutKeyboardFunc(keyboard);
+       glutMouseFunc(mouse);
+       glutMotionFunc(motion);
+
+       if(!init())
+               return 1;
+
+       atexit(cleanup);
+
+       glutMainLoop();
+       return 0;
+}
+
+static bool load_teximage(const char *fname, Texture *tex)
+{
+       FILE *fp;
+       if(!(fp = fopen(fname, "rb"))) {
+               fprintf(stderr, "failed to open file: %s: %s\n", fname, strerror(errno));
+               return false;
+       }
+
+       Header hdr;
+       if(fread(&hdr, 1, sizeof hdr, fp) != sizeof hdr) {
+               fprintf(stderr, "failed to read image file header: %s: %s\n", fname, strerror(errno));
+               fclose(fp);
+               return false;
+       }
+       if(memcmp(hdr.magic, "COMPTEX0", sizeof hdr.magic) != 0 || hdr.levels < 0 ||
+                       hdr.levels > 20 || !hdr.datadesc[0].size) {
+               fprintf(stderr, "%s is not a compressed texture file, or is corrupted\n", fname);
+               fclose(fp);
+               return false;
+       }
+
+       tex->data = new unsigned char[hdr.datadesc[0].size];
+
+       if(fread(tex->data, 1, hdr.datadesc[0].size, fp) != hdr.datadesc[0].size) {
+               fprintf(stderr, "unexpected EOF while reading texture: %s\n", fname);
+               fclose(fp);
+               delete [] tex->data;
+               return false;
+       }
+
+       tex->width = hdr.width;
+       tex->height = hdr.height;
+       tex->format = hdr.glfmt;
+       tex->size = hdr.datadesc[0].size;
+
+       fclose(fp);
+
+       return true;
+}
+
+static unsigned int load_cubemap()
+{
+       static const char *names[6] = {"data/right.tex", "data/left.tex", "data/up.tex",
+                                                                  "data/down.tex", "data/back.tex", "data/front.tex"};
+
+       Texture tex;
+       glGenTextures(1, &tex.id);
+       glBindTexture(GL_TEXTURE_CUBE_MAP, tex.id);
+       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+       for(int i=0; i<6; i++) {
+               if(!load_teximage(names[i], &tex)) {
+                       glDeleteTextures(1, &tex.id);
+                       return 0;
+               }
+               unsigned int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
+               glCompressedTexImage2D(face, 0, tex.format, tex.width, tex.height, 0, tex.size, tex.data); 
+               delete [] tex.data;
+       }
+
+       return tex.id;
+}
+
+static bool init()
+{
+       if(!(cubemap = load_cubemap())) {
+               return false;
+       }
+       glEnable(GL_TEXTURE_CUBE_MAP);
+
+       glEnable(GL_TEXTURE_GEN_S);
+       glEnable(GL_TEXTURE_GEN_T);
+       glEnable(GL_TEXTURE_GEN_R);
+
+       float planes[][4] = {{1, 0, 0, 0}, {0,1, 0, 0}, {0, 0, 1, 0}};
+
+       glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+       glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+       glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+
+       glTexGenfv(GL_S, GL_OBJECT_PLANE, planes[0]);
+       glTexGenfv(GL_T, GL_OBJECT_PLANE, planes[1]);
+       glTexGenfv(GL_R, GL_OBJECT_PLANE, planes[2]);
+
+       return true;
+}
+
+static void cleanup()
+{
+       glDeleteTextures(1, &cubemap);
+}
+
+static void display()
+{
+       glClear(GL_COLOR_BUFFER_BIT);
+
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
+       glRotatef(cam_phi, 1, 0, 0);
+       glRotatef(cam_theta, 0, 1, 0);
+
+       glutSolidSphere(10, 10, 5);
+
+       glutSwapBuffers();
+}
+
+static void reshape(int x, int y)
+{
+       glViewport(0, 0, x, y);
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       gluPerspective(45, (float)x / (float)y, 0.5, 100);
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+       switch(key) {
+       case 27:
+               exit(0);
+       default:
+               break;
+       }
+}
+
+static int prev_x, prev_y;
+static bool bnstate[6];
+
+static void mouse(int bn, int state, int x, int y)
+{
+       prev_x = x;
+       prev_y = y;
+       bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN;
+}
+
+static void motion(int x, int y)
+{
+       if(bnstate[0]) {
+               cam_phi += (y - prev_y) * 0.5;
+               cam_theta += (x - prev_x) * 0.5;
+
+               if(cam_phi < -90) cam_phi = -90;
+               if(cam_phi > 90) cam_phi = 90;
+
+               glutPostRedisplay();
+       }
+
+       prev_y = y;
+       prev_x = x;
+}