Merge branch 'kazade_patch_prepare' into 'master'
Kazade patch prepare See merge request simulant/GLdc!52
This commit is contained in:
commit
2f75ff8223
24
GL/clip.c
24
GL/clip.c
|
@ -32,39 +32,35 @@ void _glClipLineToNearZ(const Vertex* v1, const Vertex* v2, Vertex* vout, float*
|
|||
|
||||
float vec [] = {v2->xyz[0] - v1->xyz[0], v2->xyz[1] - v1->xyz[1], v2->xyz[2] - v1->xyz[2]};
|
||||
|
||||
vout->xyz[0] = v1->xyz[0] + (vec[0] * (*t));
|
||||
vout->xyz[1] = v1->xyz[1] + (vec[1] * (*t));
|
||||
vout->xyz[2] = v1->xyz[2] + (vec[2] * (*t));
|
||||
vout->xyz[0] = MATH_fmac(vec[0], (*t), v1->xyz[0]);
|
||||
vout->xyz[1] = MATH_fmac(vec[1], (*t), v1->xyz[1]);
|
||||
vout->xyz[2] = MATH_fmac(vec[2], (*t), v1->xyz[2]);
|
||||
|
||||
}
|
||||
|
||||
static inline void interpolateFloat(const float v1, const float v2, const float t, float* out) {
|
||||
float v = v2 - v1;
|
||||
*out = (v * t) + v1;
|
||||
GL_FORCE_INLINE void interpolateFloat(const float v1, const float v2, const float t, float* out) {
|
||||
*out = MATH_fmac(v2 - v1,t, v1);
|
||||
}
|
||||
|
||||
static inline void interpolateVec2(const float* v1, const float* v2, const float t, float* out) {
|
||||
/* FIXME: SH4 has an asm instruction for this */
|
||||
GL_FORCE_INLINE void interpolateVec2(const float* v1, const float* v2, const float t, float* out) {
|
||||
interpolateFloat(v1[0], v2[0], t, &out[0]);
|
||||
interpolateFloat(v1[1], v2[1], t, &out[1]);
|
||||
}
|
||||
|
||||
static inline void interpolateVec3(const float* v1, const float* v2, const float t, float* out) {
|
||||
/* FIXME: SH4 has an asm instruction for this */
|
||||
|
||||
GL_FORCE_INLINE void interpolateVec3(const float* v1, const float* v2, const float t, float* out) {
|
||||
interpolateFloat(v1[0], v2[0], t, &out[0]);
|
||||
interpolateFloat(v1[1], v2[1], t, &out[1]);
|
||||
interpolateFloat(v1[2], v2[2], t, &out[2]);
|
||||
}
|
||||
|
||||
static inline void interpolateVec4(const float* v1, const float* v2, const float t, float* out) {
|
||||
/* FIXME: SH4 has an asm instruction for this */
|
||||
GL_FORCE_INLINE void interpolateVec4(const float* v1, const float* v2, const float t, float* out) {
|
||||
interpolateFloat(v1[0], v2[0], t, &out[0]);
|
||||
interpolateFloat(v1[1], v2[1], t, &out[1]);
|
||||
interpolateFloat(v1[2], v2[2], t, &out[2]);
|
||||
interpolateFloat(v1[3], v2[3], t, &out[3]);
|
||||
}
|
||||
|
||||
static inline void interpolateColour(const uint8_t* v1, const uint8_t* v2, const float t, uint8_t* out) {
|
||||
GL_FORCE_INLINE void interpolateColour(const uint8_t* v1, const uint8_t* v2, const float t, uint8_t* out) {
|
||||
out[0] = v1[0] + (uint32_t) (((float) (v2[0] - v1[0])) * t);
|
||||
out[1] = v1[1] + (uint32_t) (((float) (v2[1] - v1[1])) * t);
|
||||
out[2] = v1[2] + (uint32_t) (((float) (v2[2] - v1[2])) * t);
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#pragma once
|
||||
|
||||
/* This figure is derived from the needs of Quake 1 */
|
||||
#define MAX_TEXTURE_COUNT 1088
|
||||
|
||||
|
||||
#endif // CONFIG_H
|
||||
|
|
68
GL/draw.c
68
GL/draw.c
|
@ -443,7 +443,7 @@ static void _fillWithNegZVE(GLuint count, GLfloat* output) {
|
|||
}
|
||||
}
|
||||
|
||||
static void _fillWhiteARGB(GLuint count, GLubyte* output) {
|
||||
GL_FORCE_INLINE void _fillWhiteARGB(GLuint count, GLubyte* output) {
|
||||
ITERATE(count) {
|
||||
output[R8IDX] = 255;
|
||||
output[G8IDX] = 255;
|
||||
|
@ -469,26 +469,50 @@ static void _fillZero2fVE(GLuint count, GLfloat* output) {
|
|||
}
|
||||
|
||||
static void _readVertexData3usARGB(const GLushort* input, GLuint count, GLubyte stride, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(count);
|
||||
_GL_UNUSED(stride);
|
||||
_GL_UNUSED(output);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
||||
static void _readVertexData3uiARGB(const GLuint* input, GLuint count, GLubyte stride, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(count);
|
||||
_GL_UNUSED(stride);
|
||||
_GL_UNUSED(output);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
||||
static void _readVertexData4usARGB(const GLushort* input, GLuint count, GLubyte stride, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(count);
|
||||
_GL_UNUSED(stride);
|
||||
_GL_UNUSED(output);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
||||
static void _readVertexData4uiARGB(const GLuint* input, GLuint count, GLubyte stride, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(count);
|
||||
_GL_UNUSED(stride);
|
||||
_GL_UNUSED(output);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
||||
static void _readVertexData4usRevARGB(const GLushort* input, GLuint count, GLubyte stride, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(count);
|
||||
_GL_UNUSED(stride);
|
||||
_GL_UNUSED(output);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
||||
static void _readVertexData4uiRevARGB(const GLuint* input, GLuint count, GLubyte stride, GLubyte* output) {
|
||||
_GL_UNUSED(input);
|
||||
_GL_UNUSED(count);
|
||||
_GL_UNUSED(stride);
|
||||
_GL_UNUSED(output);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
||||
|
@ -597,7 +621,7 @@ PVRHeader* _glSubmissionTargetHeader(SubmissionTarget* target) {
|
|||
return aligned_vector_at(&target->output->vector, target->header_offset);
|
||||
}
|
||||
|
||||
Vertex* _glSubmissionTargetStart(SubmissionTarget* target) {
|
||||
GL_INLINE_DEBUG Vertex* _glSubmissionTargetStart(SubmissionTarget* target) {
|
||||
assert(target->start_offset < target->output->vector.size);
|
||||
return aligned_vector_at(&target->output->vector, target->start_offset);
|
||||
}
|
||||
|
@ -810,7 +834,15 @@ GL_FORCE_INLINE void _readNormalData(const GLuint first, const GLuint count, Ver
|
|||
GLubyte* ptr = (GLubyte*) extra->nxyz;
|
||||
ITERATE(count) {
|
||||
GLfloat* n = (GLfloat*) ptr;
|
||||
vec3f_normalize(n[0], n[1], n[2]);
|
||||
float temp = n[0] * n[0];
|
||||
temp = MATH_fmac(n[1], n[1], temp);
|
||||
temp = MATH_fmac(n[2], n[2], temp);
|
||||
|
||||
float ilength = MATH_fsrra(temp);
|
||||
n[0] *= ilength;
|
||||
n[1] *= ilength;
|
||||
n[2] *= ilength;
|
||||
|
||||
ptr += sizeof(VertexExtra);
|
||||
}
|
||||
}
|
||||
|
@ -1104,9 +1136,6 @@ static void mat_transform_normal3(const float* xyz, const float* xyzOut, const u
|
|||
}
|
||||
|
||||
static void light(SubmissionTarget* target) {
|
||||
if(!_glIsLightingEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
static AlignedVector* eye_space_data = NULL;
|
||||
|
||||
|
@ -1132,16 +1161,6 @@ static void light(SubmissionTarget* target) {
|
|||
_glPerformLighting(vertex, ES, target->count);
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE float MATH_fsrra(float x) {
|
||||
__asm__ volatile ("fsrra %[one_div_sqrt]\n"
|
||||
: [one_div_sqrt] "+f" (x) // outputs, "+" means r/w
|
||||
: // no inputs
|
||||
: // no clobbers
|
||||
);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void divide(SubmissionTarget* target) {
|
||||
TRACE();
|
||||
|
||||
|
@ -1279,7 +1298,7 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count, GL
|
|||
|
||||
profiler_checkpoint("generate");
|
||||
|
||||
if(doLighting) {
|
||||
if(doLighting){
|
||||
light(target);
|
||||
}
|
||||
|
||||
|
@ -1386,6 +1405,7 @@ void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvo
|
|||
if(_glCheckImmediateModeInactive(__func__)) {
|
||||
return;
|
||||
}
|
||||
_glRecalcFastPath();
|
||||
|
||||
submitVertices(mode, 0, count, type, indices);
|
||||
}
|
||||
|
@ -1396,6 +1416,7 @@ void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
|||
if(_glCheckImmediateModeInactive(__func__)) {
|
||||
return;
|
||||
}
|
||||
_glRecalcFastPath();
|
||||
|
||||
submitVertices(mode, first, count, GL_UNSIGNED_INT, NULL);
|
||||
}
|
||||
|
@ -1421,8 +1442,6 @@ void APIENTRY glEnableClientState(GLenum cap) {
|
|||
default:
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
}
|
||||
|
||||
_glRecalcFastPath();
|
||||
}
|
||||
|
||||
void APIENTRY glDisableClientState(GLenum cap) {
|
||||
|
@ -1446,8 +1465,6 @@ void APIENTRY glDisableClientState(GLenum cap) {
|
|||
default:
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
}
|
||||
|
||||
_glRecalcFastPath();
|
||||
}
|
||||
|
||||
GLuint _glGetActiveClientTexture() {
|
||||
|
@ -1458,7 +1475,7 @@ void APIENTRY glClientActiveTextureARB(GLenum texture) {
|
|||
TRACE();
|
||||
|
||||
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) {
|
||||
_glKosThrowError(GL_INVALID_ENUM, "glClientActiveTextureARB");
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
}
|
||||
|
||||
if(_glKosHasError()) {
|
||||
|
@ -1489,8 +1506,6 @@ void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, cons
|
|||
tointer->stride = stride;
|
||||
tointer->type = type;
|
||||
tointer->size = size;
|
||||
|
||||
_glRecalcFastPath();
|
||||
}
|
||||
|
||||
void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {
|
||||
|
@ -1506,8 +1521,6 @@ void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const
|
|||
VERTEX_POINTER.stride = stride;
|
||||
VERTEX_POINTER.type = type;
|
||||
VERTEX_POINTER.size = size;
|
||||
|
||||
_glRecalcFastPath();
|
||||
}
|
||||
|
||||
void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) {
|
||||
|
@ -1523,8 +1536,6 @@ void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const G
|
|||
DIFFUSE_POINTER.stride = stride;
|
||||
DIFFUSE_POINTER.type = type;
|
||||
DIFFUSE_POINTER.size = size;
|
||||
|
||||
_glRecalcFastPath();
|
||||
}
|
||||
|
||||
void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid * pointer) {
|
||||
|
@ -1550,5 +1561,4 @@ void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid * poin
|
|||
NORMAL_POINTER.type = type;
|
||||
NORMAL_POINTER.size = (type == GL_UNSIGNED_INT_2_10_10_10_REV) ? 1 : 3;
|
||||
|
||||
_glRecalcFastPath();
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ void _glKosPrintError() {
|
|||
}
|
||||
|
||||
fprintf(stderr, "GL ERROR: %s when calling %s\n", _glErrorEnumAsString(last_error), error_function);
|
||||
_glKosResetError();
|
||||
}
|
||||
|
||||
GLenum glGetError(void) {
|
||||
|
|
|
@ -63,6 +63,7 @@ void APIENTRY glDeleteFramebuffersEXT(GLsizei n, const GLuint* framebuffers) {
|
|||
}
|
||||
|
||||
void APIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer) {
|
||||
_GL_UNUSED(target);
|
||||
TRACE();
|
||||
|
||||
if(framebuffer) {
|
||||
|
@ -76,6 +77,10 @@ void APIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer) {
|
|||
}
|
||||
|
||||
void APIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
|
||||
_GL_UNUSED(target);
|
||||
_GL_UNUSED(attachment);
|
||||
_GL_UNUSED(textarget);
|
||||
_GL_UNUSED(level);
|
||||
if(texture != 0 && !glIsTexture(texture)) {
|
||||
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||
_glKosPrintError();
|
||||
|
@ -91,62 +96,62 @@ void APIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum
|
|||
ACTIVE_FRAMEBUFFER->texture_id = texture;
|
||||
}
|
||||
|
||||
static inline GLubyte A1555(GLushort v) {
|
||||
GL_FORCE_INLINE GLuint A1555(GLuint v) {
|
||||
const GLuint MASK = (1 << 15);
|
||||
return (v & MASK) >> 8;
|
||||
}
|
||||
|
||||
static inline GLubyte R1555(GLushort v) {
|
||||
GL_FORCE_INLINE GLuint R1555(GLuint v) {
|
||||
const GLuint MASK = (31 << 10);
|
||||
return (v & MASK) >> 7;
|
||||
}
|
||||
|
||||
static inline GLubyte G1555(GLushort v) {
|
||||
GL_FORCE_INLINE GLuint G1555(GLuint v) {
|
||||
const GLuint MASK = (31 << 5);
|
||||
return (v & MASK) >> 2;
|
||||
}
|
||||
|
||||
static inline GLubyte B1555(GLushort v) {
|
||||
GL_FORCE_INLINE GLuint B1555(GLuint v) {
|
||||
const GLuint MASK = (31 << 0);
|
||||
return (v & MASK) << 3;
|
||||
}
|
||||
|
||||
static inline GLubyte A4444(GLushort v) {
|
||||
GL_FORCE_INLINE GLuint A4444(GLuint v) {
|
||||
const GLuint MASK = (0xF << 12);
|
||||
return (v & MASK) >> 12;
|
||||
}
|
||||
|
||||
static inline GLubyte R4444(GLushort v) {
|
||||
GL_FORCE_INLINE GLuint R4444(GLuint v) {
|
||||
const GLuint MASK = (0xF << 8);
|
||||
return (v & MASK) >> 8;
|
||||
}
|
||||
|
||||
static inline GLubyte G4444(GLushort v) {
|
||||
GL_FORCE_INLINE GLuint G4444(GLuint v) {
|
||||
const GLuint MASK = (0xF << 4);
|
||||
return (v & MASK) >> 4;
|
||||
}
|
||||
|
||||
static inline GLubyte B4444(GLushort v) {
|
||||
GL_FORCE_INLINE GLuint B4444(GLuint v) {
|
||||
const GLuint MASK = (0xF << 0);
|
||||
return (v & MASK) >> 0;
|
||||
}
|
||||
|
||||
static inline GLubyte R565(GLushort v) {
|
||||
GL_FORCE_INLINE GLuint R565(GLuint v) {
|
||||
const GLuint MASK = (31 << 11);
|
||||
return (v & MASK) >> 8;
|
||||
}
|
||||
|
||||
static inline GLubyte G565(GLushort v) {
|
||||
GL_FORCE_INLINE GLuint G565(GLuint v) {
|
||||
const GLuint MASK = (63 << 5);
|
||||
return (v & MASK) >> 3;
|
||||
}
|
||||
|
||||
static inline GLubyte B565(GLushort v) {
|
||||
GL_FORCE_INLINE GLuint B565(GLuint v) {
|
||||
const GLuint MASK = (31 << 0);
|
||||
return (v & MASK) << 3;
|
||||
}
|
||||
|
||||
GLboolean _glCalculateAverageTexel(GLuint pvrFormat, const GLubyte* src1, const GLubyte* src2, const GLubyte* src3, const GLubyte* src4, GLubyte* t) {
|
||||
static GL_NO_INSTRUMENT GLboolean _glCalculateAverageTexel(GLuint pvrFormat, const GLubyte* src1, const GLubyte* src2, const GLubyte* src3, const GLubyte* src4, GLubyte* t) {
|
||||
GLuint a, r, g, b;
|
||||
|
||||
GLubyte format = ((pvrFormat & (1 << 27)) | (pvrFormat & (1 << 26))) >> 26;
|
||||
|
|
4
GL/glu.c
4
GL/glu.c
|
@ -4,9 +4,9 @@
|
|||
/* Set the Perspective */
|
||||
void APIENTRY gluPerspective(GLfloat angle, GLfloat aspect,
|
||||
GLfloat znear, GLfloat zfar) {
|
||||
GLdouble fW, fH;
|
||||
GLfloat fW, fH;
|
||||
|
||||
fH = tan(angle / 360 * F_PI) * znear;
|
||||
fH = tanf(angle * (F_PI / 360.0f)) * znear;
|
||||
fW = fH * aspect;
|
||||
|
||||
glFrustum(-fW, fW, -fH, fH, znear, zfar);
|
||||
|
|
|
@ -192,6 +192,7 @@ void APIENTRY glVertex2fv(const GLfloat* v) {
|
|||
}
|
||||
|
||||
void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
|
||||
_GL_UNUSED(w);
|
||||
glVertex3f(x, y, z);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
static GLfloat SCENE_AMBIENT [] = {0.2f, 0.2f, 0.2f, 1.0f};
|
||||
static GLboolean VIEWER_IN_EYE_COORDINATES = GL_TRUE;
|
||||
static GLenum COLOR_CONTROL = GL_SINGLE_COLOR;
|
||||
static GLboolean TWO_SIDED_LIGHTING = GL_FALSE;
|
||||
|
||||
static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE;
|
||||
|
||||
static LightSource LIGHTS[MAX_LIGHTS];
|
||||
|
@ -346,18 +346,8 @@ GL_FORCE_INLINE void _glLightVertexPoint(
|
|||
#undef _PROCESS_COMPONENT
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE float MATH_fsrra(float x) {
|
||||
__asm__ volatile ("fsrra %[one_div_sqrt]\n"
|
||||
: [one_div_sqrt] "+f" (x) // outputs, "+" means r/w
|
||||
: // no inputs
|
||||
: // no clobbers
|
||||
);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void bgra_to_float(const uint8_t* input, GLfloat* output) {
|
||||
const static float scale = 1.0f / 255.0f;
|
||||
static const float scale = 1.0f / 255.0f;
|
||||
|
||||
output[0] = ((float) input[R8IDX]) * scale;
|
||||
output[1] = ((float) input[G8IDX]) * scale;
|
||||
|
|
106
GL/matrix.c
106
GL/matrix.c
|
@ -12,8 +12,6 @@
|
|||
|
||||
#define DEG2RAD (0.01745329251994329576923690768489)
|
||||
|
||||
/* Viewport mapping */
|
||||
static GLfloat gl_viewport_scale[3], gl_viewport_offset[3];
|
||||
|
||||
/* Depth range */
|
||||
GLfloat DEPTH_RANGE_MULTIPLIER_L = (1 - 0) / 2;
|
||||
|
@ -47,8 +45,6 @@ static void _glStoreNearPlane() {
|
|||
NEAR_PLANE_DISTANCE = -b / (1.0f - a);
|
||||
}
|
||||
|
||||
void APIENTRY glDepthRange(GLclampf n, GLclampf f);
|
||||
|
||||
static inline void upload_matrix(Matrix4x4* m) {
|
||||
mat_load((matrix_t*) m);
|
||||
}
|
||||
|
@ -78,8 +74,8 @@ void _glInitMatrices() {
|
|||
stack_push(&MATRIX_STACKS[1], IDENTITY);
|
||||
stack_push(&MATRIX_STACKS[2], IDENTITY);
|
||||
|
||||
memcpy(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4));
|
||||
memcpy(SCREENVIEW_MATRIX, IDENTITY, sizeof(Matrix4x4));
|
||||
memcpy4(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4));
|
||||
memcpy4(SCREENVIEW_MATRIX, IDENTITY, sizeof(Matrix4x4));
|
||||
|
||||
glDepthRange(0.0f, 1.0f);
|
||||
glViewport(0, 0, vid_mode->width, vid_mode->height);
|
||||
|
@ -123,7 +119,7 @@ static void transpose(GLfloat* m) {
|
|||
}
|
||||
|
||||
static void recalculateNormalMatrix() {
|
||||
memcpy(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(Matrix4x4));
|
||||
memcpy4(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(Matrix4x4));
|
||||
inverse((GLfloat*) NORMAL_MATRIX);
|
||||
transpose((GLfloat*) NORMAL_MATRIX);
|
||||
}
|
||||
|
@ -465,7 +461,7 @@ GLfloat _glGetNearPlane() {
|
|||
}
|
||||
|
||||
/* Set the depth range */
|
||||
void APIENTRY glDepthRange(GLclampf n, GLclampf f) {
|
||||
void APIENTRY glDepthRangef(GLclampf n, GLclampf f) {
|
||||
if(n < 0.0f) n = 0.0f;
|
||||
else if(n > 1.0f) n = 1.0f;
|
||||
|
||||
|
@ -476,58 +472,55 @@ void APIENTRY glDepthRange(GLclampf n, GLclampf f) {
|
|||
DEPTH_RANGE_MULTIPLIER_H = (n + f) / 2.0f;
|
||||
}
|
||||
|
||||
/* Vector Cross Product - Used by glhLookAtf2 */
|
||||
void APIENTRY glDepthRange(GLclampf n, GLclampf f){
|
||||
glDepthRangef(n,f);
|
||||
}
|
||||
|
||||
/* Vector Cross Product - Used by gluLookAt */
|
||||
static inline void vec3f_cross(const GLfloat* v1, const GLfloat* v2, GLfloat* result) {
|
||||
result[0] = v1[1] * v2[2] - v1[2] * v2[1];
|
||||
result[1] = v1[2] * v2[0] - v1[0] * v2[2];
|
||||
result[2] = v1[0] * v2[1] - v1[1] * v2[0];
|
||||
}
|
||||
|
||||
/* glhLookAtf2 adapted from http://www.opengl.org/wiki/GluLookAt_code */
|
||||
void glhLookAtf2(const GLfloat* eyePosition3D,
|
||||
const GLfloat* center3D,
|
||||
const GLfloat* upVector3D) {
|
||||
static inline void vec3f_normalize_sh4(float *v){
|
||||
float length, ilength;
|
||||
|
||||
/* Look-At Matrix */
|
||||
static Matrix4x4 MatrixLookAt __attribute__((aligned(32))) = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
ilength = MATH_fsrra(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
|
||||
length = MATH_Invert(ilength);
|
||||
if (length)
|
||||
{
|
||||
v[0] *= ilength;
|
||||
v[1] *= ilength;
|
||||
v[2] *= ilength;
|
||||
}
|
||||
}
|
||||
|
||||
GLfloat forward[3];
|
||||
GLfloat side[3];
|
||||
GLfloat up[3];
|
||||
void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
|
||||
GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy,
|
||||
GLfloat upz) {
|
||||
GLfloat m [16];
|
||||
GLfloat f [3];
|
||||
GLfloat u [3];
|
||||
GLfloat s [3];
|
||||
|
||||
vec3f_sub_normalize(center3D[0], center3D[1], center3D[2],
|
||||
eyePosition3D[0], eyePosition3D[1], eyePosition3D[2],
|
||||
forward[0], forward[1], forward[2]);
|
||||
f[0] = centerx - eyex;
|
||||
f[1] = centery - eyey;
|
||||
f[2] = centerz - eyez;
|
||||
|
||||
//Side = forward x up
|
||||
vec3f_cross(forward, upVector3D, side);
|
||||
vec3f_normalize(side[0], side[1], side[2]);
|
||||
u[0] = upx;
|
||||
u[1] = upy;
|
||||
u[2] = upz;
|
||||
|
||||
//Recompute up as: up = side x forward
|
||||
vec3f_cross(side, forward, up);
|
||||
vec3f_normalize_sh4(f);
|
||||
vec3f_cross(f, u, s);
|
||||
vec3f_normalize_sh4(s);
|
||||
vec3f_cross(s, f, u);
|
||||
|
||||
MatrixLookAt[M0] = side[0];
|
||||
MatrixLookAt[M4] = side[1];
|
||||
MatrixLookAt[M8] = side[2];
|
||||
MatrixLookAt[M12] = 0;
|
||||
|
||||
MatrixLookAt[M1] = up[0];
|
||||
MatrixLookAt[M5] = up[1];
|
||||
MatrixLookAt[M9] = up[2];
|
||||
MatrixLookAt[M13] = 0;
|
||||
|
||||
MatrixLookAt[M2] = -forward[0];
|
||||
MatrixLookAt[M6] = -forward[1];
|
||||
MatrixLookAt[M10] = -forward[2];
|
||||
MatrixLookAt[M14] = 0;
|
||||
|
||||
MatrixLookAt[M3] = MatrixLookAt[11] = MatrixLookAt[15] = 0;
|
||||
MatrixLookAt[M15] = 1;
|
||||
m[0] = s[0]; m[4] = s[1]; m[8] = s[2]; m[12] = 0.0f;
|
||||
m[1] = u[0]; m[5] = u[1]; m[9] = u[2]; m[13] = 0.0f;
|
||||
m[2] = -f[0]; m[6] = -f[1]; m[10] = -f[2]; m[14] = 0.0f;
|
||||
m[3] = 0.0f; m[7] = 0.0f; m[11] = 0.0f; m[15] = 1.0f;
|
||||
|
||||
static Matrix4x4 trn __attribute__((aligned(32))) = {
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
|
@ -536,26 +529,17 @@ void glhLookAtf2(const GLfloat* eyePosition3D,
|
|||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
trn[M12] = -eyePosition3D[0];
|
||||
trn[M13] = -eyePosition3D[1];
|
||||
trn[M14] = -eyePosition3D[2];
|
||||
trn[M12] = -eyex;
|
||||
trn[M13] = -eyey;
|
||||
trn[M14] = -eyez;
|
||||
|
||||
// Does not modify internal Modelview matrix
|
||||
upload_matrix(&MatrixLookAt);
|
||||
upload_matrix(&m);
|
||||
multiply_matrix(&trn);
|
||||
multiply_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
|
||||
download_matrix(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
|
||||
}
|
||||
|
||||
void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
|
||||
GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy,
|
||||
GLfloat upz) {
|
||||
GLfloat eye [] = { eyex, eyey, eyez };
|
||||
GLfloat point [] = { centerx, centery, centerz };
|
||||
GLfloat up [] = { upx, upy, upz };
|
||||
glhLookAtf2(eye, point, up);
|
||||
}
|
||||
|
||||
void _glApplyRenderMatrix() {
|
||||
upload_matrix(&SCREENVIEW_MATRIX);
|
||||
multiply_matrix(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF)));
|
||||
|
|
92
GL/private.h
92
GL/private.h
|
@ -11,12 +11,21 @@
|
|||
#include "../include/gl.h"
|
||||
#include "../containers/aligned_vector.h"
|
||||
#include "../containers/named_array.h"
|
||||
#include "sh4_math.h"
|
||||
|
||||
#define GL_FORCE_INLINE __attribute__((always_inline)) static __inline__
|
||||
extern void* memcpy4 (void *dest, const void *src, size_t count);
|
||||
|
||||
#define GL_NO_INSTRUMENT inline __attribute__((no_instrument_function))
|
||||
#define GL_INLINE_DEBUG GL_NO_INSTRUMENT __attribute__((always_inline))
|
||||
#define GL_FORCE_INLINE static GL_INLINE_DEBUG
|
||||
#define _GL_UNUSED(x) (void)(x)
|
||||
|
||||
#define FASTCPY(dst, src, bytes) \
|
||||
(bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy(dst, src, bytes);
|
||||
|
||||
#define FASTCPY4(dst, src, bytes) \
|
||||
(bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy4(dst, src, bytes);
|
||||
|
||||
#define _PACK4(v) ((v * 0xF) / 0xFF)
|
||||
#define PACK_ARGB4444(a,r,g,b) (_PACK4(a) << 12) | (_PACK4(r) << 8) | (_PACK4(g) << 4) | (_PACK4(b))
|
||||
#define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) )
|
||||
|
@ -109,35 +118,41 @@ typedef struct {
|
|||
} TexturePalette;
|
||||
|
||||
typedef struct {
|
||||
GLushort width;
|
||||
GLushort height;
|
||||
GLuint color; /* This is the PVR texture format */
|
||||
GLubyte env;
|
||||
GLushort mipmap; /* Bitmask of supplied mipmap levels */
|
||||
GLubyte mipmapCount; /* The number of mipmap levels */
|
||||
GLubyte uv_clamp;
|
||||
//0
|
||||
GLuint index;
|
||||
GLvoid *data;
|
||||
GLuint dataStride;
|
||||
GLuint baseDataSize; /* The data size of mipmap level 0 */
|
||||
|
||||
GLuint color; /* This is the PVR texture format */
|
||||
//8
|
||||
GLenum minFilter;
|
||||
GLenum magFilter;
|
||||
|
||||
GLboolean isCompressed;
|
||||
GLboolean isPaletted;
|
||||
|
||||
//16
|
||||
GLvoid *data;
|
||||
TexturePalette* palette;
|
||||
//24
|
||||
GLushort width;
|
||||
GLushort height;
|
||||
//28
|
||||
GLushort mipmap; /* Bitmask of supplied mipmap levels */
|
||||
/* When using the shared palette, this is the bank (0-3) */
|
||||
GLushort shared_bank;
|
||||
//32
|
||||
GLuint dataStride;
|
||||
//36
|
||||
GLubyte mipmap_bias;
|
||||
GLubyte env;
|
||||
GLubyte mipmapCount; /* The number of mipmap levels */
|
||||
GLubyte uv_clamp;
|
||||
//40
|
||||
/* Mipmap textures have a different
|
||||
* offset for the base level when supplying the data, this
|
||||
* keeps track of that. baseDataOffset == 0
|
||||
* means that the texture has no mipmaps
|
||||
*/
|
||||
GLuint baseDataOffset;
|
||||
|
||||
TexturePalette* palette;
|
||||
|
||||
/* When using the shared palette, this is the bank (0-3) */
|
||||
GLushort shared_bank;
|
||||
GLuint baseDataSize; /* The data size of mipmap level 0 */
|
||||
//48
|
||||
GLboolean isCompressed;
|
||||
GLboolean isPaletted;
|
||||
//50
|
||||
} TextureObject;
|
||||
|
||||
typedef struct {
|
||||
|
@ -176,20 +191,6 @@ typedef struct {
|
|||
float w;
|
||||
} Vertex;
|
||||
|
||||
/* FIXME: SH4 has a swap.w instruction, we should leverage it here! */
|
||||
#define _SWAP32(x, y) \
|
||||
do { \
|
||||
uint32_t t = *((uint32_t*) &x); \
|
||||
*((uint32_t*) &x) = *((uint32_t*) &y); \
|
||||
*((uint32_t*) &y) = t; \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
*((uint32_t*) &x) = *((uint32_t*) &x) ^ *((uint32_t*) &y); \
|
||||
*((uint32_t*) &y) = *((uint32_t*) &x) ^ *((uint32_t*) &y); \
|
||||
*((uint32_t*) &x) = *((uint32_t*) &x) ^ *((uint32_t*) &y); */
|
||||
|
||||
|
||||
#define swapVertex(a, b) \
|
||||
do { \
|
||||
Vertex c = *a; \
|
||||
|
@ -307,8 +308,8 @@ GLboolean _glIsBlendingEnabled();
|
|||
GLboolean _glIsAlphaTestEnabled();
|
||||
|
||||
GLboolean _glIsMipmapComplete(const TextureObject* obj);
|
||||
GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level);
|
||||
GLuint _glGetMipmapLevelCount(TextureObject* obj);
|
||||
GLubyte* _glGetMipmapLocation(const TextureObject* obj, GLuint level);
|
||||
GLuint _glGetMipmapLevelCount(const TextureObject* obj);
|
||||
|
||||
GLboolean _glIsLightingEnabled();
|
||||
GLboolean _glIsLightEnabled(GLubyte light);
|
||||
|
@ -336,19 +337,8 @@ GLubyte _glKosHasError();
|
|||
#define MAX_TEXTURE_UNITS 2
|
||||
#define MAX_LIGHTS 8
|
||||
|
||||
#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
|
||||
|
||||
#define mat_trans_fv12() { \
|
||||
__asm__ __volatile__( \
|
||||
"fldi1 fr15\n" \
|
||||
"ftrv xmtrx, fv12\n" \
|
||||
"fldi1 fr14\n" \
|
||||
"fdiv fr15, fr14\n" \
|
||||
"fmul fr14, fr12\n" \
|
||||
"fmul fr14, fr13\n" \
|
||||
: "=f" (__x), "=f" (__y), "=f" (__z) \
|
||||
: "0" (__x), "1" (__y), "2" (__z) \
|
||||
: "fr15" ); \
|
||||
}
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#define CLAMP( X, _MIN, _MAX ) ( (X)<(_MIN) ? (_MIN) : ((X)>(_MAX) ? (_MAX) : (X)) )
|
||||
|
||||
#endif // PRIVATE_H
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "profiler.h"
|
||||
#include "../containers/aligned_vector.h"
|
||||
|
||||
#if PROFILING_COMPILED
|
||||
|
||||
#define MAX_PATH 256
|
||||
|
||||
typedef struct {
|
||||
|
@ -141,3 +143,4 @@ void profiler_print_stats() {
|
|||
fprintf(stderr, "%-60s%-20f%-20f%" PRIu64 "\n", result->name, (double)avg, (double)ms, result->total_calls);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -7,12 +7,26 @@ typedef struct {
|
|||
uint64_t start_time_in_us;
|
||||
} Profiler;
|
||||
|
||||
#define PROFILING_COMPILED 0
|
||||
|
||||
#if PROFILING_COMPILED
|
||||
Profiler* profiler_push(const char* name);
|
||||
void profiler_checkpoint(const char* name);
|
||||
void profiler_pop();
|
||||
void _profiler_checkpoint(const char* name);
|
||||
void _profiler_pop();
|
||||
|
||||
void profiler_print_stats();
|
||||
void _profiler_print_stats();
|
||||
|
||||
void profiler_enable();
|
||||
void profiler_disable();
|
||||
void _profiler_enable();
|
||||
void _profiler_disable();
|
||||
|
||||
#else
|
||||
#define profiler_push(name);
|
||||
#define profiler_checkpoint(name);
|
||||
#define profiler_pop();
|
||||
|
||||
#define profiler_print_stats();
|
||||
|
||||
#define profiler_enable();
|
||||
#define profiler_disable();
|
||||
|
||||
#endif
|
||||
|
|
54
GL/sh4_math.h
Normal file
54
GL/sh4_math.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
// ---- sh4_math.h - SH7091 Math Module ----
|
||||
//
|
||||
// Version 1.0.8
|
||||
//
|
||||
// This file is part of the DreamHAL project, a hardware abstraction library
|
||||
// primarily intended for use on the SH7091 found in hardware such as the SEGA
|
||||
// Dreamcast game console.
|
||||
//
|
||||
// This math module is hereby released into the public domain in the hope that it
|
||||
// may prove useful. Now go hit 60 fps! :)
|
||||
//
|
||||
// --Moopthehedgehog
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
// 1/x
|
||||
// (1.0f / sqrt(x)) ^ 2
|
||||
// This is about 3x faster than fdiv!
|
||||
static inline __attribute__((always_inline)) float MATH_Invert(float x)
|
||||
{
|
||||
asm volatile ("fsrra %[one_div_sqrt]\n\t"
|
||||
"fmul %[one_div_sqrt], %[one_div_sqrt]\n"
|
||||
: [one_div_sqrt] "+f" (x) // outputs, "+" means r/w
|
||||
: // no inputs
|
||||
: // no clobbers
|
||||
);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// 1/sqrt(x)
|
||||
static inline __attribute__((always_inline)) float MATH_fsrra(float x)
|
||||
{
|
||||
asm volatile ("fsrra %[one_div_sqrt]\n"
|
||||
: [one_div_sqrt] "+f" (x) // outputs, "+" means r/w
|
||||
: // no inputs
|
||||
: // no clobbers
|
||||
);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// a*b+c
|
||||
static inline __attribute__((always_inline)) float MATH_fmac(float a, float b, float c)
|
||||
{
|
||||
asm volatile ("fmac fr0, %[floatb], %[floatc]\n"
|
||||
: [floatc] "+f" (c) // outputs, "+" means r/w
|
||||
: "w" (a), [floatb] "f" (b) // inputs
|
||||
: // no clobbers
|
||||
);
|
||||
|
||||
return c;
|
||||
}
|
73
GL/state.c
73
GL/state.c
|
@ -18,7 +18,6 @@ pvr_poly_cxt_t* _glGetPVRContext() {
|
|||
return &GL_CONTEXT;
|
||||
}
|
||||
|
||||
|
||||
/* We can't just use the GL_CONTEXT for this state as the two
|
||||
* GL states are combined, so we store them separately and then
|
||||
* calculate the appropriate PVR state from them. */
|
||||
|
@ -32,6 +31,8 @@ static GLboolean SHARED_PALETTE_ENABLED = GL_FALSE;
|
|||
|
||||
static GLboolean ALPHA_TEST_ENABLED = GL_FALSE;
|
||||
|
||||
static GLboolean POLYGON_OFFSET_ENABLED = GL_FALSE;
|
||||
|
||||
static GLboolean NORMALIZE_ENABLED = GL_FALSE;
|
||||
|
||||
GLboolean _glIsSharedTexturePaletteEnabled() {
|
||||
|
@ -84,6 +85,9 @@ static GLenum BLEND_SFACTOR = GL_ONE;
|
|||
static GLenum BLEND_DFACTOR = GL_ZERO;
|
||||
static GLboolean BLEND_ENABLED = GL_FALSE;
|
||||
|
||||
static GLfloat OFFSET_FACTOR = 0.0f;
|
||||
static GLfloat OFFSET_UNITS = 0.0f;
|
||||
|
||||
GLboolean _glIsNormalizeEnabled() {
|
||||
return NORMALIZE_ENABLED;
|
||||
}
|
||||
|
@ -150,7 +154,7 @@ GLboolean _glCheckValidEnum(GLint param, GLint* values, const char* func) {
|
|||
return GL_FALSE;
|
||||
}
|
||||
|
||||
static GLboolean TEXTURES_ENABLED [] = {GL_FALSE, GL_FALSE};
|
||||
GLboolean TEXTURES_ENABLED [] = {GL_FALSE, GL_FALSE};
|
||||
|
||||
void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
|
||||
const TextureObject *tx1 = (textureUnit == 0) ? _glGetTexture0() : _glGetTexture1();
|
||||
|
@ -187,6 +191,10 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
|
|||
enableMipmaps = GL_TRUE;
|
||||
}
|
||||
|
||||
if(tx1->height != tx1->width){
|
||||
enableMipmaps = GL_FALSE;
|
||||
}
|
||||
|
||||
if(enableMipmaps) {
|
||||
if(tx1->minFilter == GL_LINEAR_MIPMAP_NEAREST) {
|
||||
filter = PVR_FILTER_TRILINEAR1;
|
||||
|
@ -215,15 +223,13 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
|
|||
context->txr.filter = filter;
|
||||
context->txr.width = tx1->width;
|
||||
context->txr.height = tx1->height;
|
||||
context->txr.mipmap = enableMipmaps;
|
||||
context->txr.mipmap_bias = tx1->mipmap_bias;
|
||||
|
||||
if(enableMipmaps) {
|
||||
context->txr.base = tx1->data;
|
||||
context->txr.mipmap = PVR_MIPMAP_ENABLE;
|
||||
context->txr.mipmap_bias = PVR_MIPBIAS_NORMAL;
|
||||
} else {
|
||||
context->txr.base = tx1->data + tx1->baseDataOffset;
|
||||
context->txr.mipmap = PVR_MIPMAP_DISABLE;
|
||||
context->txr.mipmap_bias = PVR_MIPBIAS_NORMAL;
|
||||
}
|
||||
|
||||
context->txr.format = tx1->color;
|
||||
|
@ -338,6 +344,11 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
|
|||
case GL_NEARZ_CLIPPING_KOS:
|
||||
_glEnableClipping(GL_TRUE);
|
||||
break;
|
||||
case GL_POLYGON_OFFSET_POINT:
|
||||
case GL_POLYGON_OFFSET_LINE:
|
||||
case GL_POLYGON_OFFSET_FILL:
|
||||
POLYGON_OFFSET_ENABLED = GL_TRUE;
|
||||
break;
|
||||
case GL_NORMALIZE:
|
||||
NORMALIZE_ENABLED = GL_TRUE;
|
||||
break;
|
||||
|
@ -395,6 +406,11 @@ GLAPI void APIENTRY glDisable(GLenum cap) {
|
|||
case GL_NEARZ_CLIPPING_KOS:
|
||||
_glEnableClipping(GL_FALSE);
|
||||
break;
|
||||
case GL_POLYGON_OFFSET_POINT:
|
||||
case GL_POLYGON_OFFSET_LINE:
|
||||
case GL_POLYGON_OFFSET_FILL:
|
||||
POLYGON_OFFSET_ENABLED = GL_FALSE;
|
||||
break;
|
||||
case GL_NORMALIZE:
|
||||
NORMALIZE_ENABLED = GL_FALSE;
|
||||
break;
|
||||
|
@ -423,18 +439,22 @@ GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
|||
|
||||
/* Depth Testing */
|
||||
GLAPI void APIENTRY glClearDepthf(GLfloat depth) {
|
||||
_GL_UNUSED(depth);
|
||||
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glClearDepth(GLfloat depth) {
|
||||
_GL_UNUSED(depth);
|
||||
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glDrawBuffer(GLenum mode) {
|
||||
_GL_UNUSED(mode);
|
||||
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glReadBuffer(GLenum mode) {
|
||||
_GL_UNUSED(mode);
|
||||
|
||||
}
|
||||
|
||||
|
@ -500,23 +520,30 @@ GLAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref) {
|
|||
}
|
||||
|
||||
void glLineWidth(GLfloat width) {
|
||||
;
|
||||
_GL_UNUSED(width);
|
||||
}
|
||||
|
||||
void glPolygonOffset(GLfloat factor, GLfloat units) {
|
||||
;
|
||||
OFFSET_FACTOR = factor;
|
||||
OFFSET_UNITS = units;
|
||||
}
|
||||
|
||||
void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params) {
|
||||
;
|
||||
_GL_UNUSED(target);
|
||||
_GL_UNUSED(pname);
|
||||
_GL_UNUSED(params);
|
||||
}
|
||||
|
||||
void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
|
||||
;
|
||||
_GL_UNUSED(red);
|
||||
_GL_UNUSED(green);
|
||||
_GL_UNUSED(blue);
|
||||
_GL_UNUSED(alpha);
|
||||
}
|
||||
|
||||
void glPixelStorei(GLenum pname, GLint param) {
|
||||
;
|
||||
_GL_UNUSED(pname);
|
||||
_GL_UNUSED(param);
|
||||
}
|
||||
|
||||
|
||||
|
@ -538,8 +565,8 @@ void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
|
|||
PVRTileClipCommand *c = aligned_vector_extend(&_glActivePolyList()->vector, 1);
|
||||
|
||||
GLint miny, maxx, maxy;
|
||||
GLsizei gl_scissor_width = CLAMP(width, 0, vid_mode->width);
|
||||
GLsizei gl_scissor_height = CLAMP(height, 0, vid_mode->height);
|
||||
GLsizei gl_scissor_width = MAX( MIN(width, vid_mode->width), 0 );
|
||||
GLsizei gl_scissor_height = MAX( MIN(height, vid_mode->height), 0 );
|
||||
|
||||
/* force the origin to the lower left-hand corner of the screen */
|
||||
miny = (vid_mode->height - gl_scissor_height) - y;
|
||||
|
@ -567,6 +594,10 @@ GLboolean APIENTRY glIsEnabled(GLenum cap) {
|
|||
return LIGHTING_ENABLED;
|
||||
case GL_BLEND:
|
||||
return BLEND_ENABLED;
|
||||
case GL_POLYGON_OFFSET_POINT:
|
||||
case GL_POLYGON_OFFSET_LINE:
|
||||
case GL_POLYGON_OFFSET_FILL:
|
||||
return POLYGON_OFFSET_ENABLED;
|
||||
}
|
||||
|
||||
return GL_FALSE;
|
||||
|
@ -581,7 +612,7 @@ static GLenum COMPRESSED_FORMATS [] = {
|
|||
GL_COMPRESSED_RGB_565_VQ_TWID_KOS
|
||||
};
|
||||
|
||||
static GLint NUM_COMPRESSED_FORMATS = sizeof(COMPRESSED_FORMATS) / sizeof(GLenum);
|
||||
static GLuint NUM_COMPRESSED_FORMATS = sizeof(COMPRESSED_FORMATS) / sizeof(GLenum);
|
||||
|
||||
void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) {
|
||||
GLuint enabledAttrs = *_glGetEnabledAttributes();
|
||||
|
@ -616,13 +647,19 @@ void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) {
|
|||
void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) {
|
||||
switch(pname) {
|
||||
case GL_PROJECTION_MATRIX:
|
||||
memcpy(params, _glGetProjectionMatrix(), sizeof(float) * 16);
|
||||
memcpy4(params, _glGetProjectionMatrix(), sizeof(float) * 16);
|
||||
break;
|
||||
case GL_MODELVIEW_MATRIX:
|
||||
memcpy(params, _glGetModelViewMatrix(), sizeof(float) * 16);
|
||||
memcpy4(params, _glGetModelViewMatrix(), sizeof(float) * 16);
|
||||
break;
|
||||
case GL_POLYGON_OFFSET_FACTOR:
|
||||
*params = OFFSET_FACTOR;
|
||||
break;
|
||||
case GL_POLYGON_OFFSET_UNITS:
|
||||
*params = OFFSET_UNITS;
|
||||
break;
|
||||
default:
|
||||
_glKosThrowError(GL_INVALID_ENUM, "glGetIntegerv");
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
_glKosPrintError();
|
||||
break;
|
||||
}
|
||||
|
@ -664,7 +701,7 @@ void APIENTRY glGetIntegerv(GLenum pname, GLint *params) {
|
|||
}
|
||||
} break;
|
||||
default:
|
||||
_glKosThrowError(GL_INVALID_ENUM, "glGetIntegerv");
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
_glKosPrintError();
|
||||
break;
|
||||
}
|
||||
|
|
282
GL/texture.c
282
GL/texture.c
|
@ -9,12 +9,11 @@
|
|||
#include "config.h"
|
||||
#include "../include/glext.h"
|
||||
#include "../include/glkos.h"
|
||||
#include <kos/string.h>
|
||||
|
||||
#define CLAMP_U (1<<1)
|
||||
#define CLAMP_V (1<<0)
|
||||
|
||||
#define MAX(x, y) ((x > y) ? x : y)
|
||||
|
||||
static TextureObject* TEXTURE_UNITS[MAX_TEXTURE_UNITS] = {NULL, NULL};
|
||||
static NamedArray TEXTURE_OBJECTS;
|
||||
static GLubyte ACTIVE_TEXTURE = 0;
|
||||
|
@ -31,7 +30,7 @@ static TexturePalette* _initTexturePalette() {
|
|||
TexturePalette* palette = (TexturePalette*) malloc(sizeof(TexturePalette));
|
||||
assert(palette);
|
||||
|
||||
memset(palette, 0x0, sizeof(TexturePalette));
|
||||
memset4(palette, 0x0, sizeof(TexturePalette));
|
||||
palette->bank = -1;
|
||||
return palette;
|
||||
}
|
||||
|
@ -133,7 +132,7 @@ GLubyte _glGetActiveTexture() {
|
|||
return ACTIVE_TEXTURE;
|
||||
}
|
||||
|
||||
static GLint _determineStride(GLenum format, GLenum type) {
|
||||
static GLint _determineStride(GLenum format, GLenum type) {
|
||||
switch(type) {
|
||||
case GL_BYTE:
|
||||
case GL_UNSIGNED_BYTE:
|
||||
|
@ -155,7 +154,7 @@ static GLint _determineStride(GLenum format, GLenum type) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) {
|
||||
static GLuint _glGetMipmapDataOffset(const TextureObject* obj, GLuint level) {
|
||||
GLuint offset = 0;
|
||||
GLuint size = obj->height;
|
||||
|
||||
|
@ -163,7 +162,7 @@ static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) {
|
|||
fprintf(stderr, "ERROR: Accessing memory location of mipmaps on non-square texture\n");
|
||||
return obj->baseDataOffset;
|
||||
}
|
||||
|
||||
|
||||
if(obj->isPaletted){
|
||||
switch(size >> level){
|
||||
case 1024:
|
||||
|
@ -200,8 +199,44 @@ static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) {
|
|||
offset = 0x00003;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch(size >> level) {
|
||||
} else if(obj->isCompressed) {
|
||||
switch(size >> level){
|
||||
case 1024:
|
||||
offset = 0x15556;
|
||||
break;
|
||||
case 512:
|
||||
offset = 0x05556;
|
||||
break;
|
||||
case 256:
|
||||
offset = 0x01556;
|
||||
break;
|
||||
case 128:
|
||||
offset = 0x00556;
|
||||
break;
|
||||
case 64:
|
||||
offset = 0x00156;
|
||||
break;
|
||||
case 32:
|
||||
offset = 0x00056;
|
||||
break;
|
||||
case 16:
|
||||
offset = 0x00016;
|
||||
break;
|
||||
case 8:
|
||||
offset = 0x00006;
|
||||
break;
|
||||
case 4:
|
||||
offset = 0x00002;
|
||||
break;
|
||||
case 2:
|
||||
offset = 0x00001;
|
||||
break;
|
||||
case 1:
|
||||
offset = 0x00000;
|
||||
break;
|
||||
}
|
||||
}else {
|
||||
switch(size >> level){
|
||||
case 1024:
|
||||
offset = 0xAAAB0;
|
||||
break;
|
||||
|
@ -241,12 +276,12 @@ static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) {
|
|||
return offset;
|
||||
}
|
||||
|
||||
GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level) {
|
||||
GLubyte* _glGetMipmapLocation(const TextureObject* obj, GLuint level) {
|
||||
return ((GLubyte*) obj->data) + _glGetMipmapDataOffset(obj, level);
|
||||
}
|
||||
|
||||
GLuint _glGetMipmapLevelCount(TextureObject* obj) {
|
||||
return 1 + floor(log2(MAX(obj->width, obj->height)));
|
||||
GLuint _glGetMipmapLevelCount(const TextureObject* obj) {
|
||||
return 1 + floorf(log2f(MAX(obj->width, obj->height)));
|
||||
}
|
||||
|
||||
static GLuint _glGetMipmapDataSize(TextureObject* obj) {
|
||||
|
@ -318,6 +353,7 @@ static void _glInitializeTextureObject(TextureObject* txr, unsigned int id) {
|
|||
txr->palette = NULL;
|
||||
txr->isCompressed = GL_FALSE;
|
||||
txr->isPaletted = GL_FALSE;
|
||||
txr->mipmap_bias = GL_MAX_TEXTURE_LOD_BIAS_DEFAULT;
|
||||
|
||||
/* Not mipmapped by default */
|
||||
txr->baseDataOffset = 0;
|
||||
|
@ -403,18 +439,13 @@ void APIENTRY glBindTexture(GLenum target, GLuint texture) {
|
|||
void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
|
||||
TRACE();
|
||||
|
||||
GLint target_values [] = {GL_TEXTURE_ENV, 0};
|
||||
GLint pname_values [] = {GL_TEXTURE_ENV_MODE, 0};
|
||||
GLint param_values [] = {GL_MODULATE, GL_DECAL, GL_REPLACE, 0};
|
||||
|
||||
GLubyte failures = 0;
|
||||
|
||||
GLint target_values [] = {GL_TEXTURE_ENV, GL_TEXTURE_FILTER_CONTROL_EXT, 0};
|
||||
failures += _glCheckValidEnum(target, target_values, __func__);
|
||||
failures += _glCheckValidEnum(pname, pname_values, __func__);
|
||||
failures += _glCheckValidEnum(param, param_values, __func__);
|
||||
|
||||
TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE];
|
||||
|
||||
|
||||
if(!active) {
|
||||
return;
|
||||
}
|
||||
|
@ -422,19 +453,47 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
|
|||
if(failures) {
|
||||
return;
|
||||
}
|
||||
switch(target){
|
||||
case GL_TEXTURE_ENV:
|
||||
{
|
||||
GLint pname_values [] = {GL_TEXTURE_ENV_MODE, 0};
|
||||
GLint param_values [] = {GL_MODULATE, GL_DECAL, GL_REPLACE, 0};
|
||||
failures += _glCheckValidEnum(pname, pname_values, __func__);
|
||||
failures += _glCheckValidEnum(param, param_values, __func__);
|
||||
|
||||
if(failures) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(param) {
|
||||
case GL_MODULATE:
|
||||
active->env = PVR_TXRENV_MODULATE;
|
||||
break;
|
||||
case GL_DECAL:
|
||||
active->env = PVR_TXRENV_DECAL;
|
||||
break;
|
||||
case GL_REPLACE:
|
||||
active->env = PVR_TXRENV_REPLACE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch(param) {
|
||||
case GL_MODULATE:
|
||||
active->env = PVR_TXRENV_MODULATEALPHA;
|
||||
break;
|
||||
case GL_DECAL:
|
||||
active->env = PVR_TXRENV_DECAL;
|
||||
break;
|
||||
case GL_REPLACE:
|
||||
active->env = PVR_TXRENV_REPLACE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_FILTER_CONTROL_EXT:
|
||||
{
|
||||
GLint pname_values [] = {GL_TEXTURE_LOD_BIAS_EXT, 0};
|
||||
failures += _glCheckValidEnum(pname, pname_values, __func__);
|
||||
failures += (param > GL_MAX_TEXTURE_LOD_BIAS_DEFAULT || param < -GL_MAX_TEXTURE_LOD_BIAS_DEFAULT);
|
||||
if(failures) {
|
||||
return;
|
||||
}
|
||||
active->mipmap_bias = (GL_MAX_TEXTURE_LOD_BIAS_DEFAULT+1)+param; // bring to 1-15 inclusive
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,6 +605,8 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target,
|
|||
|
||||
static GLint _cleanInternalFormat(GLint internalFormat) {
|
||||
switch (internalFormat) {
|
||||
case GL_COLOR_INDEX4_EXT:
|
||||
return GL_COLOR_INDEX4_EXT;
|
||||
case GL_COLOR_INDEX8_EXT:
|
||||
return GL_COLOR_INDEX8_EXT;
|
||||
case GL_ALPHA:
|
||||
|
@ -616,7 +677,7 @@ static GLint _cleanInternalFormat(GLint internalFormat) {
|
|||
}
|
||||
}
|
||||
|
||||
static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) {
|
||||
static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) {
|
||||
/* Given a cleaned internalFormat, return the Dreamcast format
|
||||
* that can hold it
|
||||
*/
|
||||
|
@ -668,6 +729,8 @@ static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) {
|
|||
return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE;
|
||||
case GL_COLOR_INDEX8_EXT:
|
||||
return PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_TWIDDLED;
|
||||
case GL_COLOR_INDEX4_EXT:
|
||||
return PVR_TXRFMT_PAL4BPP | PVR_TXRFMT_TWIDDLED;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -676,11 +739,11 @@ static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) {
|
|||
|
||||
typedef void (*TextureConversionFunc)(const GLubyte*, GLubyte*);
|
||||
|
||||
static inline void _rgba8888_to_argb4444(const GLubyte* source, GLubyte* dest) {
|
||||
GL_FORCE_INLINE void _rgba8888_to_argb4444(const GLubyte* source, GLubyte* dest) {
|
||||
*((GLushort*) dest) = (source[3] & 0xF0) << 8 | (source[0] & 0xF0) << 4 | (source[1] & 0xF0) | (source[2] & 0xF0) >> 4;
|
||||
}
|
||||
|
||||
static inline void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
||||
GL_FORCE_INLINE void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
||||
/* Noop */
|
||||
GLubyte* dst = (GLubyte*) dest;
|
||||
dst[0] = source[0];
|
||||
|
@ -689,11 +752,11 @@ static inline void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
|||
dst[3] = source[3];
|
||||
}
|
||||
|
||||
static inline void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
||||
GL_FORCE_INLINE void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
||||
*((GLushort*) dest) = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3);
|
||||
}
|
||||
|
||||
static inline void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
||||
GL_FORCE_INLINE void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
||||
/* Noop */
|
||||
GLubyte* dst = (GLubyte*) dest;
|
||||
dst[0] = source[0];
|
||||
|
@ -702,24 +765,24 @@ static inline void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
|||
dst[3] = 255;
|
||||
}
|
||||
|
||||
static inline void _rgb888_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
||||
GL_FORCE_INLINE void _rgb888_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
||||
*((GLushort*) dest) = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3);
|
||||
}
|
||||
|
||||
static inline void _rgba8888_to_a000(const GLubyte* source, GLubyte* dest) {
|
||||
GL_FORCE_INLINE void _rgba8888_to_a000(const GLubyte* source, GLubyte* dest) {
|
||||
*((GLushort*) dest) = ((source[3] & 0b11111000) << 8);
|
||||
}
|
||||
|
||||
static inline void _r8_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
||||
GL_FORCE_INLINE void _r8_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
||||
*((GLushort*) dest) = (source[0] & 0b11111000) << 8;
|
||||
}
|
||||
|
||||
static inline void _rgba4444_to_argb4444(const GLubyte* source, GLubyte* dest) {
|
||||
GL_FORCE_INLINE void _rgba4444_to_argb4444(const GLubyte* source, GLubyte* dest) {
|
||||
GLushort* src = (GLushort*) source;
|
||||
*((GLushort*) dest) = ((*src & 0x000F) << 12) | *src >> 4;
|
||||
}
|
||||
|
||||
static inline void _rgba4444_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
||||
GL_FORCE_INLINE void _rgba4444_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
||||
GLushort src = *((GLushort*) source);
|
||||
GLubyte* dst = (GLubyte*) dest;
|
||||
|
||||
|
@ -729,7 +792,7 @@ static inline void _rgba4444_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
|||
dst[3] = ((src & 0x000F)) * 2;
|
||||
}
|
||||
|
||||
static inline void _i8_to_i8(const GLubyte* source, GLubyte* dest) {
|
||||
GL_FORCE_INLINE void _i8_to_i8(const GLubyte* source, GLubyte* dest) {
|
||||
/* For indexes */
|
||||
GLubyte* dst = (GLubyte*) dest;
|
||||
*dst = *source;
|
||||
|
@ -880,72 +943,93 @@ void _glAllocateSpaceForMipmaps(TextureObject* active) {
|
|||
active->baseDataOffset = _glGetMipmapDataOffset(active, 0);
|
||||
}
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
#define INFO_MSG(x) printf("%s %s\n", __FILE__ ":" TOSTRING(__LINE__), x)
|
||||
|
||||
void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border,
|
||||
GLenum format, GLenum type, const GLvoid *data) {
|
||||
|
||||
TRACE();
|
||||
|
||||
|
||||
if(target != GL_TEXTURE_2D) {
|
||||
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D");
|
||||
INFO_MSG("");
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
}
|
||||
|
||||
if(format != GL_COLOR_INDEX) {
|
||||
if(!_isSupportedFormat(format)) {
|
||||
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D");
|
||||
INFO_MSG("");
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
}
|
||||
|
||||
/* Abuse determineStride to see if type is valid */
|
||||
if(_determineStride(GL_RGBA, type) == -1) {
|
||||
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D");
|
||||
INFO_MSG("");
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
}
|
||||
|
||||
internalFormat = _cleanInternalFormat(internalFormat);
|
||||
if(internalFormat == -1) {
|
||||
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
|
||||
INFO_MSG("");
|
||||
_glKosThrowError(GL_INVALID_VALUE, __func__);
|
||||
}
|
||||
} else {
|
||||
if(internalFormat != GL_COLOR_INDEX8_EXT) {
|
||||
INFO_MSG("");
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
GLint w = width;
|
||||
if(w < 8 || (w & -w) != w) {
|
||||
/* Width is not a power of two. Must be!*/
|
||||
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
|
||||
}
|
||||
GLuint w = width;
|
||||
GLuint h = height;
|
||||
if(level == 0){
|
||||
if((w < 8 || (w & -w) != w)) {
|
||||
/* Width is not a power of two. Must be!*/
|
||||
INFO_MSG("");
|
||||
_glKosThrowError(GL_INVALID_VALUE, __func__);
|
||||
}
|
||||
|
||||
GLint h = height;
|
||||
if(h < 8 || (h & -h) != h) {
|
||||
/* height is not a power of two. Must be!*/
|
||||
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
|
||||
|
||||
if((h < 8 || (h & -h) != h)) {
|
||||
/* height is not a power of two. Must be!*/
|
||||
INFO_MSG("");
|
||||
_glKosThrowError(GL_INVALID_VALUE, __func__);
|
||||
}
|
||||
} else {
|
||||
/* Mipmap Errors, kos crashes if 1x1 */
|
||||
if((h < 2) || (w < 2)){
|
||||
assert(TEXTURE_UNITS[ACTIVE_TEXTURE]);
|
||||
TEXTURE_UNITS[ACTIVE_TEXTURE]->mipmap |= (1 << level);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(level < 0) {
|
||||
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
|
||||
INFO_MSG("");
|
||||
_glKosThrowError(GL_INVALID_VALUE, __func__);
|
||||
}
|
||||
|
||||
if(level > 0 && width != height) {
|
||||
INFO_MSG("");
|
||||
fprintf(stderr, "[GL ERROR] Mipmaps cannot be supported on non-square textures\n");
|
||||
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||
}
|
||||
|
||||
if(border) {
|
||||
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
|
||||
INFO_MSG("");
|
||||
_glKosThrowError(GL_INVALID_VALUE, __func__);
|
||||
}
|
||||
|
||||
if(!TEXTURE_UNITS[ACTIVE_TEXTURE]) {
|
||||
INFO_MSG("");
|
||||
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||
}
|
||||
|
||||
GLboolean isPaletted = (internalFormat == GL_COLOR_INDEX8_EXT) ? GL_TRUE : GL_FALSE;
|
||||
|
||||
if(isPaletted && level > 0) {
|
||||
/* Paletted textures can't have mipmaps */
|
||||
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||
}
|
||||
|
||||
if(_glKosHasError()) {
|
||||
_glKosPrintError();
|
||||
return;
|
||||
|
@ -958,7 +1042,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
|
||||
assert(active);
|
||||
|
||||
if(active->data && level == 0) {
|
||||
if(active->data && (level == 0)) {
|
||||
/* pre-existing texture - check if changed */
|
||||
if(active->width != width ||
|
||||
active->height != height ||
|
||||
|
@ -968,6 +1052,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
active->data = NULL;
|
||||
active->mipmap = 0;
|
||||
active->mipmapCount = 0;
|
||||
active->mipmap_bias = GL_KOS_INTERNAL_DEFAULT_MIPMAP_LOD_BIAS;
|
||||
active->dataStride = 0;
|
||||
active->baseDataOffset = 0;
|
||||
active->baseDataSize = 0;
|
||||
|
@ -992,6 +1077,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
active->color = pvr_format;
|
||||
/* Set the required mipmap count */
|
||||
active->mipmapCount = _glGetMipmapLevelCount(active);
|
||||
active->mipmap_bias = GL_KOS_INTERNAL_DEFAULT_MIPMAP_LOD_BIAS;
|
||||
active->dataStride = destStride;
|
||||
active->baseDataSize = bytes;
|
||||
|
||||
|
@ -1336,21 +1422,37 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
|
|||
}
|
||||
|
||||
GLAPI void APIENTRY glColorSubTableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) {
|
||||
_GL_UNUSED(target);
|
||||
_GL_UNUSED(start);
|
||||
_GL_UNUSED(count);
|
||||
_GL_UNUSED(format);
|
||||
_GL_UNUSED(type);
|
||||
_GL_UNUSED(data);
|
||||
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||
_glKosPrintError();
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *data) {
|
||||
_GL_UNUSED(target);
|
||||
_GL_UNUSED(format);
|
||||
_GL_UNUSED(type);
|
||||
_GL_UNUSED(data);
|
||||
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||
_glKosPrintError();
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint *params) {
|
||||
_GL_UNUSED(target);
|
||||
_GL_UNUSED(pname);
|
||||
_GL_UNUSED(params);
|
||||
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||
_glKosPrintError();
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat *params) {
|
||||
_GL_UNUSED(target);
|
||||
_GL_UNUSED(pname);
|
||||
_GL_UNUSED(params);
|
||||
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||
_glKosPrintError();
|
||||
}
|
||||
|
@ -1358,24 +1460,70 @@ GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, G
|
|||
GLAPI void APIENTRY glTexSubImage2D(
|
||||
GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
_GL_UNUSED(target);
|
||||
_GL_UNUSED(level);
|
||||
_GL_UNUSED(xoffset);
|
||||
_GL_UNUSED(yoffset);
|
||||
_GL_UNUSED(width);
|
||||
_GL_UNUSED(height);
|
||||
_GL_UNUSED(format);
|
||||
_GL_UNUSED(type);
|
||||
_GL_UNUSED(pixels);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
|
||||
_GL_UNUSED(target);
|
||||
_GL_UNUSED(level);
|
||||
_GL_UNUSED(xoffset);
|
||||
_GL_UNUSED(yoffset);
|
||||
_GL_UNUSED(x);
|
||||
_GL_UNUSED(y);
|
||||
_GL_UNUSED(width);
|
||||
_GL_UNUSED(height);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {
|
||||
|
||||
_GL_UNUSED(target);
|
||||
_GL_UNUSED(level);
|
||||
_GL_UNUSED(xoffset);
|
||||
_GL_UNUSED(x);
|
||||
_GL_UNUSED(y);
|
||||
_GL_UNUSED(width);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
|
||||
|
||||
_GL_UNUSED(target);
|
||||
_GL_UNUSED(level);
|
||||
_GL_UNUSED(internalformat);
|
||||
_GL_UNUSED(x);
|
||||
_GL_UNUSED(y);
|
||||
_GL_UNUSED(width);
|
||||
_GL_UNUSED(height);
|
||||
_GL_UNUSED(border);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) {
|
||||
|
||||
_GL_UNUSED(target);
|
||||
_GL_UNUSED(level);
|
||||
_GL_UNUSED(internalformat);
|
||||
_GL_UNUSED(x);
|
||||
_GL_UNUSED(y);
|
||||
_GL_UNUSED(width);
|
||||
_GL_UNUSED(border);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
||||
GLAPI void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
|
||||
|
||||
_GL_UNUSED(x);
|
||||
_GL_UNUSED(y);
|
||||
_GL_UNUSED(width);
|
||||
_GL_UNUSED(height);
|
||||
_GL_UNUSED(format);
|
||||
_GL_UNUSED(type);
|
||||
_GL_UNUSED(pixels);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ static inline void* memalign(size_t alignment, size_t size) {
|
|||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "../GL/private.h"
|
||||
#include "aligned_vector.h"
|
||||
|
||||
void aligned_vector_init(AlignedVector* vector, unsigned int element_size) {
|
||||
|
@ -24,7 +25,6 @@ void aligned_vector_init(AlignedVector* vector, unsigned int element_size) {
|
|||
aligned_vector_reserve(vector, ALIGNED_VECTOR_CHUNK_SIZE);
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned int round_to_chunk_size(unsigned int val) {
|
||||
const unsigned int n = val;
|
||||
const unsigned int m = ALIGNED_VECTOR_CHUNK_SIZE;
|
||||
|
@ -32,7 +32,6 @@ static inline unsigned int round_to_chunk_size(unsigned int val) {
|
|||
return ((n + m - 1) / m) * m;
|
||||
}
|
||||
|
||||
|
||||
void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count) {
|
||||
if(element_count == 0) {
|
||||
return;
|
||||
|
@ -54,7 +53,7 @@ void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count) {
|
|||
assert(vector->data);
|
||||
|
||||
if(original_data) {
|
||||
memcpy(vector->data, original_data, original_byte_size);
|
||||
FASTCPY(vector->data, original_data, original_byte_size);
|
||||
free(original_data);
|
||||
}
|
||||
|
||||
|
@ -74,7 +73,7 @@ void* aligned_vector_push_back(AlignedVector* vector, const void* objs, unsigned
|
|||
unsigned char* dest = vector->data + (vector->element_size * initial_size);
|
||||
|
||||
/* Copy the objects in */
|
||||
memcpy(dest, objs, vector->element_size * count);
|
||||
FASTCPY(dest, objs, vector->element_size * count);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
@ -101,25 +100,12 @@ void* aligned_vector_resize(AlignedVector* vector, const unsigned int element_co
|
|||
}
|
||||
}
|
||||
|
||||
void* aligned_vector_at(const AlignedVector* vector, const unsigned int index) {
|
||||
assert(index < vector->size);
|
||||
return &vector->data[index * vector->element_size];
|
||||
}
|
||||
|
||||
void* aligned_vector_back(AlignedVector* vector) {
|
||||
return aligned_vector_at(vector, vector->size - 1);
|
||||
}
|
||||
|
||||
void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count) {
|
||||
const unsigned int current = vector->size;
|
||||
aligned_vector_resize(vector, vector->size + additional_count);
|
||||
return aligned_vector_at(vector, current);
|
||||
}
|
||||
|
||||
void aligned_vector_clear(AlignedVector* vector) {
|
||||
vector->size = 0;
|
||||
}
|
||||
|
||||
void aligned_vector_shrink_to_fit(AlignedVector* vector) {
|
||||
if(vector->size == 0) {
|
||||
free(vector->data);
|
||||
|
@ -131,7 +117,7 @@ void aligned_vector_shrink_to_fit(AlignedVector* vector) {
|
|||
vector->data = (unsigned char*) memalign(0x20, new_byte_size);
|
||||
|
||||
if(original_data) {
|
||||
memcpy(vector->data, original_data, new_byte_size);
|
||||
FASTCPY(vector->data, original_data, new_byte_size);
|
||||
free(original_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef ALIGNED_VECTOR_H
|
||||
#define ALIGNED_VECTOR_H
|
||||
|
||||
|
@ -5,6 +7,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned int size;
|
||||
unsigned int capacity;
|
||||
|
@ -18,12 +22,19 @@ void aligned_vector_init(AlignedVector* vector, unsigned int element_size);
|
|||
void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count);
|
||||
void* aligned_vector_push_back(AlignedVector* vector, const void* objs, unsigned int count);
|
||||
void* aligned_vector_resize(AlignedVector* vector, const unsigned int element_count);
|
||||
void* aligned_vector_at(const AlignedVector* vector, const unsigned int index);
|
||||
static inline void* aligned_vector_at(const AlignedVector* vector, const unsigned int index) {
|
||||
assert(index < vector->size);
|
||||
return &vector->data[index * vector->element_size];
|
||||
}
|
||||
void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count);
|
||||
void aligned_vector_clear(AlignedVector* vector);
|
||||
static inline void aligned_vector_clear(AlignedVector* vector){
|
||||
vector->size = 0;
|
||||
}
|
||||
void aligned_vector_shrink_to_fit(AlignedVector* vector);
|
||||
void aligned_vector_cleanup(AlignedVector* vector);
|
||||
void* aligned_vector_back(AlignedVector* vector);
|
||||
static inline void* aligned_vector_back(AlignedVector* vector){
|
||||
return aligned_vector_at(vector, vector->size - 1);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
@ -16,8 +17,7 @@ void named_array_init(NamedArray* array, unsigned int element_size, unsigned int
|
|||
array->element_size = element_size;
|
||||
array->max_element_count = max_elements;
|
||||
|
||||
float c = (float) max_elements / 8.0f;
|
||||
array->marker_count = (unsigned char) ceil(c);
|
||||
array->marker_count = (unsigned char)((max_elements+8-1)/8);
|
||||
|
||||
#ifdef _arch_dreamcast
|
||||
// Use 32-bit aligned memory on the Dreamcast
|
||||
|
@ -30,17 +30,6 @@ void named_array_init(NamedArray* array, unsigned int element_size, unsigned int
|
|||
memset(array->used_markers, 0, sizeof(unsigned char) * array->marker_count);
|
||||
}
|
||||
|
||||
char named_array_used(NamedArray* array, unsigned int id) {
|
||||
unsigned int i = id / 8;
|
||||
unsigned int j = id % 8;
|
||||
|
||||
assert(i < array->max_element_count);
|
||||
assert(array->used_markers);
|
||||
|
||||
unsigned char v = array->used_markers[i] & (unsigned char) (1 << j);
|
||||
return !!(v);
|
||||
}
|
||||
|
||||
void* named_array_alloc(NamedArray* array, unsigned int* new_id) {
|
||||
unsigned int i = 0, j = 0;
|
||||
for(i = 0; i < array->marker_count; ++i) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef NAMED_ARRAY_H
|
||||
#define NAMED_ARRAY_H
|
||||
|
||||
|
@ -5,6 +7,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../GL/private.h"
|
||||
|
||||
typedef struct {
|
||||
unsigned int element_size;
|
||||
unsigned int max_element_count;
|
||||
|
@ -14,7 +18,13 @@ typedef struct {
|
|||
} NamedArray;
|
||||
|
||||
void named_array_init(NamedArray* array, unsigned int element_size, unsigned int max_elements);
|
||||
char named_array_used(NamedArray* array, unsigned int id);
|
||||
static inline char named_array_used(NamedArray* array, unsigned int id) {
|
||||
const unsigned int i = id / 8;
|
||||
const unsigned int j = id % 8;
|
||||
|
||||
unsigned char v = array->used_markers[i] & (unsigned char) (1 << j);
|
||||
return !!(v);
|
||||
}
|
||||
|
||||
void* named_array_alloc(NamedArray* array, unsigned int* new_id);
|
||||
void* named_array_reserve(NamedArray* array, unsigned int id);
|
||||
|
|
22
include/gl.h
22
include/gl.h
|
@ -362,6 +362,27 @@ __BEGIN_DECLS
|
|||
#define GL_RGBA12 0x805A
|
||||
#define GL_RGBA16 0x805B
|
||||
|
||||
/* Polygons */
|
||||
#define GL_POINT 0x1B00
|
||||
#define GL_LINE 0x1B01
|
||||
#define GL_FILL 0x1B02
|
||||
#define GL_CW 0x0900
|
||||
#define GL_CCW 0x0901
|
||||
#define GL_FRONT 0x0404
|
||||
#define GL_BACK 0x0405
|
||||
#define GL_POLYGON_MODE 0x0B40
|
||||
#define GL_POLYGON_SMOOTH 0x0B41
|
||||
#define GL_POLYGON_STIPPLE 0x0B42
|
||||
#define GL_EDGE_FLAG 0x0B43
|
||||
#define GL_CULL_FACE 0x0B44
|
||||
#define GL_CULL_FACE_MODE 0x0B45
|
||||
#define GL_FRONT_FACE 0x0B46
|
||||
#define GL_POLYGON_OFFSET_FACTOR 0x8038
|
||||
#define GL_POLYGON_OFFSET_UNITS 0x2A00
|
||||
#define GL_POLYGON_OFFSET_POINT 0x2A01
|
||||
#define GL_POLYGON_OFFSET_LINE 0x2A02
|
||||
#define GL_POLYGON_OFFSET_FILL 0x8037
|
||||
|
||||
#define GLbyte char
|
||||
#define GLshort short
|
||||
#define GLint int
|
||||
|
@ -471,6 +492,7 @@ GLAPI void APIENTRY glClearDepthf(GLfloat depth);
|
|||
GLAPI void APIENTRY glDepthMask(GLboolean flag);
|
||||
GLAPI void APIENTRY glDepthFunc(GLenum func);
|
||||
GLAPI void APIENTRY glDepthRange(GLclampf n, GLclampf f);
|
||||
GLAPI void APIENTRY glDepthRangef(GLclampf n, GLclampf f);
|
||||
|
||||
/* Hints */
|
||||
/* Currently Supported Capabilities:
|
||||
|
|
|
@ -190,6 +190,21 @@ GLAPI void APIENTRY glCompressedTexImage2DARB(GLenum target,
|
|||
#define glGenerateMipmap glGenerateMipmapEXT
|
||||
#define glCompressedTexImage2D glCompressedTexImage2DARB
|
||||
|
||||
#ifndef GL_VERSION_1_4
|
||||
#define GL_VERSION_1_4 1
|
||||
#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
|
||||
#define GL_TEXTURE_LOD_BIAS 0x8501
|
||||
#define GL_MAX_TEXTURE_LOD_BIAS_DEFAULT 7
|
||||
#define GL_KOS_INTERNAL_DEFAULT_MIPMAP_LOD_BIAS -4
|
||||
#endif
|
||||
|
||||
#ifndef GL_EXT_texture_lod_bias
|
||||
#define GL_EXT_texture_lod_bias 1
|
||||
#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
|
||||
#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
|
||||
#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
|
||||
#endif /* GL_EXT_texture_lod_bias */
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !__GL_GLEXT_H */
|
||||
|
|
Loading…
Reference in New Issue
Block a user