diff --git a/examples/simple_tri/source/main.c b/examples/simple_tri/source/main.c index 872ed68..7cc6b2c 100644 --- a/examples/simple_tri/source/main.c +++ b/examples/simple_tri/source/main.c @@ -43,6 +43,10 @@ static void sceneInit(void) C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); AttrInfo_Init(attrInfo); AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // v0=position + AttrInfo_AddFixed(attrInfo, 1); // v1=color + + // Set the fixed attribute (color) to solid white + C3D_FixedAttribSet(1, 1.0, 1.0, 1.0, 1.0); // Compute the projection matrix Mtx_OrthoTilt(&projection, 0.0, 400.0, 0.0, 240.0, 0.0, 1.0); diff --git a/examples/simple_tri/source/vshader.v.pica b/examples/simple_tri/source/vshader.v.pica index 8b14900..ca9498c 100644 --- a/examples/simple_tri/source/vshader.v.pica +++ b/examples/simple_tri/source/vshader.v.pica @@ -15,6 +15,7 @@ ; Inputs (defined as aliases for convenience) .alias inpos v0 +.alias inclr v1 .bool test @@ -29,8 +30,8 @@ dp4 outpos.z, projection[2], r0 dp4 outpos.w, projection[3], r0 - ; outclr = solid white color - mov outclr, ones + ; outclr = inclr + mov outclr, inclr ; We're finished end diff --git a/include/c3d/base.h b/include/c3d/base.h index d679137..3ecf728 100644 --- a/include/c3d/base.h +++ b/include/c3d/base.h @@ -36,3 +36,15 @@ static inline void C3D_Flush(void) C3D_FlushAsync(); C3D_FlushAwait(); } + +// Fixed vertex attributes +C3D_FVec* C3D_FixedAttribGetWritePtr(int id); + +static inline void C3D_FixedAttribSet(int id, float x, float y, float z, float w) +{ + C3D_FVec* ptr = C3D_FixedAttribGetWritePtr(id); + ptr->x = x; + ptr->y = y; + ptr->z = z; + ptr->w = w; +} diff --git a/source/base.c b/source/base.c index a93c1a2..40fa8db 100644 --- a/source/base.c +++ b/source/base.c @@ -55,6 +55,8 @@ static void C3Di_AptEventHook(APT_HookType hookType, void* param) C3Di_DirtyUniforms(GPU_VERTEX_SHADER); C3Di_DirtyUniforms(GPU_GEOMETRY_SHADER); + ctx->fixedAttribDirty |= ctx->fixedAttribEverDirty; + C3D_LightEnv* env = ctx->lightEnv; if (env) env->Dirty(env); @@ -98,6 +100,9 @@ bool C3D_Init(size_t cmdBufSize) for (i = 0; i < 6; i ++) TexEnv_Init(&ctx->texEnv[i]); + ctx->fixedAttribDirty = 0; + ctx->fixedAttribEverDirty = 0; + aptHook(&hookCookie, C3Di_AptEventHook, NULL); return true; @@ -230,6 +235,19 @@ void C3Di_UpdateContext(void) if (env) env->Update(env); + if (ctx->fixedAttribDirty) + { + for (i = 0; i < 12; i ++) + { + if (!(ctx->fixedAttribDirty & BIT(i))) continue; + C3D_FVec* v = &ctx->fixedAttribs[i]; + + GPUCMD_AddWrite(GPUREG_FIXEDATTRIB_INDEX, i); + C3D_ImmSendAttrib(v->x, v->y, v->z, v->w); + } + ctx->fixedAttribDirty = 0; + } + C3D_UpdateUniforms(GPU_VERTEX_SHADER); C3D_UpdateUniforms(GPU_GEOMETRY_SHADER); } @@ -297,3 +315,18 @@ void C3D_BindProgram(shaderProgram_s* program) else C3Di_ClearShaderUniforms(GPU_GEOMETRY_SHADER); } + +C3D_FVec* C3D_FixedAttribGetWritePtr(int id) +{ + if (id < 0 || id >= 12) + return NULL; + + C3D_Context* ctx = C3Di_GetContext(); + + if (!(ctx->flags & C3DiF_Active)) + return NULL; + + ctx->fixedAttribDirty |= BIT(id); + ctx->fixedAttribEverDirty |= BIT(id); + return &ctx->fixedAttribs[id]; +} diff --git a/source/context.h b/source/context.h index b886443..903b43c 100644 --- a/source/context.h +++ b/source/context.h @@ -44,6 +44,9 @@ typedef struct u32 viewport[5]; u32 scissor[3]; + u16 fixedAttribDirty, fixedAttribEverDirty; + C3D_FVec fixedAttribs[12]; + } C3D_Context; enum