Untested multitexture implementation

This commit is contained in:
Luke Benstead 2018-08-04 21:00:26 +01:00
parent db0d39d487
commit 6942e597f4
6 changed files with 101 additions and 9 deletions

View File

@ -138,6 +138,9 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
interpolateVec2(v1->uv, v2->uv, t1, output[1].uv);
interpolateVec2(v1->uv, v3->uv, t2, output[2].uv);
interpolateVec2(v1->st, v2->st, t1, output[1].st);
interpolateVec2(v1->st, v3->st, t2, output[2].st);
interpolateVec4(v1->diffuse, v2->diffuse, t1, output[1].diffuse);
interpolateVec4(v1->diffuse, v3->diffuse, t2, output[2].diffuse);
@ -169,6 +172,9 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
interpolateVec2(v2->uv, v1->uv, t1, output[0].uv);
interpolateVec2(v2->uv, v3->uv, t2, output[2].uv);
interpolateVec2(v2->st, v1->st, t1, output[0].st);
interpolateVec2(v2->st, v3->st, t2, output[2].st);
interpolateVec4(v2->diffuse, v1->diffuse, t1, output[0].diffuse);
interpolateVec4(v2->diffuse, v3->diffuse, t2, output[2].diffuse);
@ -200,6 +206,9 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
interpolateVec2(v3->uv, v1->uv, t1, output[0].uv);
interpolateVec2(v3->uv, v2->uv, t2, output[1].uv);
interpolateVec2(v3->st, v1->st, t1, output[0].st);
interpolateVec2(v3->st, v2->st, t2, output[1].st);
interpolateVec4(v3->diffuse, v1->diffuse, t1, output[0].diffuse);
interpolateVec4(v3->diffuse, v2->diffuse, t2, output[1].diffuse);
@ -232,6 +241,9 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
interpolateVec2(v2->uv, v3->uv, t1, output[2].uv);
interpolateVec2(v1->uv, v3->uv, t2, output[3].uv);
interpolateVec2(v2->st, v3->st, t1, output[2].st);
interpolateVec2(v1->st, v3->st, t2, output[3].st);
interpolateVec4(v2->diffuse, v3->diffuse, t1, output[2].diffuse);
interpolateVec4(v1->diffuse, v3->diffuse, t2, output[3].diffuse);
@ -264,6 +276,9 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
interpolateVec2(v1->uv, v2->uv, t1, output[0].uv);
interpolateVec2(v1->uv, v3->uv, t2, output[2].uv);
interpolateVec2(v1->st, v2->st, t1, output[0].st);
interpolateVec2(v1->st, v3->st, t2, output[2].st);
interpolateVec4(v1->diffuse, v2->diffuse, t1, output[0].diffuse);
interpolateVec4(v1->diffuse, v3->diffuse, t2, output[2].diffuse);
@ -296,6 +311,9 @@ void clipTriangleStrip(AlignedVector* vertices, AlignedVector* outBuffer) {
interpolateVec2(v1->uv, v2->uv, t1, output[1].uv);
interpolateVec2(v3->uv, v2->uv, t2, output[3].uv);
interpolateVec2(v1->st, v2->st, t1, output[1].st);
interpolateVec2(v3->st, v2->st, t2, output[3].st);
interpolateVec4(v1->diffuse, v2->diffuse, t1, output[1].diffuse);
interpolateVec4(v3->diffuse, v2->diffuse, t2, output[3].diffuse);

View File

@ -28,15 +28,13 @@ typedef struct {
float uv[2];
uint32_t argb;
float nxyz[3];
float nxyz[3]; /* Normal */
float w;
float xyzES[3]; /* Coordinate 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];
float st[2]; /* 8-bytes makes this 96 bytes in total */
} ClipVertex;
void clipLineToNearZ(const ClipVertex* v1, const ClipVertex* v2, ClipVertex* vout, float* t);

View File

@ -196,7 +196,8 @@ static void swapVertex(ClipVertex* v1, ClipVertex* v2) {
static void generate(AlignedVector* output, const GLenum mode, const GLsizei first, const GLsizei count,
const GLubyte* indices, const GLenum type,
const GLubyte* vptr, const GLubyte vstride, const GLubyte* cptr, const GLubyte cstride,
const GLubyte* uvptr, const GLubyte uvstride, const GLubyte* nptr, const GLubyte nstride) {
const GLubyte* uvptr, const GLubyte uvstride, const GLubyte* stptr, const GLubyte ststride,
const GLubyte* nptr, const GLubyte nstride) {
/* Read from the client buffers and generate an array of ClipVertices */
GLsizei max = first + count;
@ -233,6 +234,12 @@ static void generate(AlignedVector* output, const GLenum mode, const GLsizei fir
vertex->uv[0] = vertex->uv[1] = 0.0f;
}
if(ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) {
_parseFloats(vertex->st, stptr + (idx * ststride), ST_POINTER.size, ST_POINTER.type);
} else {
vertex->st[0] = vertex->st[1] = 0.0f;
}
if(ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) {
_parseFloats(vertex->nxyz, nptr + (idx * nstride), NORMAL_POINTER.size, NORMAL_POINTER.type);
} else {
@ -428,7 +435,7 @@ typedef struct {
#define MAX_LISTS 5
static void push(const AlignedVector* vertices, PolyList* activePolyList) {
static void push(const AlignedVector* vertices, PolyList* activePolyList, TextureObject* textureObject) {
/* Copy the vertices to the active poly list */
static GLuint LIST_COUNTER = 0;
@ -448,7 +455,7 @@ static void push(const AlignedVector* vertices, PolyList* activePolyList) {
pvr_poly_cxt_t cxt = *getPVRContext();
cxt.list_type = activePolyList->list_type;
updatePVRTextureContext(&cxt, getTexture0());
updatePVRTextureContext(&cxt, textureObject);
pvr_poly_compile(hdr, &cxt);
@ -539,10 +546,19 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
GLubyte uvstride = (UV_POINTER.stride) ? UV_POINTER.stride : UV_POINTER.size * byte_size(UV_POINTER.type);
const GLubyte* uvptr = UV_POINTER.ptr;
GLubyte ststride = (ST_POINTER.stride) ? ST_POINTER.stride : ST_POINTER.size * byte_size(ST_POINTER.type);
const GLubyte* stptr = ST_POINTER.ptr;
GLubyte nstride = (NORMAL_POINTER.stride) ? NORMAL_POINTER.stride : NORMAL_POINTER.size * byte_size(NORMAL_POINTER.type);
const GLubyte* nptr = NORMAL_POINTER.ptr;
generate(buffer, mode, first, count, (GLubyte*) indices, type, vptr, vstride, cptr, cstride, uvptr, uvstride, nptr, nstride);
generate(
buffer, mode, first, count, (GLubyte*) indices, type,
vptr, vstride, cptr, cstride,
uvptr, uvstride, stptr, ststride,
nptr, nstride
);
light(buffer);
transform(buffer);
@ -551,7 +567,53 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
}
divide(buffer);
push(buffer, activePolyList());
push(buffer, activePolyList(), getTexture0());
/*
Now, if multitexturing is enabled, we want to send exactly the same vertices again, except:
- We want to enable blending, and send them to the TR list
- We want to set the depth func to GL_EQUAL
- We want to set the second texture ID
- We want to set the uv coordinates to the passed st ones
*/
TextureObject* texture1 = getTexture1();
if(!texture1 || ((ENABLED_VERTEX_ATTRIBUTES & ST_ENABLED_FLAG) != ST_ENABLED_FLAG)) {
/* Multitexture disabled */
return;
}
ClipVertex* vertex = (ClipVertex*) aligned_vector_at(buffer, 0);
/* Copy ST coordinates to UV ones */
GLsizei i = 0;
for(; i < buffer->size; ++i, ++vertex) {
vertex->uv[0] = vertex->st[0];
vertex->uv[1] = vertex->st[1];
}
/* Store state, as we're about to mess around with it */
GLint depthFunc, blendSrc, blendDst;
glGetIntegerv(GL_DEPTH_FUNC, &depthFunc);
glGetIntegerv(GL_BLEND_SRC, &blendSrc);
glGetIntegerv(GL_BLEND_DST, &blendDst);
GLboolean blendEnabled = glIsEnabled(GL_BLEND);
GLboolean depthEnabled = glIsEnabled(GL_DEPTH_TEST);
glDepthFunc(GL_EQUAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* Send the buffer again to the transparent list */
push(buffer, transparentPolyList(), texture1);
/* Reset state */
glDepthFunc(depthFunc);
glBlendFunc(blendSrc, blendDst);
(blendEnabled) ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
(depthEnabled) ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
}
void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {

View File

@ -58,6 +58,10 @@ PolyList* activePolyList() {
}
}
PolyList *transparentPolyList() {
return &TR_LIST;
}
void APIENTRY glKosInit() {
TRACE();

View File

@ -64,6 +64,7 @@ typedef struct {
PolyList *activePolyList();
PolyList *transparentPolyList();
void initAttributePointers();
void initContext();

View File

@ -425,6 +425,15 @@ void APIENTRY glGetIntegerv(GLenum pname, GLint *params) {
case GL_TEXTURE_BINDING_2D:
*params = getBoundTexture()->index;
break;
case GL_DEPTH_FUNC:
*params = DEPTH_FUNC;
break;
case GL_BLEND_SRC:
*params = BLEND_SFACTOR;
break;
case GL_BLEND_DST:
*params = BLEND_DFACTOR;
break;
default:
_glKosThrowError(GL_INVALID_ENUM, "glGetIntegerv");
_glKosPrintError();