Merge branch 'fog_fix' into 'master'
Fixed OpenGL Fog implementation + Added New Sample See merge request simulant/GLdc!155
This commit is contained in:
commit
6bd42b87b9
@ -197,6 +197,7 @@ gen_sample(nehe06_vq samples/nehe06_vq/main.c)
|
||||
gen_sample(nehe06_4444twid samples/nehe06_4444twid/main.c)
|
||||
gen_sample(nehe08 samples/nehe08/main.c samples/nehe08/pvr-texture.c)
|
||||
gen_sample(nehe10 samples/nehe10/main.c samples/loadbmp.c)
|
||||
gen_sample(nehe16 samples/nehe16/main.c samples/nehe16/pvr-texture.c)
|
||||
gen_sample(nehe20 samples/nehe20/main.c samples/loadbmp.c)
|
||||
gen_sample(ortho2d samples/ortho2d/main.c)
|
||||
gen_sample(paletted samples/paletted/main.c)
|
||||
|
175
GL/fog.c
175
GL/fog.c
@ -1,73 +1,138 @@
|
||||
|
||||
/*
|
||||
TODO: glGetX() fog values
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include "private.h"
|
||||
|
||||
static GLfloat FOG_START = 0.0f;
|
||||
static GLfloat FOG_END = 1.0f;
|
||||
static GLfloat FOG_DENSITY = 1.0f;
|
||||
static GLenum FOG_MODE = GL_EXP;
|
||||
static GLfloat FOG_COLOR [] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
static struct {
|
||||
GLfloat START;
|
||||
GLfloat END;
|
||||
GLfloat DENSITY;
|
||||
GLenum MODE;
|
||||
GLfloat COLOR[4];
|
||||
} FOG = {
|
||||
0.0f, 1.0f, 1.0f, GL_EXP, { 0.0f, 0.0f, 0.0f, 0.0f }
|
||||
};
|
||||
|
||||
static void updatePVRFog() {
|
||||
if(FOG_MODE == GL_LINEAR) {
|
||||
GPUSetFogLinear(FOG_START, FOG_END);
|
||||
} else if(FOG_MODE == GL_EXP) {
|
||||
GPUSetFogExp(FOG_DENSITY);
|
||||
} else if(FOG_MODE == GL_EXP2) {
|
||||
GPUSetFogExp2(FOG_DENSITY);
|
||||
static void updatePVRFog(void) {
|
||||
switch(FOG.MODE) {
|
||||
case GL_LINEAR:
|
||||
GPUSetFogLinear(FOG.START, FOG.END);
|
||||
break;
|
||||
|
||||
case GL_EXP:
|
||||
GPUSetFogExp(FOG.DENSITY);
|
||||
break;
|
||||
|
||||
case GL_EXP2:
|
||||
GPUSetFogExp2(FOG.DENSITY);
|
||||
break;
|
||||
}
|
||||
GPUSetFogColor(FOG_COLOR[3], FOG_COLOR[0], FOG_COLOR[1], FOG_COLOR[2]);
|
||||
|
||||
GPUSetFogColor(FOG.COLOR[3], FOG.COLOR[0], FOG.COLOR[1], FOG.COLOR[2]);
|
||||
}
|
||||
|
||||
void APIENTRY glFogf(GLenum pname, GLfloat param) {
|
||||
void APIENTRY glFogf(GLenum pname, GLfloat param) {
|
||||
switch(pname) {
|
||||
case GL_FOG_MODE: {
|
||||
FOG_MODE = (GLenum) param;
|
||||
updatePVRFog();
|
||||
} break;
|
||||
case GL_FOG_DENSITY: {
|
||||
FOG_DENSITY = param;
|
||||
updatePVRFog();
|
||||
} break;
|
||||
case GL_FOG_START: {
|
||||
FOG_START = param;
|
||||
updatePVRFog();
|
||||
} break;
|
||||
case GL_FOG_END: {
|
||||
FOG_END = param;
|
||||
updatePVRFog();
|
||||
} break;
|
||||
case GL_FOG_INDEX:
|
||||
default: {
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
}
|
||||
case GL_FOG_DENSITY:
|
||||
if(FOG.DENSITY != param) {
|
||||
if(param < 0.0f)
|
||||
_glKosThrowError(GL_INVALID_VALUE, __func__);
|
||||
else {
|
||||
FOG.DENSITY = param;
|
||||
updatePVRFog();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_FOG_START:
|
||||
if(FOG.START != param) {
|
||||
FOG.START = param;
|
||||
updatePVRFog();
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_FOG_END:
|
||||
if(FOG.END != param) {
|
||||
FOG.END = param;
|
||||
updatePVRFog();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY glFogi(GLenum pname, GLint param) {
|
||||
glFogf(pname, (GLfloat) param);
|
||||
}
|
||||
void APIENTRY glFogi(GLenum pname, GLint param) {
|
||||
switch(pname) {
|
||||
case GL_FOG_DENSITY:
|
||||
case GL_FOG_START:
|
||||
case GL_FOG_END:
|
||||
glFogf(pname, (GLfloat)param);
|
||||
break;
|
||||
|
||||
void APIENTRY glFogfv(GLenum pname, const GLfloat* params) {
|
||||
if(pname == GL_FOG_COLOR) {
|
||||
FOG_COLOR[0] = params[0];
|
||||
FOG_COLOR[1] = params[1];
|
||||
FOG_COLOR[2] = params[2];
|
||||
FOG_COLOR[3] = params[3];
|
||||
updatePVRFog();
|
||||
} else {
|
||||
glFogf(pname, *params);
|
||||
case GL_FOG_MODE:
|
||||
if(FOG.MODE != param) {
|
||||
switch(param) {
|
||||
case GL_LINEAR:
|
||||
case GL_EXP:
|
||||
case GL_EXP2:
|
||||
FOG.MODE = param;
|
||||
updatePVRFog();
|
||||
break;
|
||||
|
||||
default:
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_FOG_INDEX:
|
||||
default:
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY glFogiv(GLenum pname, const GLint* params) {
|
||||
if(pname == GL_FOG_COLOR) {
|
||||
FOG_COLOR[0] = ((GLfloat) params[0]) / (GLfloat) INT_MAX;
|
||||
FOG_COLOR[1] = ((GLfloat) params[1]) / (GLfloat) INT_MAX;
|
||||
FOG_COLOR[2] = ((GLfloat) params[2]) / (GLfloat) INT_MAX;
|
||||
FOG_COLOR[3] = ((GLfloat) params[3]) / (GLfloat) INT_MAX;
|
||||
updatePVRFog();
|
||||
} else {
|
||||
glFogi(pname, *params);
|
||||
void APIENTRY glFogfv(GLenum pname, const GLfloat* params) {
|
||||
switch(pname) {
|
||||
case GL_FOG_COLOR: {
|
||||
GLfloat color[] = {
|
||||
CLAMP(params[0], 0.0f, 1.0f),
|
||||
CLAMP(params[1], 0.0f, 1.0f),
|
||||
CLAMP(params[2], 0.0f, 1.0f),
|
||||
CLAMP(params[3], 0.0f, 1.0f)
|
||||
};
|
||||
|
||||
if(memcmp(color, FOG.COLOR, sizeof(float) * 4)) {
|
||||
memcpy(FOG.COLOR, color, sizeof(float) * 4);
|
||||
updatePVRFog();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
glFogf(pname, *params);
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY glFogiv(GLenum pname, const GLint* params) {
|
||||
switch(pname) {
|
||||
case GL_FOG_COLOR: {
|
||||
GLfloat color[] = {
|
||||
(GLfloat)params[0] / (GLfloat)INT_MAX,
|
||||
(GLfloat)params[1] / (GLfloat)INT_MAX,
|
||||
(GLfloat)params[2] / (GLfloat)INT_MAX,
|
||||
(GLfloat)params[3] / (GLfloat)INT_MAX,
|
||||
};
|
||||
|
||||
glFogfv(pname, color);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
glFogi(pname, *params);
|
||||
}
|
||||
}
|
||||
|
247
samples/nehe16/main.c
Normal file
247
samples/nehe16/main.c
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
KallistiOS 2.0.0
|
||||
|
||||
nehe16.c
|
||||
(c)2025 Falco Girgis
|
||||
(c)2014 Josh Pearson
|
||||
(c)2001 Benoit Miller
|
||||
(c)2000 Jeff Molofee
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <GL/glkos.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
|
||||
#ifdef __DREAMCAST__
|
||||
#include <kos.h>
|
||||
extern uint8 romdisk[];
|
||||
KOS_INIT_ROMDISK(romdisk);
|
||||
#define IMG_PATH "/rd/glass.pvr"
|
||||
#else
|
||||
#define IMG_PATH "../samples/nehe08/romdisk/glass.pvr"
|
||||
#endif
|
||||
|
||||
/* Simple GL example to demonstrate fog (PVR table fog).
|
||||
|
||||
Essentially the same thing as NeHe's lesson16 code.
|
||||
To learn more, go to http://nehe.gamedev.net/.
|
||||
|
||||
DPAD controls the cube rotation, button A & B control the depth
|
||||
of the cube, button X toggles fog on/off, and button Y toggles fog type.
|
||||
*/
|
||||
|
||||
static GLfloat xrot; /* X Rotation */
|
||||
static GLfloat yrot; /* Y Rotation */
|
||||
static GLfloat xspeed; /* X Rotation Speed */
|
||||
static GLfloat yspeed; /* Y Rotation Speed */
|
||||
static GLfloat z = -5.0f; /* Depth Into The Screen */
|
||||
|
||||
static GLuint texture; /* Storage For Texture */
|
||||
|
||||
/* Storage For Three Types Of Fog */
|
||||
GLuint fogType = 0; /* use GL_EXP initially */
|
||||
GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR };
|
||||
char cfogMode[3][10] = {"GL_EXP ", "GL_EXP2 ", "GL_LINEAR" };
|
||||
GLfloat fogColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; /* Fog Color */
|
||||
int fog = GL_TRUE;
|
||||
|
||||
/* Load a PVR texture - located in pvr-texture.c */
|
||||
extern GLuint glTextureLoadPVR(char *fname, unsigned char isMipMapped, unsigned char glMipMap);
|
||||
|
||||
void draw_gl(void) {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0f, 0.0f, z);
|
||||
|
||||
glRotatef(xrot, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
/* Front Face */
|
||||
glNormal3f(0.0f, 0.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex3f(1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex3f(1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||
/* Back Face */
|
||||
glNormal3f(0.0f, 0.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex3f(1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(1.0f, -1.0f, -1.0f);
|
||||
/* Top Face */
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex3f(1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex3f(1.0f, 1.0f, -1.0f);
|
||||
/* Bottom Face */
|
||||
glNormal3f(0.0f, -1.0f, 0.0f);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex3f(1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||
/* Right face */
|
||||
glNormal3f(1.0f, 0.0f, 0.0f);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex3f(1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex3f(1.0f, 1.0f, -1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex3f(1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(1.0f, -1.0f, 1.0f);
|
||||
/* Left Face */
|
||||
glNormal3f(-1.0f, 0.0f, 0.0f);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(-1.0f, -1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex3f(-1.0f, -1.0f, 1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex3f(-1.0f, 1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex3f(-1.0f, 1.0f, -1.0f);
|
||||
glEnd();
|
||||
|
||||
xrot += xspeed;
|
||||
yrot += yspeed;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
GLboolean xp = GL_FALSE;
|
||||
GLboolean yp = GL_FALSE;
|
||||
|
||||
printf("nehe16 beginning\n");
|
||||
|
||||
/* Get basic stuff initialized */
|
||||
glKosInit();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(45.0f, 640.0f / 480.0f, 0.1f, 100.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
glClearDepth(1.0f);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 0.5);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
/* Enable Lighting and GL_LIGHT0 */
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
|
||||
/* Set up the fog */
|
||||
glFogi(GL_FOG_MODE, fogMode[fogType]); /* Fog Mode */
|
||||
glFogfv(GL_FOG_COLOR, fogColor); /* Set Fog Color */
|
||||
glFogf(GL_FOG_DENSITY, 0.35f); /* How Dense The Fog is */
|
||||
glHint(GL_FOG_HINT, GL_DONT_CARE); /* Fog Hint Value */
|
||||
glFogf(GL_FOG_START, 0.0f); /* Fog Start Depth */
|
||||
glFogf(GL_FOG_END, 5.0f); /* Fog End Depth */
|
||||
glEnable(GL_FOG); /* Enables GL_FOG */
|
||||
|
||||
/* Set up the textures */
|
||||
texture = glTextureLoadPVR(IMG_PATH, 0, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
while(1) {
|
||||
#ifdef __DREAMCAST__
|
||||
maple_device_t *cont;
|
||||
cont_state_t *state;
|
||||
|
||||
cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
|
||||
|
||||
/* Check key status */
|
||||
state = (cont_state_t *)maple_dev_status(cont);
|
||||
|
||||
if(!state) {
|
||||
printf("Error reading controller\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if(state->start)
|
||||
break;
|
||||
|
||||
if(state->a) {
|
||||
if(z >= -15.0f) z -= 0.02f;
|
||||
}
|
||||
|
||||
if(state->b) {
|
||||
if(z <= 0.0f) z += 0.02f;
|
||||
}
|
||||
|
||||
if(state->x && !xp) {
|
||||
xp = GL_TRUE;
|
||||
fogType = (fogType + 1) % 3;
|
||||
glFogi(GL_FOG_MODE, fogMode[fogType]);
|
||||
printf("%s\n", cfogMode[fogType]);
|
||||
}
|
||||
|
||||
if(!state->x)
|
||||
xp = GL_FALSE;
|
||||
|
||||
if(state->y && !yp) {
|
||||
yp = GL_TRUE;
|
||||
fog = !fog;
|
||||
}
|
||||
|
||||
if(!state->y)
|
||||
yp = GL_FALSE;
|
||||
|
||||
if(state->dpad_up)
|
||||
xspeed -= 0.1f;
|
||||
|
||||
if(state->dpad_down)
|
||||
xspeed += 0.1f;
|
||||
|
||||
if(state->dpad_left)
|
||||
yspeed -= 0.1f;
|
||||
|
||||
if(state->dpad_right)
|
||||
yspeed += 0.1f;
|
||||
#endif
|
||||
|
||||
/* Switch fog off/on */
|
||||
if(fog) {
|
||||
glEnable(GL_FOG);
|
||||
}
|
||||
else {
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
|
||||
/* Draw the GL "scene" */
|
||||
draw_gl();
|
||||
|
||||
/* Finish the frame */
|
||||
glKosSwapBuffers();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
176
samples/nehe16/pvr-texture.c
Normal file
176
samples/nehe16/pvr-texture.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
KallistiOS 2.0.0
|
||||
|
||||
pvr-texture.c
|
||||
(c)2014 Josh PH3NOM Pearson
|
||||
|
||||
Load A PVR Texture to the PVR using Open GL
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "GL/gl.h"
|
||||
#include "GL/glu.h"
|
||||
#include "GL/glkos.h"
|
||||
#include "GL/glext.h"
|
||||
|
||||
#define PVR_HDR_SIZE 0x20
|
||||
#define MAX(x, y) ((x > y) ? x : y)
|
||||
|
||||
static GLuint PVR_TextureHeight(unsigned char *HDR);
|
||||
static GLuint PVR_TextureWidth(unsigned char *HDR);
|
||||
static GLuint PVR_TextureFormat(unsigned char *HDR);
|
||||
|
||||
static GLuint _glGetMipmapLevelCount(GLuint width, GLuint height) {
|
||||
return 1 + floor(log2(MAX(width, height)));
|
||||
}
|
||||
|
||||
static GLuint _glGetMipmapDataSize(GLuint width, GLuint height) {
|
||||
GLuint size = 0;
|
||||
|
||||
GLuint i = 0;
|
||||
|
||||
for(; i < _glGetMipmapLevelCount(width, height); ++i) {
|
||||
size += (width * height * 2);
|
||||
|
||||
if(width > 1) {
|
||||
width /= 2;
|
||||
}
|
||||
|
||||
if(height > 1) {
|
||||
height /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Load a PVR texture file into memory, and then bind the texture to Open GL.
|
||||
fname is the name of the PVR texture file to be opened and read.
|
||||
isMipMapped should be passed as 1 if the texture contains MipMap levels, 0 otherwise.
|
||||
glMipMap should be passed as 1 if Open GL should calculate the Mipmap levels, 0 otherwise */
|
||||
GLuint glTextureLoadPVR(char *fname, unsigned char isMipMapped, unsigned char glMipMap) {
|
||||
FILE *tex = NULL;
|
||||
uint16_t *TEX0 = NULL;
|
||||
uint8_t HDR[PVR_HDR_SIZE];
|
||||
GLuint texID, texSize, texW, texH, texFormat;
|
||||
|
||||
/* Open the PVR texture file, and get its file size */
|
||||
tex = fopen(fname, "rb");
|
||||
|
||||
if(tex == NULL) {
|
||||
printf("FILE READ ERROR: %s\n", fname);
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
fseek(tex, 0, SEEK_END);
|
||||
texSize = ftell(tex) - PVR_HDR_SIZE;
|
||||
fseek(tex, 0, SEEK_SET);
|
||||
|
||||
/* Read in the PVR texture file header */
|
||||
fread(HDR, 1, PVR_HDR_SIZE, tex);
|
||||
|
||||
/* Extract some information from the PVR texture file header */
|
||||
texW = PVR_TextureWidth(HDR);
|
||||
texH = PVR_TextureHeight(HDR);
|
||||
texFormat = PVR_TextureFormat(HDR);
|
||||
|
||||
/* Allocate Some Memory for the texture. If we are using Open GL to build the MipMap,
|
||||
we need to allocate enough space to hold the MipMap texture levels. */
|
||||
if(!isMipMapped && glMipMap)
|
||||
TEX0 = malloc(_glGetMipmapDataSize(texW, texH));
|
||||
else
|
||||
TEX0 = malloc(texSize);
|
||||
|
||||
fread(TEX0, 1, texSize, tex); /* Read in the PVR texture data */
|
||||
|
||||
/* Generate and bind a texture as normal for Open GL */
|
||||
glGenTextures(1, &texID);
|
||||
glBindTexture(GL_TEXTURE_2D, texID);
|
||||
|
||||
if(texFormat != GL_UNSIGNED_SHORT_5_6_5)
|
||||
glCompressedTexImage2DARB(GL_TEXTURE_2D,
|
||||
0,
|
||||
texFormat,
|
||||
texW,
|
||||
texH,
|
||||
0,
|
||||
texSize,
|
||||
TEX0);
|
||||
else {
|
||||
fprintf(stderr, "%x\n", texFormat);
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGB,
|
||||
texW, texH,
|
||||
0,
|
||||
GL_RGB,
|
||||
texFormat,
|
||||
TEX0);
|
||||
if(!isMipMapped && glMipMap)
|
||||
glGenerateMipmapEXT(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
free(TEX0);
|
||||
|
||||
return texID;
|
||||
}
|
||||
|
||||
static GLuint PVR_TextureFormat(unsigned char *HDR) {
|
||||
GLuint color = (GLuint)HDR[PVR_HDR_SIZE - 8];
|
||||
GLuint format = (GLuint)HDR[PVR_HDR_SIZE - 7];
|
||||
|
||||
GLboolean twiddled = format == 0x01;
|
||||
GLboolean compressed = (format == 0x10 || format == 0x03);
|
||||
|
||||
if(compressed) {
|
||||
if(twiddled) {
|
||||
switch(color) {
|
||||
case 0x0: {
|
||||
return GL_COMPRESSED_ARGB_1555_VQ_TWID_KOS;
|
||||
} break;
|
||||
case 0x01: {
|
||||
return GL_COMPRESSED_RGB_565_VQ_TWID_KOS;
|
||||
} break;
|
||||
case 0x02: {
|
||||
return GL_COMPRESSED_ARGB_4444_VQ_TWID_KOS;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Invalid texture format");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
switch(color) {
|
||||
case 0: {
|
||||
return GL_COMPRESSED_ARGB_1555_VQ_KOS;
|
||||
} break;
|
||||
case 1: {
|
||||
return GL_COMPRESSED_RGB_565_VQ_KOS;
|
||||
} break;
|
||||
case 2: {
|
||||
return GL_COMPRESSED_ARGB_4444_VQ_KOS;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Invalid texture format");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(color == 1) {
|
||||
return GL_UNSIGNED_SHORT_5_6_5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint PVR_TextureWidth(unsigned char *HDR) {
|
||||
return (GLuint)HDR[PVR_HDR_SIZE - 4] | HDR[PVR_HDR_SIZE - 3] << 8;
|
||||
}
|
||||
|
||||
static GLuint PVR_TextureHeight(unsigned char *HDR) {
|
||||
return (GLuint)HDR[PVR_HDR_SIZE - 2] | HDR[PVR_HDR_SIZE - 1] << 8;
|
||||
}
|
BIN
samples/nehe16/romdisk/glass.pvr
Normal file
BIN
samples/nehe16/romdisk/glass.pvr
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user