From 6942e597f4f2f8983d463b6358a069e2d0bfcb82 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 4 Aug 2018 21:00:26 +0100 Subject: [PATCH] Untested multitexture implementation --- GL/clip.c | 18 +++++++++++++ GL/clip.h | 6 ++--- GL/draw.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++---- GL/flush.c | 4 +++ GL/private.h | 1 + GL/state.c | 9 +++++++ 6 files changed, 101 insertions(+), 9 deletions(-) diff --git a/GL/clip.c b/GL/clip.c index b89bad4..426966b 100644 --- a/GL/clip.c +++ b/GL/clip.c @@ -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); diff --git a/GL/clip.h b/GL/clip.h index d2f5c63..4a8a216 100644 --- a/GL/clip.h +++ b/GL/clip.h @@ -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); diff --git a/GL/draw.c b/GL/draw.c index 2935407..9becdbf 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -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) { diff --git a/GL/flush.c b/GL/flush.c index 6352b9d..bb8f3b1 100644 --- a/GL/flush.c +++ b/GL/flush.c @@ -58,6 +58,10 @@ PolyList* activePolyList() { } } +PolyList *transparentPolyList() { + return &TR_LIST; +} + void APIENTRY glKosInit() { TRACE(); diff --git a/GL/private.h b/GL/private.h index 6ef39b1..1bb7a7d 100644 --- a/GL/private.h +++ b/GL/private.h @@ -64,6 +64,7 @@ typedef struct { PolyList *activePolyList(); +PolyList *transparentPolyList(); void initAttributePointers(); void initContext(); diff --git a/GL/state.c b/GL/state.c index e99723c..e57e1e0 100644 --- a/GL/state.c +++ b/GL/state.c @@ -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();