Simplify colour handling
This commit is contained in:
parent
bebca59796
commit
39ac10af00
48
GL/clip.c
48
GL/clip.c
|
@ -50,24 +50,12 @@ static void interpolateVec3(const float* v1, const float* v2, const float t, flo
|
||||||
out[2] = v1[2] + (v2[2] - v1[2]) * t;
|
out[2] = v1[2] + (v2[2] - v1[2]) * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void interpolateColour(const uint32_t* c1, const uint32_t* c2, const float t, uint32_t* out) {
|
static void interpolateVec4(const float* v1, const float* v2, const float t, float* out) {
|
||||||
float r1 = (*c1 >> 16) & 0xFF;
|
/* FIXME: SH4 has an asm instruction for this */
|
||||||
float r2 = (*c2 >> 16) & 0xFF;
|
out[0] = v1[0] + (v2[0] - v1[0]) * t;
|
||||||
uint8_t r = (r1 + (r2 - r1) * t);
|
out[1] = v1[1] + (v2[1] - v1[1]) * t;
|
||||||
|
out[2] = v1[2] + (v2[2] - v1[2]) * t;
|
||||||
r1 = (*c1 >> 24) & 0xFF;
|
out[3] = v1[3] + (v2[3] - v1[3]) * t;
|
||||||
r2 = (*c2 >> 24) & 0xFF;
|
|
||||||
uint8_t a = (r1 + (r2 - r1) * t);
|
|
||||||
|
|
||||||
r1 = (*c1 >> 8) & 0xFF;
|
|
||||||
r2 = (*c2 >> 8) & 0xFF;
|
|
||||||
uint8_t g = (r1 + (r2 - r1) * t);
|
|
||||||
|
|
||||||
r1 = (*c1 >> 0) & 0xFF;
|
|
||||||
r2 = (*c2 >> 0) & 0xFF;
|
|
||||||
uint8_t b = (r1 + (r2 - r1) * t);
|
|
||||||
|
|
||||||
*out = (a << 24 | r << 16 | g << 8 | b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t VERTEX_CMD_EOL = 0xf0000000;
|
const uint32_t VERTEX_CMD_EOL = 0xf0000000;
|
||||||
|
@ -147,8 +135,8 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
|
||||||
interpolateVec2(v1->uv, v2->uv, t1, output[1].uv);
|
interpolateVec2(v1->uv, v2->uv, t1, output[1].uv);
|
||||||
interpolateVec2(v1->uv, v3->uv, t2, output[2].uv);
|
interpolateVec2(v1->uv, v3->uv, t2, output[2].uv);
|
||||||
|
|
||||||
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v2->argb, t1, (uint32_t*) &output[1].argb);
|
interpolateVec4(v1->diffuse, v2->diffuse, t1, output[1].diffuse);
|
||||||
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v3->argb, t2, (uint32_t*) &output[2].argb);
|
interpolateVec4(v1->diffuse, v3->diffuse, t2, output[2].diffuse);
|
||||||
|
|
||||||
output[0].flags = VERTEX_CMD;
|
output[0].flags = VERTEX_CMD;
|
||||||
output[1].flags = VERTEX_CMD;
|
output[1].flags = VERTEX_CMD;
|
||||||
|
@ -178,8 +166,8 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
|
||||||
interpolateVec2(v2->uv, v1->uv, t1, output[0].uv);
|
interpolateVec2(v2->uv, v1->uv, t1, output[0].uv);
|
||||||
interpolateVec2(v2->uv, v3->uv, t2, output[2].uv);
|
interpolateVec2(v2->uv, v3->uv, t2, output[2].uv);
|
||||||
|
|
||||||
interpolateColour((uint32_t*) &v2->argb, (uint32_t*) &v1->argb, t1, (uint32_t*) &output[0].argb);
|
interpolateVec4(v2->diffuse, v1->diffuse, t1, output[0].diffuse);
|
||||||
interpolateColour((uint32_t*) &v2->argb, (uint32_t*) &v3->argb, t2, (uint32_t*) &output[2].argb);
|
interpolateVec4(v2->diffuse, v3->diffuse, t2, output[2].diffuse);
|
||||||
|
|
||||||
output[0].flags = VERTEX_CMD;
|
output[0].flags = VERTEX_CMD;
|
||||||
output[1].flags = VERTEX_CMD;
|
output[1].flags = VERTEX_CMD;
|
||||||
|
@ -209,8 +197,8 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
|
||||||
interpolateVec2(v3->uv, v1->uv, t1, output[0].uv);
|
interpolateVec2(v3->uv, v1->uv, t1, output[0].uv);
|
||||||
interpolateVec2(v3->uv, v2->uv, t2, output[1].uv);
|
interpolateVec2(v3->uv, v2->uv, t2, output[1].uv);
|
||||||
|
|
||||||
interpolateColour((uint32_t*) &v3->argb, (uint32_t*) &v1->argb, t1, (uint32_t*) &output[0].argb);
|
interpolateVec4(v3->diffuse, v1->diffuse, t1, output[0].diffuse);
|
||||||
interpolateColour((uint32_t*) &v3->argb, (uint32_t*) &v2->argb, t2, (uint32_t*) &output[1].argb);
|
interpolateVec4(v3->diffuse, v2->diffuse, t2, output[1].diffuse);
|
||||||
|
|
||||||
output[0].flags = VERTEX_CMD;
|
output[0].flags = VERTEX_CMD;
|
||||||
output[1].flags = VERTEX_CMD;
|
output[1].flags = VERTEX_CMD;
|
||||||
|
@ -241,8 +229,8 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
|
||||||
interpolateVec2(v2->uv, v3->uv, t1, output[2].uv);
|
interpolateVec2(v2->uv, v3->uv, t1, output[2].uv);
|
||||||
interpolateVec2(v1->uv, v3->uv, t2, output[3].uv);
|
interpolateVec2(v1->uv, v3->uv, t2, output[3].uv);
|
||||||
|
|
||||||
interpolateColour((uint32_t*) &v2->argb, (uint32_t*) &v3->argb, t1, (uint32_t*) &output[2].argb);
|
interpolateVec4(v2->diffuse, v3->diffuse, t1, output[2].diffuse);
|
||||||
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v3->argb, t2, (uint32_t*) &output[3].argb);
|
interpolateVec4(v1->diffuse, v3->diffuse, t2, output[3].diffuse);
|
||||||
|
|
||||||
output[0].flags = VERTEX_CMD;
|
output[0].flags = VERTEX_CMD;
|
||||||
output[1].flags = VERTEX_CMD;
|
output[1].flags = VERTEX_CMD;
|
||||||
|
@ -273,8 +261,8 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
|
||||||
interpolateVec2(v1->uv, v2->uv, t1, output[0].uv);
|
interpolateVec2(v1->uv, v2->uv, t1, output[0].uv);
|
||||||
interpolateVec2(v1->uv, v3->uv, t2, output[2].uv);
|
interpolateVec2(v1->uv, v3->uv, t2, output[2].uv);
|
||||||
|
|
||||||
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v2->argb, t1, (uint32_t*) &output[0].argb);
|
interpolateVec4(v1->diffuse, v2->diffuse, t1, output[0].diffuse);
|
||||||
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v3->argb, t2, (uint32_t*) &output[2].argb);
|
interpolateVec4(v1->diffuse, v3->diffuse, t2, output[2].diffuse);
|
||||||
|
|
||||||
output[0].flags = VERTEX_CMD;
|
output[0].flags = VERTEX_CMD;
|
||||||
output[1].flags = VERTEX_CMD;
|
output[1].flags = VERTEX_CMD;
|
||||||
|
@ -305,8 +293,8 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
|
||||||
interpolateVec2(v1->uv, v2->uv, t1, output[1].uv);
|
interpolateVec2(v1->uv, v2->uv, t1, output[1].uv);
|
||||||
interpolateVec2(v3->uv, v2->uv, t2, output[3].uv);
|
interpolateVec2(v3->uv, v2->uv, t2, output[3].uv);
|
||||||
|
|
||||||
interpolateColour((uint32_t*) &v1->argb, (uint32_t*) &v2->argb, t1, (uint32_t*) &output[1].argb);
|
interpolateVec4(v1->diffuse, v2->diffuse, t1, output[1].diffuse);
|
||||||
interpolateColour((uint32_t*) &v3->argb, (uint32_t*) &v2->argb, t2, (uint32_t*) &output[3].argb);
|
interpolateVec4(v3->diffuse, v2->diffuse, t2, output[3].diffuse);
|
||||||
|
|
||||||
output[0].flags = VERTEX_CMD;
|
output[0].flags = VERTEX_CMD;
|
||||||
output[1].flags = VERTEX_CMD;
|
output[1].flags = VERTEX_CMD;
|
||||||
|
|
18
GL/clip.h
18
GL/clip.h
|
@ -17,26 +17,26 @@ typedef enum {
|
||||||
CLIP_RESULT_BACK_TO_FRONT
|
CLIP_RESULT_BACK_TO_FRONT
|
||||||
} ClipResult;
|
} ClipResult;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t a;
|
|
||||||
uint8_t r;
|
|
||||||
uint8_t g;
|
|
||||||
uint8_t b;
|
|
||||||
} ClipColour;
|
|
||||||
|
|
||||||
/* Note: This structure is the almost the same format as pvr_vertex_t aside from the offet
|
/* Note: This structure is the almost the same format as pvr_vertex_t aside from the offet
|
||||||
* (oargb) which is replaced by the floating point w value. This is so that we can
|
* (oargb) which is replaced by the floating point w value. This is so that we can
|
||||||
* simply zero it and memcpy the lot into the output */
|
* simply zero it and memcpy the lot into the output. This struct is 96 bytes to keep
|
||||||
|
* 32 byte alignment */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
float xyz[3];
|
float xyz[3];
|
||||||
float uv[2];
|
float uv[2];
|
||||||
ClipColour argb;
|
uint32_t argb;
|
||||||
|
|
||||||
float nxyz[3];
|
float nxyz[3];
|
||||||
float w;
|
float w;
|
||||||
|
|
||||||
float xyzES[3]; /* Coordinate in eye space */
|
float xyzES[3]; /* Coordinate in eye space */
|
||||||
float nES[3]; /* Normal in eye space */
|
float nES[3]; /* Normal in eye space */
|
||||||
|
|
||||||
|
float diffuse[4]; /* Colour in floating point */
|
||||||
|
|
||||||
|
/* Keep things 32 byte aligned */
|
||||||
|
unsigned char padding[8];
|
||||||
} ClipVertex;
|
} ClipVertex;
|
||||||
|
|
||||||
void clipLineToNearZ(const ClipVertex* v1, const ClipVertex* v2, ClipVertex* vout, float* t);
|
void clipLineToNearZ(const ClipVertex* v1, const ClipVertex* v2, ClipVertex* vout, float* t);
|
||||||
|
|
52
GL/draw.c
52
GL/draw.c
|
@ -73,11 +73,16 @@ static GLuint byte_size(GLenum type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _parseColour(uint32* out, const GLubyte* in, GLint size, GLenum type) {
|
static void _parseColour(float* out, const GLubyte* in, GLint size, GLenum type) {
|
||||||
|
const float ONE_OVER_255 = 1.0f / 255.0f;
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case GL_BYTE: {
|
case GL_BYTE: {
|
||||||
case GL_UNSIGNED_BYTE:
|
case GL_UNSIGNED_BYTE:
|
||||||
*out = in[3] << 24 | in[0] << 16 | in[1] << 8 | in[0];
|
out[0] = ((GLfloat)in[0]) * ONE_OVER_255;
|
||||||
|
out[1] = ((GLfloat)in[1]) * ONE_OVER_255;
|
||||||
|
out[2] = ((GLfloat)in[2]) * ONE_OVER_255;
|
||||||
|
out[3] = ((GLfloat)in[3]) * ONE_OVER_255;
|
||||||
} break;
|
} break;
|
||||||
case GL_SHORT:
|
case GL_SHORT:
|
||||||
case GL_UNSIGNED_SHORT:
|
case GL_UNSIGNED_SHORT:
|
||||||
|
@ -90,8 +95,10 @@ static void _parseColour(uint32* out, const GLubyte* in, GLint size, GLenum type
|
||||||
case GL_FLOAT:
|
case GL_FLOAT:
|
||||||
case GL_DOUBLE:
|
case GL_DOUBLE:
|
||||||
default: {
|
default: {
|
||||||
const GLfloat* src = (GLfloat*) in;
|
out[0] = ((GLfloat*) in)[0];
|
||||||
*out = PVR_PACK_COLOR(src[3], src[0], src[1], src[2]);
|
out[1] = ((GLfloat*) in)[1];
|
||||||
|
out[2] = ((GLfloat*) in)[2];
|
||||||
|
out[3] = ((GLfloat*) in)[3];
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,10 +221,10 @@ static void generate(AlignedVector* output, const GLenum mode, const GLsizei fir
|
||||||
_parseFloats(vertex->xyz, vptr + (idx * vstride), VERTEX_POINTER.size, VERTEX_POINTER.type);
|
_parseFloats(vertex->xyz, vptr + (idx * vstride), VERTEX_POINTER.size, VERTEX_POINTER.type);
|
||||||
|
|
||||||
if(ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) {
|
if(ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) {
|
||||||
_parseColour((uint32_t*) &vertex->argb, cptr + (idx * cstride), DIFFUSE_POINTER.size, DIFFUSE_POINTER.type);
|
_parseColour(vertex->diffuse, cptr + (idx * cstride), DIFFUSE_POINTER.size, DIFFUSE_POINTER.type);
|
||||||
} else {
|
} else {
|
||||||
/* Default to white if colours are disabled */
|
/* Default to white if colours are disabled */
|
||||||
*((uint32_t*) &vertex->argb) = ~0;
|
vertex->diffuse[0] = vertex->diffuse[1] = vertex->diffuse[2] = vertex->diffuse[3] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG) {
|
if(ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG) {
|
||||||
|
@ -383,7 +390,8 @@ static void light(AlignedVector* vertices) {
|
||||||
for(i = 0; i < vertices->size; ++i, ++vertex) {
|
for(i = 0; i < vertices->size; ++i, ++vertex) {
|
||||||
/* We ignore diffuse colour when lighting is enabled. If GL_COLOR_MATERIAL is enabled
|
/* We ignore diffuse colour when lighting is enabled. If GL_COLOR_MATERIAL is enabled
|
||||||
* then the lighting calculation should possibly take it into account */
|
* then the lighting calculation should possibly take it into account */
|
||||||
GLfloat contribution [] = {0.0f, 0.0f, 0.0f, 0.0f};
|
memset(vertex->diffuse, 0, sizeof(float) * 4);
|
||||||
|
|
||||||
GLfloat to_add [] = {0.0f, 0.0f, 0.0f, 0.0f};
|
GLfloat to_add [] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
GLubyte j;
|
GLubyte j;
|
||||||
|
@ -391,15 +399,12 @@ static void light(AlignedVector* vertices) {
|
||||||
if(isLightEnabled(j)) {
|
if(isLightEnabled(j)) {
|
||||||
calculateLightingContribution(j, vertex->xyzES, vertex->nES, to_add);
|
calculateLightingContribution(j, vertex->xyzES, vertex->nES, to_add);
|
||||||
|
|
||||||
contribution[0] += to_add[0];
|
vertex->diffuse[0] += to_add[0];
|
||||||
contribution[1] += to_add[1];
|
vertex->diffuse[1] += to_add[1];
|
||||||
contribution[2] += to_add[2];
|
vertex->diffuse[2] += to_add[2];
|
||||||
contribution[3] += to_add[3];
|
vertex->diffuse[3] += to_add[3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t final = PVR_PACK_COLOR(contribution[3], contribution[0], contribution[1], contribution[2]);
|
|
||||||
vertex->argb = *((ClipColour*) &final);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,14 +441,20 @@ static void push(const AlignedVector* vertices, PolyList* activePolyList) {
|
||||||
pvr_poly_compile(hdr, &cxt);
|
pvr_poly_compile(hdr, &cxt);
|
||||||
|
|
||||||
GLsizei i;
|
GLsizei i;
|
||||||
|
ClipVertex* vin = aligned_vector_at(vertices, 0);
|
||||||
|
|
||||||
for(i = 0; i < vertices->size; ++i, dst++) {
|
for(i = 0; i < vertices->size; ++i, dst++) {
|
||||||
pvr_vertex_t* vout = (pvr_vertex_t*) dst;
|
pvr_vertex_t* vout = (pvr_vertex_t*) dst;
|
||||||
|
vout->flags = vin->flags;
|
||||||
/* The first part of ClipVertex is the same as the first part of pvr_vertex_t */
|
vout->x = vin->xyz[0];
|
||||||
memcpy(vout, aligned_vector_at(vertices, i), sizeof(pvr_vertex_t));
|
vout->y = vin->xyz[1];
|
||||||
|
vout->z = vin->xyz[2];
|
||||||
/* Except for this bit */
|
vout->u = vin->uv[0];
|
||||||
|
vout->v = vin->uv[1];
|
||||||
|
vout->argb = PVR_PACK_COLOR(vin->diffuse[3], vin->diffuse[0], vin->diffuse[1], vin->diffuse[2]);
|
||||||
vout->oargb = 0;
|
vout->oargb = 0;
|
||||||
|
|
||||||
|
vin++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,6 +470,9 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
|
||||||
if(!buffer) {
|
if(!buffer) {
|
||||||
buffer = (AlignedVector*) malloc(sizeof(AlignedVector));
|
buffer = (AlignedVector*) malloc(sizeof(AlignedVector));
|
||||||
aligned_vector_init(buffer, sizeof(ClipVertex));
|
aligned_vector_init(buffer, sizeof(ClipVertex));
|
||||||
|
|
||||||
|
/* Reserve 64k up-front */
|
||||||
|
aligned_vector_reserve(buffer, 64 * 1024);
|
||||||
} else {
|
} else {
|
||||||
/* Else, resize to zero (this will retain the allocated memory) */
|
/* Else, resize to zero (this will retain the allocated memory) */
|
||||||
aligned_vector_resize(buffer, 0);
|
aligned_vector_resize(buffer, 0);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user