Last active
August 29, 2015 14:02
-
-
Save JayFoxRox/2badc7fa6c9e297349f2 to your computer and use it in GitHub Desktop.
OpengGL flipped GL_TEXTURE_CUBE_MAP
This file contains 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
/* rm -f *.trace && reset && clear && clang cubemap-flip.c -lGL -lglut -lGLU -lGLEW && apitrace trace ./a.out */ | |
#if 0 | |
#define FLIP | |
#endif | |
/* This was written for XQEMU so we can see what to do about cubemaps in the | |
upside-down cache/FBO results. | |
FLIP and un-FLIP-ed should behave exactly the same. Also both should match | |
the reference (r key to switch). | |
Use WASD to rotate the cube. | |
Results from this test (For upside-down GL cubemaps): | |
- Swap +Y and -Y faces while loading the textures | |
- Use this to sample: | |
vec4 flipTextureCube(samplerCube sampler, vec3 texCoord) { | |
return textureCube(sampler, vec3(texCoord.x,-texCoord.y,texCoord.z)); | |
} | |
Still no idea about D3D cubemaps! So there might be an additional step */ | |
/* Copyright (c) Mark J. Kilgard, 1997. */ | |
/* Copyright (c) Jannik Vogel, 2014. */ | |
/* This program is freely distributable without licensing fees | |
and is provided without guarantee or warrantee expressed or | |
implied. This program is -not- in the public domain. */ | |
/* This program was requested by Patrick Earl; hopefully someone else | |
will write the equivalent Direct3D immediate mode program. */ | |
#include <GL/glew.h> | |
#include <GL/freeglut.h> | |
#include <stdint.h> | |
GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. */ | |
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */ | |
GLfloat n[6][3] = { /* Normals for the 6 faces of a cube. */ | |
{-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, | |
{0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} }; | |
GLint faces[6][4] = { /* Vertex indices for the 6 faces of a cube. */ | |
{0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4}, | |
{4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} }; | |
GLfloat v[8][3]; /* Will be filled in with X,Y,Z vertexes. */ | |
void | |
drawBox(void) | |
{ | |
int i; | |
for (i = 0; i < 6; i++) { | |
glBegin(GL_QUADS); | |
glNormal3fv(&n[i][0]); | |
glVertex3fv(&v[faces[i][0]][0]); | |
glVertex3fv(&v[faces[i][1]][0]); | |
glVertex3fv(&v[faces[i][2]][0]); | |
glVertex3fv(&v[faces[i][3]][0]); | |
glEnd(); | |
} | |
} | |
void | |
display(void) | |
{ | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
drawBox(); | |
glutSwapBuffers(); | |
glutPostRedisplay(); | |
} | |
const int SZ = 256; /* Texture size */ | |
uint32_t val(float r, float g, float b) { | |
uint32_t rgba = 0xFF000000; | |
rgba |= (int)(b * 255.0f) << 16; | |
rgba |= (int)(g * 255.0f) << 8; | |
rgba |= (int)(r * 255.0f) << 0; | |
return rgba; | |
} | |
#define VAL(r,g,b) val((r) / (float)((SZ)-1),(g) / (float)((SZ)-1),(b) / (float)((SZ)-1)) | |
#ifdef FLIP | |
#define ADDR(x,y) ((SZ - (y) - 1)*(SZ)+(x)) | |
#else | |
#define ADDR(x,y) ((y)*(SZ)+(x)) | |
#endif | |
void* posx() { | |
static uint32_t pixels[SZ*SZ]; | |
int y,z; | |
for(y = 0; y < SZ; y++) { | |
for(z = 0; z < SZ; z++) { | |
pixels[ADDR(y,z)] = VAL(SZ-1,SZ-z-1,SZ-y-1); | |
} | |
} | |
return pixels; | |
} | |
void* negx() { | |
static uint32_t pixels[SZ*SZ]; | |
int y,z; | |
for(y = 0; y < SZ; y++) { | |
for(z = 0; z < SZ; z++) { | |
pixels[ADDR(y,z)] = VAL(0,SZ-z-1,y); | |
} | |
} | |
return pixels; | |
} | |
void* posy() { | |
static uint32_t pixels[SZ*SZ]; | |
int x,z; | |
for(x = 0; x < SZ; x++) { | |
for(z = 0; z < SZ; z++) { | |
pixels[ADDR(x,z)] = VAL(x,SZ-1,z); | |
} | |
} | |
return pixels; | |
} | |
void* negy() { | |
static uint32_t pixels[SZ*SZ]; | |
int x,z; | |
for(x = 0; x < SZ; x++) { | |
for(z = 0; z < SZ; z++) { | |
pixels[ADDR(x,z)] = VAL(x,0,SZ-z-1); | |
} | |
} | |
return pixels; | |
} | |
void* posz() { | |
static uint32_t pixels[SZ*SZ]; | |
int x,y; | |
for(x = 0; x < SZ; x++) { | |
for(y = 0; y < SZ; y++) { | |
pixels[ADDR(x,y)] = VAL(x,SZ-y-1,SZ-1); | |
} | |
} | |
return pixels; | |
} | |
void* negz() { | |
static uint32_t pixels[SZ*SZ]; | |
int x,y; | |
for(x = 0; x < SZ; x++) { | |
for(y = 0; y < SZ; y++) { | |
pixels[ADDR(x,y)] = VAL(SZ-x-1,SZ-y-1,0); | |
} | |
} | |
return pixels; | |
} | |
GLuint prog; | |
void | |
init(void) | |
{ | |
glewInit(); | |
const char* vsh = "#version 110\n" | |
"varying vec3 uv;" | |
"void main() {" | |
" gl_Position = ftransform();" | |
" uv = gl_Vertex.xyz;" | |
"}"; | |
const char* fsh = "#version 110\n" | |
"varying vec3 uv;" | |
"uniform int ref;" | |
"uniform samplerCube sampler;" | |
"vec4 flipTextureCube(samplerCube sampler, vec3 texCoord) {" | |
" return textureCube(sampler, vec3(texCoord.x,-texCoord.y,texCoord.z));" | |
"}" | |
"void main() {" | |
#ifdef FLIP | |
" gl_FragColor = flipTextureCube(sampler, uv);" | |
#else | |
" gl_FragColor = textureCube(sampler, uv);" | |
#endif | |
" if (ref != 0) {" | |
" gl_FragColor = vec4(uv.xyz*vec3(0.5)+vec3(0.5),1.0);" | |
" }" | |
"}"; | |
prog = glCreateProgram(); | |
GLuint s; | |
s = glCreateShader(GL_VERTEX_SHADER); | |
glShaderSource(s, 1, &vsh, NULL); | |
glCompileShader(s); | |
glAttachShader(prog, s); | |
s = glCreateShader(GL_FRAGMENT_SHADER); | |
glShaderSource(s, 1, &fsh, NULL); | |
glCompileShader(s); | |
glAttachShader(prog, s); | |
glLinkProgram(prog); | |
glUseProgram(prog); | |
glActiveTexture(GL_TEXTURE0); | |
GLuint tex; | |
glGenTextures(1,&tex); | |
glBindTexture(GL_TEXTURE_CUBE_MAP,tex); | |
glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_MIN_FILTER,GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_CUBE_MAP,GL_TEXTURE_MAG_FILTER,GL_LINEAR); | |
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X,0,GL_RGBA,(SZ),(SZ),0,GL_RGBA,GL_UNSIGNED_BYTE,posx()); | |
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,0,GL_RGBA,(SZ),(SZ),0,GL_RGBA,GL_UNSIGNED_BYTE,negx()); | |
#ifdef FLIP | |
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,0,GL_RGBA,(SZ),(SZ),0,GL_RGBA,GL_UNSIGNED_BYTE,negy()); | |
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,0,GL_RGBA,(SZ),(SZ),0,GL_RGBA,GL_UNSIGNED_BYTE,posy()); | |
#else | |
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,0,GL_RGBA,(SZ),(SZ),0,GL_RGBA,GL_UNSIGNED_BYTE,posy()); | |
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,0,GL_RGBA,(SZ),(SZ),0,GL_RGBA,GL_UNSIGNED_BYTE,negy()); | |
#endif | |
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,0,GL_RGBA,(SZ),(SZ),0,GL_RGBA,GL_UNSIGNED_BYTE,posz()); | |
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,0,GL_RGBA,(SZ),(SZ),0,GL_RGBA,GL_UNSIGNED_BYTE,negz()); | |
glUniform1i(glGetUniformLocation(prog,"sampler"),0); | |
/* Setup cube vertex data. */ | |
v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1; | |
v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1; | |
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1; | |
v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1; | |
v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1; | |
v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1; | |
/* Enable a single OpenGL light. */ | |
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); | |
glLightfv(GL_LIGHT0, GL_POSITION, light_position); | |
glEnable(GL_LIGHT0); | |
glEnable(GL_LIGHTING); | |
/* Use depth buffering for hidden surface elimination. */ | |
glEnable(GL_DEPTH_TEST); | |
/* Setup the view of the cube. */ | |
glMatrixMode(GL_PROJECTION); | |
gluPerspective( /* field of view in degree */ 40.0, | |
/* aspect ratio */ 1.0, | |
/* Z near */ 1.0, /* Z far */ 10.0); | |
glMatrixMode(GL_MODELVIEW); | |
gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */ | |
0.0, 0.0, 0.0, /* center is at (0,0,0) */ | |
0.0, 1.0, 0.0); /* up is in positive Y direction */ | |
} | |
void keyPressed(unsigned char key, int x, int y) { | |
static int ref = 0; | |
if (key == 'r') { | |
ref++; | |
glUniform1i(glGetUniformLocation(prog,"ref"), ref & 1); | |
} | |
if (key == 'w') { | |
glRotatef(-10, 1.0, 0.0, 0.0); | |
} | |
if (key == 's') { | |
glRotatef(10, 1.0, 0.0, 0.0); | |
} | |
if (key == 'a') { | |
glRotatef(-10, 0.0, 1.0, 0.0); | |
} | |
if (key == 'd') { | |
glRotatef(10, 0.0, 1.0, 0.0); | |
} | |
} | |
int | |
main(int argc, char **argv) | |
{ | |
glutInit(&argc, argv); | |
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); | |
glutCreateWindow("red 3D lighted cube"); | |
glutDisplayFunc(display); | |
glutKeyboardFunc(keyPressed); | |
init(); | |
glutMainLoop(); | |
return 0; /* ANSI C requires main to return int. */ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment