diff --git a/src/arrays.cpp b/src/arrays.cpp index f792f5f..36a0fc5 100644 --- a/src/arrays.cpp +++ b/src/arrays.cpp @@ -143,6 +143,8 @@ struct VertexReaderBase { format.attribute <= GX_VA_TEX7) { /* Texture coordinates must be enable sequentially */ format.attribute = GX_VA_TEX0 + s_num_tex_arrays++; + /* And GX does not support more than two coordinates */ + if (format.num_components > 2) format.num_components = 2; } GX_SetVtxDesc(format.attribute, GX_DIRECT); GX_SetVtxAttrFmt(GX_VTXFMT0, format.attribute, @@ -180,6 +182,11 @@ struct DirectVboReader: public VertexReaderBase { } void setup_draw() override { + if (format.attribute >= GX_VA_TEX0 && + format.attribute <= GX_VA_TEX7) { + /* Texture coordinates must be enable sequentially */ + format.attribute = GX_VA_TEX0 + s_num_tex_arrays++; + } GX_SetArray(format.attribute, const_cast(data), stride); GX_SetVtxDesc(format.attribute, GX_INDEX16); GX_SetVtxAttrFmt(GX_VTXFMT0, format.attribute, @@ -327,21 +334,21 @@ struct CoordVertexReader: public GenericVertexReader { using GenericVertexReader::GenericVertexReader; void process_element(int index) { - float x, y, z; const T *ptr = elemAt(index); - x = *ptr++; - y = *ptr++; - if (format.num_components >= 3) { + if (format.num_components == 4) { + float x, y, z, w; + x = *ptr++; + y = *ptr++; z = *ptr++; - if (format.num_components == 4) { - float w = *ptr++; - x /= w; - y /= w; - z /= w; - } + w = *ptr++; + x /= w; + y /= w; + z /= w; GX_Position3f32(x, y, z); } else { - GX_Position2f32(x, y); + for (int i = 0; i < format.num_components; i++, ptr++) { + wgPipe->F32 = float(*ptr++); + } } } }; diff --git a/src/gc_gl.c b/src/gc_gl.c index cf59080..22c36bd 100644 --- a/src/gc_gl.c +++ b/src/gc_gl.c @@ -999,6 +999,7 @@ void glPopMatrix(void) } memcpy(glparamstate.projection_matrix, glparamstate.projection_stack[glparamstate.cur_proj_mat], sizeof(Mtx44)); glparamstate.cur_proj_mat--; + break; case 1: if (glparamstate.cur_modv_mat < 0) { set_error(GL_STACK_UNDERFLOW); @@ -1006,6 +1007,7 @@ void glPopMatrix(void) } memcpy(glparamstate.modelview_matrix, glparamstate.modelview_stack[glparamstate.cur_modv_mat], sizeof(Mtx)); glparamstate.cur_modv_mat--; + break; case 2: { OgxTextureUnit *tu = active_tex_unit(); @@ -1049,6 +1051,8 @@ void glPushMatrix(void) set_error(GL_STACK_OVERFLOW); return; } + memcpy(tu->matrix[tu->matrix_index + 1], + tu->matrix[tu->matrix_index], sizeof(Mtx)); tu->matrix_index++; } default: @@ -1208,6 +1212,7 @@ void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) Mtx *target = NULL; Mtx44 rot; guVector axis = { x, y, z }; + if (angle == 0.0f || (x == 0.0f && y == 0.0f && z == 0.0f)) return; guMtxRotAxisDeg(rot, &axis, angle); switch (glparamstate.matrixmode) { @@ -1546,7 +1551,10 @@ void glDisableClientState(GLenum cap) glparamstate.cs.normal_enabled = 0; break; case GL_TEXTURE_COORD_ARRAY: - glparamstate.cs.texcoord_enabled = 0; + { + int unit = glparamstate.cs.active_texture; + glparamstate.cs.texcoord_enabled &= ~(1 << unit); + } break; case GL_VERTEX_ARRAY: glparamstate.cs.vertex_enabled = 0; @@ -1570,7 +1578,10 @@ void glEnableClientState(GLenum cap) glparamstate.cs.normal_enabled = 1; break; case GL_TEXTURE_COORD_ARRAY: - glparamstate.cs.texcoord_enabled = 1; + { + int unit = glparamstate.cs.active_texture; + glparamstate.cs.texcoord_enabled |= (1 << unit); + } break; case GL_VERTEX_ARRAY: glparamstate.cs.vertex_enabled = 1; @@ -2030,10 +2041,18 @@ static void setup_fog() bool _ogx_setup_render_stages() { + u8 raster_output, raster_reg_index; + if (glparamstate.texture_enabled) { + raster_reg_index = _ogx_gpu_resources->tevreg_first++; + raster_output = GX_TEVREG0 + raster_reg_index; + } else { + raster_output = GX_TEVPREV; + } + if (glparamstate.lighting.enabled) { LightMasks light_mask = prepare_lighting(); - GXColor color_zero = { 0, 0, 0, 0 }; + GXColor color_black = { 0, 0, 0, 255 }; GXColor color_gamb = gxcol_new_fv(glparamstate.lighting.globalambient); _ogx_gpu_resources->tevstage_first += 2; @@ -2101,14 +2120,17 @@ bool _ogx_setup_render_stages() light_mask.ambient_mask | light_mask.specular_mask , GX_DF_NONE, GX_AF_SPEC); GX_SetChanAmbColor(GX_COLOR0A0, color_gamb); - // Color1 channel: Multiplies the light raster result with the vertex color. Ambient is set to register (which is zero) + // Color1 channel: Multiplies the light raster result with the vertex color. Ambient is set to register (which is black) GX_SetChanCtrl(GX_COLOR1A1, GX_TRUE, GX_SRC_REG, vert_color_src, light_mask.diffuse_mask, GX_DF_CLAMP, GX_AF_SPOT); - GX_SetChanAmbColor(GX_COLOR1A1, color_zero); + GX_SetChanAmbColor(GX_COLOR1A1, color_black); // STAGE 0: ambient*vert_color -> cprev // In data: d: Raster Color, a: emission color - GX_SetTevColor(GX_TEVPREV, ecol); - GX_SetTevColorIn(GX_TEVSTAGE0, GX_CC_CPREV, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC); + u8 emission_reg = _ogx_gpu_resources->tevreg_first++; + GX_SetTevColor(GX_TEVREG0 + emission_reg, ecol); + /* Multiply by two because there are alpha registers in between */ + GX_SetTevColorIn(GX_TEVSTAGE0, GX_CC_C0 + emission_reg * 2, + GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC); GX_SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA); // Operation: Pass d GX_SetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); @@ -2119,16 +2141,16 @@ bool _ogx_setup_render_stages() // STAGE 1: diffuse*vert_color + cprev -> cprev // In data: d: Raster Color a: CPREV GX_SetTevColorIn(GX_TEVSTAGE1, GX_CC_CPREV, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC); - GX_SetTevAlphaIn(GX_TEVSTAGE1, GX_CA_APREV, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA); + GX_SetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_APREV, GX_CA_RASA, GX_CA_ZERO); // Operation: Sum a + d - GX_SetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); - GX_SetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GX_SetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, raster_output); + GX_SetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, raster_output); // Select COLOR1A1 for the rasterizer, disable all textures GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORDNULL, GX_TEXMAP_DISABLE, GX_COLOR1A1); if (glparamstate.texture_enabled) { - // Do not select any raster value, Texture 0 for texture rasterizer and TEXCOORD0 slot for tex coordinates - _ogx_setup_texture_stages(GX_CC_CPREV, GX_CA_APREV, GX_COLORNULL); + // Do not select any raster color channel + _ogx_setup_texture_stages(raster_reg_index, GX_COLORNULL); } } else { // Unlit scene @@ -2153,7 +2175,7 @@ bool _ogx_setup_render_stages() if (glparamstate.texture_enabled) { // Select COLOR0A0 for the rasterizer, Texture 0 for texture rasterizer and TEXCOORD0 slot for tex coordinates - _ogx_setup_texture_stages(GX_CC_RASC, GX_CA_RASA, GX_COLOR0A0); + _ogx_setup_texture_stages(raster_reg_index, GX_COLOR0A0); } else { // Use one stage only _ogx_gpu_resources->tevstage_first += 1; diff --git a/src/getters.c b/src/getters.c index 3fd33db..badf662 100644 --- a/src/getters.c +++ b/src/getters.c @@ -58,7 +58,7 @@ const GLubyte *glGetString(GLenum name) return "1.1"; case GL_EXTENSIONS: return - "GL_ARB_multitexture" + "GL_ARB_multitexture " "GL_ARB_vertex_buffer_object "; default: set_error(GL_INVALID_ENUM); @@ -204,6 +204,7 @@ void glGetIntegerv(GLenum pname, GLint *params) return; case GL_MAX_TEXTURE_COORDS: case GL_MAX_TEXTURE_IMAGE_UNITS: + case GL_MAX_TEXTURE_UNITS: *params = MAX_TEXTURE_UNITS; break; case GL_MAX_TEXTURE_SIZE: diff --git a/src/gpu_resources.c b/src/gpu_resources.c index 683377b..45393b5 100644 --- a/src/gpu_resources.c +++ b/src/gpu_resources.c @@ -52,6 +52,9 @@ static void resources_init(OgxGpuResources *resources) resources->kcolor_first = 0; resources->kcolor_end = GX_KCOLOR_MAX; + resources->tevreg_first = 0; + resources->tevreg_end = GX_MAX_TEVREG - 1; /* we exclude GX_TEVPREV */ + resources->texcoord_first = 0; resources->texcoord_end = GX_MAXCOORD; diff --git a/src/gpu_resources.h b/src/gpu_resources.h index 6bceba6..ef7a065 100644 --- a/src/gpu_resources.h +++ b/src/gpu_resources.h @@ -57,6 +57,8 @@ typedef struct { uint8_t tevstage_end; uint8_t kcolor_first; uint8_t kcolor_end; + uint8_t tevreg_first; + uint8_t tevreg_end; uint8_t texcoord_first; uint8_t texcoord_end; uint8_t pnmtx_first; diff --git a/src/pixel_stream.h b/src/pixel_stream.h index e393c72..3c0e484 100644 --- a/src/pixel_stream.h +++ b/src/pixel_stream.h @@ -79,6 +79,9 @@ struct PixelStreamBase { virtual void write(GXColor color) = 0; virtual void setup() {} + void *operator new(size_t size) { return malloc(size); } + void operator delete(void * p) { free(p); } + protected: void *m_data; int m_width; diff --git a/src/stencil.c b/src/stencil.c index 16614ea..e5e7f62 100644 --- a/src/stencil.c +++ b/src/stencil.c @@ -451,11 +451,14 @@ static bool draw_op(uint16_t op, glparamstate.dirty.bits.dirty_color_update = 1; u8 stage = GX_TEVSTAGE0 + _ogx_gpu_resources->tevstage_first++; - GX_SetTevColor(GX_TEVPREV, drawColor); + u8 tevreg_index = _ogx_gpu_resources->tevreg_first++; + GX_SetTevColor(GX_TEVREG0 + tevreg_index, drawColor); GX_SetTevOrder(stage, GX_TEXCOORDNULL, GX_TEXMAP_DISABLE, GX_COLOR0A0); /* Pass the constant color */ - GX_SetTevColorIn(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_CPREV); - GX_SetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GX_SetTevColorIn(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, + GX_CC_C0 + tevreg_index * 2); + GX_SetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, + GX_CA_A0 + tevreg_index); GX_SetTevColorOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GX_SetTevAlphaOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, diff --git a/src/texel.h b/src/texel.h index 91b11c2..8637b74 100644 --- a/src/texel.h +++ b/src/texel.h @@ -72,6 +72,9 @@ struct Texel { } } + void *operator new(size_t size) { return malloc(size); } + void operator delete(void * p) { free(p); } + void *m_data; int m_x; int m_y; diff --git a/src/texture.c b/src/texture.c index 8993943..f0906b1 100644 --- a/src/texture.c +++ b/src/texture.c @@ -58,7 +58,9 @@ typedef union { (TEXTURE_USER_DATA(&texture.texobj).d.is_reserved) #define TEXTURE_RESERVE(texture) \ { \ - UserData ud = TEXTURE_USER_DATA(&(texture).texobj); \ + GX_InitTexObj(&(texture).texobj, NULL, 0, 0, 0, \ + GX_REPEAT, GX_REPEAT, 0); \ + UserData ud = { .ptr = NULL }; \ ud.d.is_reserved = 1; \ GX_InitTexObjUserData(&(texture).texobj, ud.ptr); \ } @@ -122,6 +124,8 @@ static unsigned char gcgl_texwrap_conv(GLint param) case GL_MIRRORED_REPEAT: return GX_MIRROR; case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + case GL_CLAMP_TO_BORDER: return GX_CLAMP; case GL_REPEAT: default: @@ -430,7 +434,6 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt ti.maxlevel = level; ti.width = wi; ti.height = he; - ti.wraps = ti.wrapt = GX_REPEAT; } if (ti.maxlevel < level) ti.maxlevel = level; @@ -523,7 +526,7 @@ void glDeleteTextures(GLsizei n, const GLuint *textures) GX_DrawDone(); while (n-- > 0) { int i = *texlist++; - if (!(i < 0 || i >= _MAX_GL_TEX)) { + if (i > 0 && i < _MAX_GL_TEX) { void *data = GX_GetTexObjData(&texture_list[i].texobj); if (data != 0) free(MEM_PHYSICAL_TO_K0(data)); @@ -538,8 +541,6 @@ void glGenTextures(GLsizei n, GLuint *textures) int i; for (i = 0; i < _MAX_GL_TEX && n > 0; i++) { if (!TEXTURE_IS_RESERVED(texture_list[i])) { - GXTexObj *texobj = &texture_list[i].texobj; - GX_InitTexObj(texobj, NULL, 0, 0, 0, GX_REPEAT, GX_REPEAT, 0); TEXTURE_RESERVE(texture_list[i]); *texlist++ = i; n--; diff --git a/src/texture_unit.c b/src/texture_unit.c index 18a8d5f..58ce64e 100644 --- a/src/texture_unit.c +++ b/src/texture_unit.c @@ -77,7 +77,9 @@ typedef struct { "source" */ } TevSource; -static TevSource gl_rgbsource_to_gx(GLenum source, GLenum operand) +static TevSource gl_rgbsource_to_gx(GLenum source, GLenum operand, + u8 prev_rgb, u8 prev_alpha, + u8 raster_rgb, u8 raster_alpha) { TevSource ret = { GX_CC_ZERO, false }; if (operand == GL_ONE_MINUS_SRC_COLOR) { @@ -97,22 +99,23 @@ static TevSource gl_rgbsource_to_gx(GLenum source, GLenum operand) break; case GL_PREVIOUS: switch (operand) { - case GL_SRC_COLOR: ret.source = GX_CC_CPREV; break; - case GL_SRC_ALPHA: ret.source = GX_CC_APREV; break; + case GL_SRC_COLOR: ret.source = prev_rgb; break; + case GL_SRC_ALPHA: ret.source = prev_alpha; break; } break; case GL_CONSTANT: ret.source = GX_CC_KONST; break; case GL_PRIMARY_COLOR: switch (operand) { - case GL_SRC_COLOR: ret.source = GX_CC_RASC; break; - case GL_SRC_ALPHA: ret.source = GX_CC_RASA; break; + case GL_SRC_COLOR: ret.source = raster_rgb; break; + case GL_SRC_ALPHA: ret.source = raster_alpha; break; } break; } return ret; } -static TevSource gl_alphasource_to_gx(GLenum source, GLenum operand) +static TevSource gl_alphasource_to_gx(GLenum source, GLenum operand, + u8 prev_alpha, u8 raster_alpha) { TevSource ret = { GX_CA_ZERO, false }; /* For the alpha channel, operand can only be either GL_SRC_ALPHA or @@ -123,9 +126,9 @@ static TevSource gl_alphasource_to_gx(GLenum source, GLenum operand) switch (source) { case GL_TEXTURE: ret.source = GX_CA_TEXA; break; - case GL_PREVIOUS: ret.source = GX_CA_APREV; break; + case GL_PREVIOUS: ret.source = prev_alpha; break; case GL_CONSTANT: ret.source = GX_CA_KONST; break; - case GL_PRIMARY_COLOR: ret.source = GX_CA_RASA; break; + case GL_PRIMARY_COLOR: ret.source = raster_alpha; break; } return ret; } @@ -148,9 +151,12 @@ static TevInput compute_tev_input(GLenum combine_func, u8 stage, GXColor color, B = 1, C = 2, D = 3, + NUM_TEV_REGS, }; int used_args = 0; + const int CA_ONE = 0xa1; /* sentinel value, we won't actually store this in + the TEV registers */ u8 zero_value, one_value, konst_value; if (is_alpha) { zero_value = GX_CA_ZERO; @@ -160,7 +166,7 @@ static TevInput compute_tev_input(GLenum combine_func, u8 stage, GXColor color, * careful, because this if one of the arg{0,1,2} is set to a constant, * we'll need to solve the conflict somehow (we can use only one * constant value per TEV stage). */ - one_value = GX_CA_KONST; + one_value = CA_ONE; konst_value = GX_CA_KONST; } else { zero_value = GX_CC_ZERO; @@ -296,12 +302,12 @@ static TevInput compute_tev_input(GLenum combine_func, u8 stage, GXColor color, } int used_constants = 0; + bool needs_constant_one = false; if (is_alpha) { - bool needs_constant_one = false; - for (int i = 0; i < used_args; i++) { - if (args[i].source == one_value) { + for (int i = 0; i < NUM_TEV_REGS; i++) { + if (reg[i] == one_value) { needs_constant_one = true; - break; + reg[i] = GX_CA_KONST; } } if (needs_constant_one) { @@ -320,7 +326,7 @@ static TevInput compute_tev_input(GLenum combine_func, u8 stage, GXColor color, /* We could support this by using more stages. TODO */ } /* TODO: dynamically allocate constant register! */ - if (is_alpha) { + if (is_alpha && !needs_constant_one) { GX_SetTevKAlphaSel(stage, GX_TEV_KASEL_K0_A); } else { GX_SetTevKColorSel(stage, GX_TEV_KCSEL_K0); @@ -334,17 +340,21 @@ static TevInput compute_tev_input(GLenum combine_func, u8 stage, GXColor color, return ret; } -static void setup_combine_operation(const OgxTextureUnit *te, - u8 stage) +static void setup_combine_operation(const OgxTextureUnit *te, u8 stage, + u8 prev_rgb, u8 prev_alpha, + u8 raster_rgb, u8 raster_alpha) { TevSource source_rgb[3]; TevSource source_alpha[3]; for (int i = 0; i < 3; i++) { source_rgb[i] = gl_rgbsource_to_gx(te->source_rgb[i], - te->operand_rgb[i]); + te->operand_rgb[i], + prev_rgb, prev_alpha, + raster_rgb, raster_alpha); source_alpha[i] = gl_alphasource_to_gx(te->source_alpha[i], - te->operand_alpha[i]); + te->operand_alpha[i], + prev_alpha, raster_alpha); } TevInput rgb = compute_tev_input(te->combine_rgb, stage, te->color, @@ -363,7 +373,8 @@ static void setup_combine_operation(const OgxTextureUnit *te, static void setup_texture_stage(const OgxTextureUnit *tu, u8 stage, u8 tex_coord, u8 tex_map, - u8 raster_color, u8 raster_alpha, + u8 prev_rgb, u8 prev_alpha, + u8 raster_rgb, u8 raster_alpha, u8 channel) { switch (tu->mode) { @@ -373,26 +384,28 @@ static void setup_texture_stage(const OgxTextureUnit *tu, GX_SetTevAlphaIn(stage, GX_CA_TEXA, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); break; case GL_ADD: - // In data: d: Texture Color a: raster value, Operation: a+d - GX_SetTevColorIn(stage, raster_color, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); - GX_SetTevAlphaIn(stage, raster_alpha, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + /* In data: d: Texture Color a: raster value, Operation: a+d + * Alpha gets multiplied. */ + GX_SetTevColorIn(stage, prev_rgb, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + GX_SetTevAlphaIn(stage, GX_CA_ZERO, prev_alpha, GX_CA_TEXA, GX_CA_ZERO); break; case GL_BLEND: /* In data: c: Texture Color, a: raster value, b: tex env * Operation: a(1-c)+b*c * Until we implement GL_TEXTURE_ENV_COLOR, use white (GX_CC_ONE) for * the tex env color. */ - GX_SetTevColorIn(stage, raster_color, GX_CC_ONE, GX_CC_TEXC, GX_CC_ZERO); - GX_SetTevAlphaIn(stage, GX_CA_ZERO, raster_alpha, GX_CA_TEXA, GX_CA_ZERO); + GX_SetTevColorIn(stage, prev_rgb, GX_CC_ONE, GX_CC_TEXC, GX_CC_ZERO); + GX_SetTevAlphaIn(stage, GX_CA_ZERO, prev_alpha, GX_CA_TEXA, GX_CA_ZERO); break; case GL_COMBINE: - setup_combine_operation(tu, stage); + setup_combine_operation(tu, stage, prev_rgb, prev_alpha, + raster_rgb, raster_alpha); break; case GL_MODULATE: default: // In data: c: Texture Color b: raster value, Operation: b*c - GX_SetTevColorIn(stage, GX_CC_ZERO, raster_color, GX_CC_TEXC, GX_CC_ZERO); - GX_SetTevAlphaIn(stage, GX_CA_ZERO, raster_alpha, GX_CA_TEXA, GX_CA_ZERO); + GX_SetTevColorIn(stage, GX_CC_ZERO, prev_rgb, GX_CC_TEXC, GX_CC_ZERO); + GX_SetTevAlphaIn(stage, GX_CA_ZERO, prev_alpha, GX_CA_TEXA, GX_CA_ZERO); break; } if (!tu->mode != GL_COMBINE) { @@ -420,9 +433,20 @@ static void setup_texture_stage_matrix(const OgxTextureUnit *tu, GX_LoadTexMtxImm(m, dtt_matrix, GX_MTX3x4); } -void _ogx_setup_texture_stages(u8 raster_color, u8 raster_alpha, - u8 channel) +void _ogx_setup_texture_stages(u8 raster_reg_index, u8 channel) { + u8 raster_rgb, raster_alpha; + if (channel != GX_COLORNULL) { + raster_rgb = GX_CC_RASC; + raster_alpha = GX_CA_RASA; + } else { + raster_rgb = GX_CC_C0 + raster_reg_index * 2; + raster_alpha = GX_CA_A0 + raster_reg_index; + } + + u8 prev_rgb = raster_rgb; + u8 prev_alpha = raster_alpha; + /* This variable holds the number of enabled texture units for which the * client provided texture coordinates (not generated, but literally a * GX_VA_TEX* array was specified). */ @@ -449,7 +473,8 @@ void _ogx_setup_texture_stages(u8 raster_color, u8 raster_alpha, u8 dtt_matrix = GX_DTTMTX0 + _ogx_gpu_resources->dttmtx_first++ * 3; setup_texture_stage(tu, stage, tex_coord, tex_map, - raster_color, raster_alpha, channel); + prev_rgb, prev_alpha, + raster_rgb, raster_alpha, channel); setup_texture_stage_matrix(tu, dtt_matrix); if (tu->gen_enabled) { @@ -461,7 +486,7 @@ void _ogx_setup_texture_stages(u8 raster_color, u8 raster_alpha, /* All texture stages after the first one get their vertex color from * the previous stage */ - raster_color = GX_CC_CPREV; - raster_alpha = GX_CA_APREV; + prev_rgb = GX_CC_CPREV; + prev_alpha = GX_CA_APREV; } } diff --git a/src/texture_unit.h b/src/texture_unit.h index 58fd677..c0063c2 100644 --- a/src/texture_unit.h +++ b/src/texture_unit.h @@ -36,8 +36,7 @@ POSSIBILITY OF SUCH DAMAGE. extern "C" { #endif -void _ogx_setup_texture_stages(u8 raster_color, u8 raster_alpha, - u8 channel); +void _ogx_setup_texture_stages(u8 raster_reg_index, u8 channel); #ifdef __cplusplus } // extern C