Merge branch 'master' into tnl_effects
This commit is contained in:
commit
0e112ffb3c
@ -198,6 +198,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)
|
||||
|
||||
177
GL/attributes.c
177
GL/attributes.c
@ -31,11 +31,10 @@ GL_FORCE_INLINE GLboolean _glStateUnchanged(AttribPointer* p, GLint size, GLenum
|
||||
return (p->size == size && p->type == type && p->stride == stride);
|
||||
}
|
||||
|
||||
GLuint* _glGetEnabledAttributes() {
|
||||
GLuint* _glGetEnabledAttributes(void) {
|
||||
return &ATTRIB_LIST.enabled;
|
||||
}
|
||||
|
||||
|
||||
static void _readPosition3f3f(const GLubyte* __restrict__ in, GLubyte* __restrict__ out) {
|
||||
const float* input = (const float*) in;
|
||||
Vertex* it = (Vertex*) out;
|
||||
@ -47,6 +46,17 @@ static void _readPosition3f3f(const GLubyte* __restrict__ in, GLubyte* __restric
|
||||
TransformVertex(x, y, z, w, it->xyz, &it->w);
|
||||
}
|
||||
|
||||
static void _readPosition3d3f(const GLubyte* __restrict__ in, GLubyte* __restrict__ out) {
|
||||
const double* input = (const double*) in;
|
||||
Vertex* it = (Vertex*) out;
|
||||
|
||||
float x = input[0];
|
||||
float y = input[1];
|
||||
float z = input[2];
|
||||
float w = 1.0f;
|
||||
TransformVertex(x, y, z, w, it->xyz, &it->w);
|
||||
}
|
||||
|
||||
static void _readPosition3ub3f(const GLubyte* input, GLubyte* out) {
|
||||
Vertex* it = (Vertex*)out;
|
||||
|
||||
@ -90,6 +100,17 @@ static void _readPosition2f3f(const GLubyte* in, GLubyte* out) {
|
||||
TransformVertex(x, y, z, w, it->xyz, &it->w);
|
||||
}
|
||||
|
||||
static void _readPosition2d3f(const GLubyte* in, GLubyte* out) {
|
||||
const double* input = (const double*) in;
|
||||
Vertex* it = (Vertex*) out;
|
||||
|
||||
float x = input[0];
|
||||
float y = input[1];
|
||||
float z = 0.0f;
|
||||
float w = 1.0f;
|
||||
TransformVertex(x, y, z, w, it->xyz, &it->w);
|
||||
}
|
||||
|
||||
static void _readPosition2ub3f(const GLubyte* input, GLubyte* out) {
|
||||
Vertex* it = (Vertex*) out;
|
||||
|
||||
@ -122,10 +143,12 @@ static void _readPosition2ui3f(const GLubyte* in, GLubyte* out) {
|
||||
TransformVertex(x, y, z, w, it->xyz, &it->w);
|
||||
}
|
||||
|
||||
static ReadAttributeFunc calcReadPositionFunc() {
|
||||
static ReadAttributeFunc calcReadPositionFunc(void) {
|
||||
switch(ATTRIB_LIST.vertex.type) {
|
||||
default:
|
||||
case GL_DOUBLE:
|
||||
return (ATTRIB_LIST.vertex.size == 3) ? _readPosition3d3f:
|
||||
_readPosition2d3f;
|
||||
default:
|
||||
case GL_FLOAT:
|
||||
return (ATTRIB_LIST.vertex.size == 3) ? _readPosition3f3f:
|
||||
_readPosition2f3f;
|
||||
@ -144,7 +167,6 @@ static ReadAttributeFunc calcReadPositionFunc() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void _fillWhiteARGB(const GLubyte* __restrict__ input, GLubyte* __restrict__ output) {
|
||||
_GL_UNUSED(input);
|
||||
*((uint32_t*) output) = ~0;
|
||||
@ -157,24 +179,6 @@ static void _readColour4ubARGB(const GLubyte* input, GLubyte* output) {
|
||||
output[A8IDX] = input[3];
|
||||
}
|
||||
|
||||
static void _readColour4fARGB(const GLubyte* in, GLubyte* output) {
|
||||
const float* input = (const float*) in;
|
||||
|
||||
output[R8IDX] = (GLubyte) clamp(input[0] * 255.0f, 0, 255);
|
||||
output[G8IDX] = (GLubyte) clamp(input[1] * 255.0f, 0, 255);
|
||||
output[B8IDX] = (GLubyte) clamp(input[2] * 255.0f, 0, 255);
|
||||
output[A8IDX] = (GLubyte) clamp(input[3] * 255.0f, 0, 255);
|
||||
}
|
||||
|
||||
static void _readColour3fARGB(const GLubyte* in, GLubyte* output) {
|
||||
const float* input = (const float*) in;
|
||||
|
||||
output[R8IDX] = (GLubyte) clamp(input[0] * 255.0f, 0, 255);
|
||||
output[G8IDX] = (GLubyte) clamp(input[1] * 255.0f, 0, 255);
|
||||
output[B8IDX] = (GLubyte) clamp(input[2] * 255.0f, 0, 255);
|
||||
output[A8IDX] = 255;
|
||||
}
|
||||
|
||||
static void _readColour3ubARGB(const GLubyte* __restrict__ input, GLubyte* __restrict__ output) {
|
||||
output[R8IDX] = input[0];
|
||||
output[G8IDX] = input[1];
|
||||
@ -182,6 +186,30 @@ static void _readColour3ubARGB(const GLubyte* __restrict__ input, GLubyte* __res
|
||||
output[A8IDX] = 255;
|
||||
}
|
||||
|
||||
#define DEF_READ_COLOUR_4_ARGB_FP(prefix, intype) \
|
||||
static void _readColour##prefix##ARGB(const GLubyte* __restrict in, GLubyte* __restrict out) { \
|
||||
const intype* input = (const intype*) in; \
|
||||
out[R8IDX] = (GLubyte) clamp(input[0] * 255.0f, 0, 255); \
|
||||
out[G8IDX] = (GLubyte) clamp(input[1] * 255.0f, 0, 255); \
|
||||
out[B8IDX] = (GLubyte) clamp(input[2] * 255.0f, 0, 255); \
|
||||
out[A8IDX] = (GLubyte) clamp(input[3] * 255.0f, 0, 255); \
|
||||
}
|
||||
|
||||
#define DEF_READ_COLOUR_3_ARGB_FP(prefix, intype) \
|
||||
static void _readColour##prefix##ARGB(const GLubyte* __restrict in, GLubyte* __restrict out) { \
|
||||
const intype* input = (const intype*) in; \
|
||||
out[R8IDX] = (GLubyte) clamp(input[0] * 255.0f, 0, 255); \
|
||||
out[G8IDX] = (GLubyte) clamp(input[1] * 255.0f, 0, 255); \
|
||||
out[B8IDX] = (GLubyte) clamp(input[2] * 255.0f, 0, 255); \
|
||||
out[A8IDX] = 255; \
|
||||
}
|
||||
|
||||
DEF_READ_COLOUR_4_ARGB_FP(4f, float)
|
||||
DEF_READ_COLOUR_4_ARGB_FP(4d, double)
|
||||
|
||||
DEF_READ_COLOUR_3_ARGB_FP(3f, float)
|
||||
DEF_READ_COLOUR_3_ARGB_FP(3d, double)
|
||||
|
||||
static void _readColour4ubRevARGB(const GLubyte* __restrict__ input, GLubyte* __restrict__ output) {
|
||||
argbcpy(output, input);
|
||||
}
|
||||
@ -195,51 +223,58 @@ static void _readColour4fRevARGB(const GLubyte* __restrict__ in, GLubyte* __rest
|
||||
output[3] = (GLubyte) clamp(input[3] * 255.0f, 0, 255);
|
||||
}
|
||||
|
||||
static void _readColour3usARGB(const GLubyte* input, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(output);
|
||||
gl_assert(0 && "Not Implemented");
|
||||
static void _readColour4dRevARGB(const GLubyte* __restrict__ in, GLubyte* __restrict__ output) {
|
||||
const double* input = (const double*) in;
|
||||
|
||||
output[0] = (GLubyte) clamp(input[0] * 255.0f, 0, 255);
|
||||
output[1] = (GLubyte) clamp(input[1] * 255.0f, 0, 255);
|
||||
output[2] = (GLubyte) clamp(input[2] * 255.0f, 0, 255);
|
||||
output[3] = (GLubyte) clamp(input[3] * 255.0f, 0, 255);
|
||||
}
|
||||
|
||||
static void _readColour3uiARGB(const GLubyte* input, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(output);
|
||||
gl_assert(0 && "Not Implemented");
|
||||
}
|
||||
#define DEF_READ_COLOUR_N_ARGB_INT(prefix, intype, max, alpha, i0, i1, i2, i3) \
|
||||
static void _readColour##prefix##ARGB(const GLubyte* __restrict in, GLubyte* __restrict out) { \
|
||||
const intype* input = (const intype*) in; \
|
||||
out[i0] = (GLubyte) clamp((float)input[0] / (float)max * 255.0f, 0, 255); \
|
||||
out[i1] = (GLubyte) clamp((float)input[1] / (float)max * 255.0f, 0, 255); \
|
||||
out[i2] = (GLubyte) clamp((float)input[2] / (float)max * 255.0f, 0, 255); \
|
||||
out[i3] = alpha; \
|
||||
}
|
||||
|
||||
static void _readColour4usARGB(const GLubyte* input, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(output);
|
||||
gl_assert(0 && "Not Implemented");
|
||||
}
|
||||
#define DEF_READ_COLOUR_3_ARGB_INT(prefix, intype, max) \
|
||||
DEF_READ_COLOUR_N_ARGB_INT(prefix, intype, max, 255, R8IDX, G8IDX, B8IDX, A8IDX)
|
||||
|
||||
static void _readColour4uiARGB(const GLubyte* input, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(output);
|
||||
gl_assert(0 && "Not Implemented");
|
||||
}
|
||||
#define DEF_READ_COLOUR_4_ARGB_INT(prefix, intype, max) \
|
||||
DEF_READ_COLOUR_N_ARGB_INT(prefix, intype, max, \
|
||||
((GLubyte)clamp((float)input[3] / (float)max * 255.0f, 0, 255)), \
|
||||
R8IDX, G8IDX, B8IDX, A8IDX)
|
||||
|
||||
static void _readColour4usRevARGB(const GLubyte* input, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(output);
|
||||
gl_assert(0 && "Not Implemented");
|
||||
}
|
||||
#define DEF_READ_COLOUR_4_REV_ARGB_INT(prefix, intype, max) \
|
||||
DEF_READ_COLOUR_N_ARGB_INT(prefix##Rev, intype, max, \
|
||||
((GLubyte)clamp((float)input[3] / (float)max * 255.0f, 0, 255)), \
|
||||
0, 1, 2, 3)
|
||||
|
||||
static void _readColour4uiRevARGB(const GLubyte* input, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(output);
|
||||
gl_assert(0 && "Not Implemented");
|
||||
}
|
||||
DEF_READ_COLOUR_3_ARGB_INT(3us, GLushort, UINT16_MAX)
|
||||
DEF_READ_COLOUR_3_ARGB_INT(3ui, GLuint, UINT32_MAX)
|
||||
|
||||
static ReadAttributeFunc calcReadDiffuseFunc() {
|
||||
DEF_READ_COLOUR_4_ARGB_INT(4us, GLushort, UINT16_MAX)
|
||||
DEF_READ_COLOUR_4_ARGB_INT(4ui, GLuint, UINT32_MAX)
|
||||
|
||||
DEF_READ_COLOUR_4_REV_ARGB_INT(4us, GLushort, UINT16_MAX)
|
||||
DEF_READ_COLOUR_4_REV_ARGB_INT(4ui, GLuint, UINT32_MAX)
|
||||
|
||||
static ReadAttributeFunc calcReadDiffuseFunc(void) {
|
||||
if((ATTRIB_LIST.enabled & DIFFUSE_ENABLED_FLAG) != DIFFUSE_ENABLED_FLAG) {
|
||||
/* Just fill the whole thing white if the attribute is disabled */
|
||||
return _fillWhiteARGB;
|
||||
}
|
||||
|
||||
switch(ATTRIB_LIST.colour.type) {
|
||||
default:
|
||||
case GL_DOUBLE:
|
||||
return (ATTRIB_LIST.colour.size == 3) ? _readColour3dARGB:
|
||||
(ATTRIB_LIST.colour.size == 4) ? _readColour4dARGB:
|
||||
_readColour4dRevARGB;
|
||||
default:
|
||||
case GL_FLOAT:
|
||||
return (ATTRIB_LIST.colour.size == 3) ? _readColour3fARGB:
|
||||
(ATTRIB_LIST.colour.size == 4) ? _readColour4fARGB:
|
||||
@ -276,6 +311,11 @@ static void _readTexcoord2f2f(const GLubyte* in, GLubyte* out) {
|
||||
vec2cpy(out, in);
|
||||
}
|
||||
|
||||
static void _readTexcoord2d2f(const GLubyte* in, GLubyte* out) {
|
||||
((float*)out)[0] = ((const double*)in)[0];
|
||||
((float*)out)[1] = ((const double*)in)[1];
|
||||
}
|
||||
|
||||
static void _readTexcoord2ub2f(const GLubyte* input, GLubyte* out) {
|
||||
float* output = (float*) out;
|
||||
|
||||
@ -299,14 +339,15 @@ static void _readTexcoord2ui2f(const GLubyte* in, GLubyte* out) {
|
||||
output[1] = input[1];
|
||||
}
|
||||
|
||||
static ReadAttributeFunc calcReadUVFunc() {
|
||||
static ReadAttributeFunc calcReadUVFunc(void) {
|
||||
if((ATTRIB_LIST.enabled & UV_ENABLED_FLAG) != UV_ENABLED_FLAG) {
|
||||
return _fillZero2f;
|
||||
}
|
||||
|
||||
switch(ATTRIB_LIST.uv.type) {
|
||||
default:
|
||||
case GL_DOUBLE:
|
||||
return _readTexcoord2d2f;
|
||||
default:
|
||||
case GL_FLOAT:
|
||||
return _readTexcoord2f2f;
|
||||
case GL_BYTE:
|
||||
@ -321,14 +362,15 @@ static ReadAttributeFunc calcReadUVFunc() {
|
||||
}
|
||||
}
|
||||
|
||||
static ReadAttributeFunc calcReadSTFunc() {
|
||||
static ReadAttributeFunc calcReadSTFunc(void) {
|
||||
if((ATTRIB_LIST.enabled & ST_ENABLED_FLAG) != ST_ENABLED_FLAG) {
|
||||
return _fillZero2f;
|
||||
}
|
||||
|
||||
switch(ATTRIB_LIST.st.type) {
|
||||
default:
|
||||
case GL_DOUBLE:
|
||||
return _readTexcoord2d2f;
|
||||
default:
|
||||
case GL_FLOAT:
|
||||
return _readTexcoord2f2f;
|
||||
case GL_BYTE:
|
||||
@ -357,6 +399,12 @@ static void _readNormal3f3f(const GLubyte* __restrict__ in, GLubyte* __restrict_
|
||||
vec3cpy(out, in);
|
||||
}
|
||||
|
||||
static void _readNormal3d3f(const GLubyte* __restrict__ in, GLubyte* __restrict__ out) {
|
||||
((float*)out)[0] = ((const double*)in)[0];
|
||||
((float*)out)[1] = ((const double*)in)[1];
|
||||
((float*)out)[2] = ((const double*)in)[2];
|
||||
}
|
||||
|
||||
static void _readNormal3ub3f(const GLubyte* input, GLubyte* out) {
|
||||
float* output = (float*) out;
|
||||
|
||||
@ -406,15 +454,16 @@ static void _readNormal1i3f(const GLubyte* in, GLubyte* out) {
|
||||
output[2] = (2.0f * (float) input.bits.z + 1.0f) * MULTIPLIER;
|
||||
}
|
||||
|
||||
static ReadAttributeFunc calcReadNormalFunc() {
|
||||
static ReadAttributeFunc calcReadNormalFunc(void) {
|
||||
if((ATTRIB_LIST.enabled & NORMAL_ENABLED_FLAG) != NORMAL_ENABLED_FLAG) {
|
||||
return _fillWithNegZVE;
|
||||
}
|
||||
|
||||
switch(ATTRIB_LIST.normal.type) {
|
||||
default:
|
||||
case GL_DOUBLE:
|
||||
return _readNormal3d3f;
|
||||
case GL_FLOAT:
|
||||
default:
|
||||
return _readNormal3f3f;
|
||||
break;
|
||||
case GL_BYTE:
|
||||
@ -497,7 +546,7 @@ void APIENTRY glDisableClientState(GLenum cap) {
|
||||
}
|
||||
|
||||
|
||||
void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {
|
||||
void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
|
||||
TRACE();
|
||||
|
||||
stride = (stride) ? stride : size * byte_size(type);
|
||||
@ -591,7 +640,7 @@ void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid * poin
|
||||
}
|
||||
|
||||
|
||||
void _glInitAttributePointers() {
|
||||
void _glInitAttributePointers(void) {
|
||||
TRACE();
|
||||
ATTRIB_LIST.dirty = ~0; // all attributes dirty
|
||||
|
||||
@ -601,7 +650,7 @@ void _glInitAttributePointers() {
|
||||
glNormalPointer(GL_FLOAT, 0, NULL);
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE GLuint _glIsVertexDataFastPathCompatible() {
|
||||
GL_FORCE_INLINE GLuint _glIsVertexDataFastPathCompatible(void) {
|
||||
/* The fast path is enabled when all enabled elements of the vertex
|
||||
* match the output format. This means:
|
||||
*
|
||||
@ -649,7 +698,7 @@ GL_FORCE_INLINE GLuint _glIsVertexDataFastPathCompatible() {
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
void _glUpdateAttributes() {
|
||||
void _glUpdateAttributes(void) {
|
||||
if(ATTRIB_LIST.dirty & VERTEX_ENABLED_FLAG) {
|
||||
ATTRIB_LIST.vertex_func = calcReadPositionFunc();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,11 +209,11 @@ void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
float r = DEG2RAD * angle;
|
||||
#ifdef __DREAMCAST__
|
||||
float s, c;
|
||||
fsincos(r, &s, &c);
|
||||
fsincos(angle, &s, &c);
|
||||
#else
|
||||
float r = DEG2RAD * angle;
|
||||
float c = cosf(r);
|
||||
float s = sinf(r);
|
||||
#endif
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
|
||||
#include "../types.h"
|
||||
|
||||
#define __restrict
|
||||
|
||||
#define PREFETCH(addr) do {} while(0)
|
||||
|
||||
#define MATH_fsrra(x) (1.0f / sqrtf((x)))
|
||||
|
||||
49
GL/texture.c
49
GL/texture.c
@ -906,6 +906,55 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target,
|
||||
_glGPUStateMarkDirty();
|
||||
}
|
||||
|
||||
void APIENTRY glCompressedTexSubImage2DARB(GLenum target,
|
||||
GLint level,
|
||||
GLint xoffset,
|
||||
GLint yoffset,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLenum format,
|
||||
GLsizei imageSize,
|
||||
const GLvoid *data) {
|
||||
TRACE();
|
||||
|
||||
if (target != GL_TEXTURE_2D) {
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (xoffset < 0 || yoffset < 0 || width <= 0 || height <= 0) {
|
||||
_glKosThrowError(GL_INVALID_VALUE, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
gl_assert(ACTIVE_TEXTURE < MAX_GLDC_TEXTURE_UNITS);
|
||||
TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE];
|
||||
|
||||
if (!active) {
|
||||
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
GLuint original_id = active->index;
|
||||
|
||||
// Ensure that we're modifying the correct texture
|
||||
if (active->index != original_id) {
|
||||
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy raw compressed texture data into the texture buffer.
|
||||
GLubyte* targetData = active->data;
|
||||
GLubyte* src = (GLubyte*)data;
|
||||
|
||||
// Copy the compressed data directly to the texture
|
||||
if (data) {
|
||||
FASTCPY(targetData + (yoffset * active->width + xoffset), src, imageSize);
|
||||
}
|
||||
|
||||
_glGPUStateMarkDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an internal format, and returns a GL format matching how we'd store
|
||||
* it internally, so it'll return one of the following:
|
||||
|
||||
@ -185,6 +185,15 @@ GLAPI void APIENTRY glCompressedTexImage2DARB(GLenum target,
|
||||
GLsizei imageSize,
|
||||
const GLvoid *data);
|
||||
|
||||
GLAPI void APIENTRY glCompressedTexSubImage2DARB(GLenum target,
|
||||
GLint level,
|
||||
GLint xoffset,
|
||||
GLint yoffset,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLenum format,
|
||||
GLsizei imageSize,
|
||||
const GLvoid *data);
|
||||
|
||||
/* Core aliases */
|
||||
#define GL_INVALID_FRAMEBUFFER_OPERATION GL_INVALID_FRAMEBUFFER_OPERATION_EXT
|
||||
@ -195,6 +204,7 @@ GLAPI void APIENTRY glCompressedTexImage2DARB(GLenum target,
|
||||
|
||||
#define glGenerateMipmapEXT glGenerateMipmap
|
||||
#define glCompressedTexImage2D glCompressedTexImage2DARB
|
||||
#define glCompressedTexSubImage2D glCompressedTexSubImage2DARB
|
||||
|
||||
#ifndef GL_VERSION_1_4
|
||||
#define GL_VERSION_1_4 1
|
||||
|
||||
@ -165,9 +165,16 @@ void LoadGLTextures() {
|
||||
|
||||
// 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image,
|
||||
// border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.
|
||||
// Allocate texture memory (but don't upload compressed data yet)
|
||||
glCompressedTexImage2DARB(
|
||||
GL_TEXTURE_2D, 0, image1->internalFormat, image1->sizeX, image1->sizeY, 0,
|
||||
image1->dataSize, image1->data
|
||||
image1->dataSize, NULL // NULL here means we are not uploading data yet
|
||||
);
|
||||
|
||||
// Now use glCompressedTexSubImage2DARB to upload the compressed data to the texture
|
||||
glCompressedTexSubImage2DARB(
|
||||
GL_TEXTURE_2D, 0, 0, 0, image1->sizeX, image1->sizeY,
|
||||
image1->internalFormat, image1->dataSize, image1->data
|
||||
);
|
||||
|
||||
free(image1);
|
||||
|
||||
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