### Complete Citro3D Rendering Example Source: https://context7.com/devkitpro/citro3d/llms.txt A full example demonstrating citro3d initialization, scene setup, and rendering loop with textures and transformations. This includes system initialization, render target creation, shader loading, vertex buffer setup, texture handling, and the main rendering loop. ```c #include <3ds.h> #include #include #define CLEAR_COLOR 0x68B0D8FF #define DISPLAY_TRANSFER_FLAGS \ (GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | \ GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \ GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)) typedef struct { float position[3]; float texcoord[2]; float normal[3]; } Vertex; static DVLB_s* vshader_dvlb; static shaderProgram_s program; static int uLoc_projection, uLoc_modelView; static C3D_Mtx projection, modelView; static void* vbo_data; static C3D_Tex texture; int main() { // Initialize systems gfxInitDefault(); C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); // Create render target C3D_RenderTarget* target = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTargetClear(target, C3D_CLEAR_ALL, CLEAR_COLOR, 0); C3D_RenderTargetSetOutput(target, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); // Load and bind shader vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size); shaderProgramInit(&program); shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]); C3D_BindProgram(&program); // Get uniform locations uLoc_projection = shaderInstanceGetUniformLocation(program.vertexShader, "projection"); uLoc_modelView = shaderInstanceGetUniformLocation(program.vertexShader, "modelView"); // Configure vertex attributes C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); AttrInfo_Init(attrInfo); AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // position AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2); // texcoord AttrInfo_AddLoader(attrInfo, 2, GPU_FLOAT, 3); // normal // Create VBO with cube vertices Vertex vertices[] = { /* ... cube vertex data ... */ }; vbo_data = linearAlloc(sizeof(vertices)); memcpy(vbo_data, vertices, sizeof(vertices)); C3D_BufInfo* bufInfo = C3D_GetBufInfo(); BufInfo_Init(bufInfo); BufInfo_Add(bufInfo, vbo_data, sizeof(Vertex), 3, 0x210); // Load texture C3D_TexInit(&texture, 64, 64, GPU_RGBA8); C3D_TexUpload(&texture, textureData); C3D_TexSetFilter(&texture, GPU_LINEAR, GPU_NEAREST); C3D_TexBind(0, &texture); // Configure texture environment C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvInit(env); C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); // Setup projection Mtx_PerspTilt(&projection, C3D_AngleFromDegrees(60.0f), C3D_AspectRatioTop, 0.1f, 100.0f, false); // Configure depth test C3D_DepthTest(true, GPU_GREATER, GPU_WRITE_ALL); float angle = 0.0f; // Main loop while (aptMainLoop()) { hidScanInput(); if (hidKeysDown() & KEY_START) break; // Update model-view matrix Mtx_Identity(&modelView); Mtx_Translate(&modelView, 0.0f, 0.0f, -3.0f, true); Mtx_RotateY(&modelView, C3D_Angle(angle), true); angle += 0.01f; // Upload uniforms C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projection); C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_modelView, &modelView); // Render C3D_FrameBegin(C3D_FRAME_SYNCDRAW); C3D_FrameDrawOn(target); C3D_DrawArrays(GPU_TRIANGLES, 0, 36); // 6 faces * 2 triangles * 3 vertices C3D_FrameEnd(0); } // Cleanup C3D_TexDelete(&texture); linearFree(vbo_data); shaderProgramFree(&program); DVLB_Free(vshader_dvlb); C3D_RenderTargetDelete(target); C3D_Fini(); gfxExit(); return 0; } ``` -------------------------------- ### Begin Immediate Mode Drawing Source: https://context7.com/devkitpro/citro3d/llms.txt Use C3D_ImmDrawBegin to start immediate mode drawing. This is suitable for simple or dynamic geometry without pre-allocated buffers. Ensure to call C3D_ImmDrawEnd when finished. ```c #include // Begin immediate mode drawing C3D_ImmDrawBegin(GPU_TRIANGLES); // Submit vertices (x, y, z, w) C3D_ImmSendAttrib(0.0f, 1.0f, 0.0f, 1.0f); // Top vertex C3D_ImmSendAttrib(-1.0f, -1.0f, 0.0f, 1.0f); // Bottom-left C3D_ImmSendAttrib(1.0f, -1.0f, 0.0f, 1.0f); // Bottom-right // For triangle strips, restart primitive C3D_ImmDrawRestartPrim(); // End immediate mode C3D_ImmDrawEnd(); ``` -------------------------------- ### Initialize and Cleanup Citro3D Source: https://context7.com/devkitpro/citro3d/llms.txt Initializes the citro3d library with a default command buffer size and cleans up resources. Use C3D_Init to start and C3D_Fini to end the library's lifecycle. Check the return value of C3D_Init for success. ```c #include int main() { // Initialize citro3d with default command buffer size (256KB) if (!C3D_Init(C3D_DEFAULT_CMDBUF_SIZE)) { printf("Failed to initialize citro3d\n"); return 1; } // Your rendering code here... // Get command buffer usage (0.0 to 1.0) float usage = C3D_GetCmdBufUsage(); printf("Command buffer usage: %.1f%%\n", usage * 100.0f); // Cleanup C3D_Fini(); return 0; } ``` -------------------------------- ### Citro3D Frame Rendering Loop Source: https://context7.com/devkitpro/citro3d/llms.txt Manages the rendering frame lifecycle using C3D_FrameBegin, C3D_FrameDrawOn, and C3D_FrameEnd. Use C3D_FRAME_SYNCDRAW for VBlank synchronization. This example also shows drawing to stereo 3D targets and retrieving timing statistics. ```c #include // Main rendering loop while (aptMainLoop()) { // Begin frame with sync to display refresh C3D_FrameBegin(C3D_FRAME_SYNCDRAW); // Select render target to draw on C3D_FrameDrawOn(top); // Draw geometry C3D_DrawArrays(GPU_TRIANGLES, 0, vertexCount); // For stereo 3D, draw to both eyes if (iod > 0.0f) { C3D_FrameDrawOn(topLeft); C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projLeft); C3D_DrawArrays(GPU_TRIANGLES, 0, vertexCount); C3D_FrameDrawOn(topRight); C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projRight); C3D_DrawArrays(GPU_TRIANGLES, 0, vertexCount); } // End frame C3D_FrameEnd(0); } // Get timing statistics float drawTime = C3D_GetDrawingTime(); // GPU drawing time in ms float procTime = C3D_GetProcessingTime(); // CPU processing time in ms ``` -------------------------------- ### Configure Lighting System Source: https://context7.com/devkitpro/citro3d/llms.txt Initializes a light environment, defines material properties, and configures light sources with spotlights, distance attenuation, and Phong specular highlights. ```c #include // Initialize light environment C3D_LightEnv lightEnv; C3D_LightEnvInit(&lightEnv); // Set ambient light C3D_LightEnvAmbient(&lightEnv, 0.2f, 0.2f, 0.2f); // Configure material C3D_Material material = { .ambient = { 0.2f, 0.2f, 0.2f }, .diffuse = { 0.8f, 0.8f, 0.8f }, .specular0 = { 1.0f, 1.0f, 1.0f }, .specular1 = { 0.0f, 0.0f, 0.0f }, .emission = { 0.0f, 0.0f, 0.0f } }; C3D_LightEnvMaterial(&lightEnv, &material); // Create a light C3D_Light light; C3D_LightInit(&light, &lightEnv); C3D_LightEnable(&light, true); // Set light colors C3D_LightColor(&light, 1.0f, 1.0f, 1.0f); // Sets diffuse and both specular C3D_LightAmbient(&light, 0.1f, 0.1f, 0.1f); C3D_LightDiffuse(&light, 0.8f, 0.8f, 0.8f); C3D_LightSpecular0(&light, 1.0f, 1.0f, 1.0f); C3D_LightSpecular1(&light, 0.5f, 0.5f, 0.5f); // Set light position C3D_FVec lightPos = FVec4_New(0.0f, 10.0f, 0.0f, 1.0f); C3D_LightPosition(&light, &lightPos); // Configure spotlight C3D_LightSpotEnable(&light, true); C3D_LightSpotDir(&light, 0.0f, -1.0f, 0.0f); // Create spotlight LUT C3D_LightLut spotLut; LightLut_Spotlight(&spotLut, C3D_AngleFromDegrees(30.0f)); C3D_LightSpotLut(&light, &spotLut); // Configure distance attenuation C3D_LightDistAttnEnable(&light, true); C3D_LightLutDA distLut; LightLutDA_Quadratic(&distLut, 0.0f, 100.0f, 0.01f, 0.001f); C3D_LightDistAttn(&light, &distLut); // Create Phong specular LUT C3D_LightLut phongLut; LightLut_Phong(&phongLut, 32.0f); // Shininess C3D_LightEnvLut(&lightEnv, GPU_LUT_D0, GPU_LUTINPUT_NH, false, &phongLut); // Enable Fresnel effect C3D_LightEnvFresnel(&lightEnv, GPU_PRI_SEC_ALPHA_FRESNEL); // Enable bump mapping C3D_LightEnvBumpMode(&lightEnv, GPU_BUMP_AS_BUMP); C3D_LightEnvBumpSel(&lightEnv, 0); // Normal map on texture unit 0 // Bind the light environment C3D_LightEnvBind(&lightEnv); ``` -------------------------------- ### Initialize and Transform Matrices Source: https://context7.com/devkitpro/citro3d/llms.txt Demonstrates initializing an identity matrix and applying translation, rotation, and scaling transformations. The `bRightSide` parameter controls the order of matrix multiplication. ```c #include C3D_Mtx projection, modelView; // Create identity matrix Mtx_Identity(&modelView); // Apply transformations (bRightSide=true applies to the right: M = M * T) Mtx_Translate(&modelView, 0.0f, 0.0f, -2.0f, true); Mtx_RotateY(&modelView, C3D_AngleFromDegrees(45.0f), true); Mtx_Scale(&modelView, 1.0f, 1.0f, 1.0f); ``` -------------------------------- ### Create and Configure Render Target Source: https://context7.com/devkitpro/citro3d/llms.txt Creates a render target with specified dimensions, color, and depth formats. Use C3D_RenderTargetSetOutput to link it to a display screen and set transfer flags. Remember to delete the render target when done. ```c #include // Create render target for top screen (240x400 in rotated coordinates) C3D_RenderTarget* top = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); // Set clear color and depth values C3D_RenderTargetClear(top, C3D_CLEAR_ALL, 0x777777FF, 0); // Link to top screen left eye #define DISPLAY_TRANSFER_FLAGS \ (GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | \ GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \ GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)) C3D_RenderTargetSetOutput(top, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); // For stereoscopic 3D, create separate targets for each eye C3D_RenderTarget* topLeft = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTarget* topRight = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTargetSetOutput(topLeft, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); C3D_RenderTargetSetOutput(topRight, GFX_TOP, GFX_RIGHT, DISPLAY_TRANSFER_FLAGS); // Cleanup when done C3D_RenderTargetDelete(top); ``` -------------------------------- ### Create and Manipulate 3D Vectors Source: https://context7.com/devkitpro/citro3d/llms.txt Shows how to create 3D vectors and perform basic arithmetic operations like addition, subtraction, scaling, and negation. ```c #include // Create vectors C3D_FVec v1 = FVec3_New(1.0f, 2.0f, 3.0f); C3D_FVec v2 = FVec3_New(4.0f, 5.0f, 6.0f); C3D_FVec v4 = FVec4_New(1.0f, 2.0f, 3.0f, 1.0f); // Vector arithmetic C3D_FVec sum = FVec3_Add(v1, v2); C3D_FVec diff = FVec3_Subtract(v1, v2); C3D_FVec scaled = FVec3_Scale(v1, 2.0f); C3D_FVec negated = FVec3_Negate(v1); ``` -------------------------------- ### Configure Vertex Buffers and Draw Source: https://context7.com/devkitpro/citro3d/llms.txt Allocate vertex data in linear memory and configure BufInfo for rendering. Use permutation masks to define how interleaved data maps to attributes. ```c #include // Allocate vertex buffer in linear memory Vertex* vboData = (Vertex*)linearAlloc(sizeof(Vertex) * vertexCount); // Fill vertex data vboData[0].position[0] = -0.5f; vboData[0].position[1] = -0.5f; vboData[0].position[2] = 0.0f; // ... fill remaining vertices // Configure buffer info C3D_BufInfo* bufInfo = C3D_GetBufInfo(); BufInfo_Init(bufInfo); // Add buffer: data, stride, attribCount, permutation // Permutation 0x210 means: attr0 at offset 0, attr1 at offset 1, attr2 at offset 2 BufInfo_Add(bufInfo, vboData, sizeof(Vertex), 3, 0x210); // Draw with configured buffers C3D_DrawArrays(GPU_TRIANGLES, 0, vertexCount); // For indexed drawing u16 indices[] = { 0, 1, 2, 2, 3, 0 }; C3D_DrawElements(GPU_TRIANGLES, 6, C3D_UNSIGNED_SHORT, indices); // Cleanup linearFree(vboData); ``` -------------------------------- ### Perform Quaternion Operations Source: https://context7.com/devkitpro/citro3d/llms.txt Demonstrates common quaternion operations including multiplication, normalization, conjugation, inversion, and dot product. ```c // Quaternion operations C3D_FQuat combined = Quat_Multiply(q, rotation); C3D_FQuat normalized = Quat_Normalize(combined); C3D_FQuat conjugate = Quat_Conjugate(q); C3D_FQuat inverse = Quat_Inverse(q); float dot = Quat_Dot(q, rotation); ``` -------------------------------- ### Create Look-At Matrix Source: https://context7.com/devkitpro/citro3d/llms.txt Constructs a view matrix that positions and orients the camera in the scene. Requires camera position, target point, and an up vector. ```c // Look-at matrix C3D_FVec cameraPos = FVec3_New(0.0f, 0.0f, 5.0f); C3D_FVec target = FVec3_New(0.0f, 0.0f, 0.0f); C3D_FVec up = FVec3_New(0.0f, 1.0f, 0.0f); Mtx_LookAt(&modelView, cameraPos, target, up, false); ``` -------------------------------- ### Calculate Vector Properties Source: https://context7.com/devkitpro/citro3d/llms.txt Demonstrates calculating the dot product, magnitude (length), and distance between two vectors. Also shows how to normalize a vector to unit length. ```c // Vector properties float dot = FVec3_Dot(v1, v2); float magnitude = FVec3_Magnitude(v1); float distance = FVec3_Distance(v1, v2); C3D_FVec normalized = FVec3_Normalize(v1); ``` -------------------------------- ### Configure Fog Effects Source: https://context7.com/devkitpro/citro3d/llms.txt Sets up distance-based atmospheric fog using lookup tables and color configuration. ```c #include // Create fog lookup table C3D_FogLut fogLut; FogLut_Exp(&fogLut, 0.5f, // Density 1.5f, // Gradient (controls falloff curve) 1.0f, // Near distance 100.0f); // Far distance // Configure fog mode C3D_FogGasMode(GPU_FOG, GPU_PLAIN_DENSITY, false); // Set fog color C3D_FogColor(0xFFCCCCCC); // Gray fog // Bind fog LUT C3D_FogLutBind(&fogLut); // Alternative: Create fog from custom array float fogData[256]; // ... fill with custom fog values FogLut_FromArray(&fogLut, fogData); ``` -------------------------------- ### Initialize and Manage Textures with C3D_Tex Source: https://context7.com/devkitpro/citro3d/llms.txt Use these functions to create, upload, and configure various texture types including mipmaps and cube maps. Ensure C3D_TexFlush is called after modifications to synchronize the cache. ```c #include C3D_Tex texture; // Initialize 2D texture C3D_TexInit(&texture, 64, 64, GPU_RGBA8); // Initialize with mipmaps C3D_TexInitMipmap(&texture, 256, 256, GPU_RGBA8); // Initialize cube map C3D_TexCube cube; C3D_TexInitCube(&texture, &cube, 128, 128, GPU_RGBA8); // Initialize in VRAM (faster access, limited space) C3D_TexInitVRAM(&texture, 64, 64, GPU_RGBA8); // Initialize shadow map C3D_TexInitShadow(&texture, 256, 256); // Upload texture data void* textureData = loadTextureFromFile("texture.bin"); C3D_TexUpload(&texture, textureData); // Load specific mipmap level C3D_TexLoadImage(&texture, mipmapData, GPU_TEXFACE_2D, 1); // Generate mipmaps automatically C3D_TexGenerateMipmap(&texture, GPU_TEXFACE_2D); // Set texture filtering C3D_TexSetFilter(&texture, GPU_LINEAR, GPU_NEAREST); // Mag, Min filter C3D_TexSetFilterMipmap(&texture, GPU_LINEAR); // Mipmap filter // Set texture wrapping C3D_TexSetWrap(&texture, GPU_REPEAT, GPU_REPEAT); // S, T wrap mode // Set LOD bias C3D_TexSetLodBias(&texture, 0.5f); // Bind texture to texture unit C3D_TexBind(0, &texture); // Flush texture cache C3D_TexFlush(&texture); // Cleanup C3D_TexDelete(&texture); ``` -------------------------------- ### Manage Matrix Stacks Source: https://context7.com/devkitpro/citro3d/llms.txt Uses a stack-based system to manage hierarchical transformations for rendering objects. ```c #include C3D_MtxStack modelStack; // Initialize matrix stack MtxStack_Init(&modelStack); // Bind to shader uniform MtxStack_Bind(&modelStack, GPU_VERTEX_SHADER, uLoc_modelView, 4); // Get current matrix and modify C3D_Mtx* current = MtxStack_Cur(&modelStack); Mtx_Identity(current); Mtx_Translate(current, 0.0f, 0.0f, -5.0f, true); // Push matrix (save state) C3D_Mtx* pushed = MtxStack_Push(&modelStack); Mtx_RotateY(pushed, C3D_AngleFromDegrees(45.0f), true); // Draw child object MtxStack_Update(&modelStack); // Upload to GPU C3D_DrawArrays(GPU_TRIANGLES, 0, childVertexCount); // Pop matrix (restore state) MtxStack_Pop(&modelStack); // Draw parent object MtxStack_Update(&modelStack); C3D_DrawArrays(GPU_TRIANGLES, 0, parentVertexCount); ``` -------------------------------- ### Generate Procedural Textures Source: https://context7.com/devkitpro/citro3d/llms.txt Configures procedural texture parameters including noise, UV mapping, and color lookup tables. ```c #include C3D_ProcTex procTex; // Initialize procedural texture C3D_ProcTexInit(&procTex, 0, 128); // offset, length in color LUT // Configure UV clamping C3D_ProcTexClamp(&procTex, GPU_PT_REPEAT, GPU_PT_REPEAT); // Configure combiner function C3D_ProcTexCombiner(&procTex, false, GPU_PT_U, GPU_PT_U); // Configure shift C3D_ProcTexShift(&procTex, GPU_PT_NONE, GPU_PT_NONE); // Enable noise C3D_ProcTexNoiseEnable(&procTex, true); C3D_ProcTexNoiseCoefs(&procTex, C3D_ProcTex_UV, 0.5f, 2.0f, 0.0f); // Set LOD bias C3D_ProcTexLodBias(&procTex, 0.0f); // Configure filter C3D_ProcTexFilter(&procTex, GPU_PT_NEAREST); // Create and bind noise LUT C3D_ProcTexLut noiseLut; float noiseData[129]; // ... fill with noise values ProcTexLut_FromArray(&noiseLut, noiseData); C3D_ProcTexLutBind(GPU_LUT_NOISE, &noiseLut); // Create and bind color LUT C3D_ProcTexColorLut colorLut; u32 colorData[128]; // ... fill with gradient colors ProcTexColorLut_Write(&colorLut, colorData, 0, 128); C3D_ProcTexColorLutBind(&colorLut); // Bind procedural texture to texture coordinate set C3D_ProcTexBind(0, &procTex); ``` -------------------------------- ### Create Look-At Quaternion Source: https://context7.com/devkitpro/citro3d/llms.txt Generates a quaternion that orients an object to face from a source position towards a target position, considering a forward and up direction. ```c // Look-at quaternion C3D_FVec source = FVec3_New(0.0f, 0.0f, 0.0f); C3D_FVec target = FVec3_New(0.0f, 0.0f, -1.0f); C3D_FVec forward = FVec3_New(0.0f, 0.0f, -1.0f); C3D_FVec up = FVec3_New(0.0f, 1.0f, 0.0f); C3D_FQuat lookAt = Quat_LookAt(source, target, forward, up); ``` -------------------------------- ### Configure Depth and Stencil Testing with Citro3D Source: https://context7.com/devkitpro/citro3d/llms.txt Control per-fragment operations like depth testing, stencil testing, alpha blending, and face culling. This includes enabling/disabling tests, setting comparison functions, defining operations for stencil failures, and configuring blending factors. ```c #include // Enable depth testing with write C3D_DepthTest(true, GPU_GREATER, GPU_WRITE_ALL); // Configure depth map C3D_DepthMap(true, -1.0f, 0.0f); // bIsZBuffer, zScale, zOffset // Enable stencil testing C3D_StencilTest(true, GPU_EQUAL, 1, 0xFF, 0xFF); C3D_StencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_REPLACE); // Alpha testing (discard fragments below threshold) C3D_AlphaTest(true, GPU_GREATER, 128); // Alpha blending C3D_AlphaBlend( GPU_BLEND_ADD, GPU_BLEND_ADD, // Color, Alpha equations GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, // Source, Dest color factors GPU_ONE, GPU_ZERO); // Source, Dest alpha factors // Set blending color C3D_BlendingColor(0x80808080); // Face culling C3D_CullFace(GPU_CULL_BACK_CCW); // Early depth test (performance optimization) C3D_EarlyDepthTest(true, GPU_EARLYDEPTH_GREATER, 0); // Color logic operation (alternative to blending) C3D_ColorLogicOp(GPU_LOGICOP_XOR); // Fragment operation mode C3D_FragOpMode(GPU_FRAGOPMODE_GL); ``` -------------------------------- ### Create Identity Quaternion Source: https://context7.com/devkitpro/citro3d/llms.txt Initializes a quaternion representing no rotation (identity). ```c #include // Identity quaternion (no rotation) C3D_FQuat q = Quat_Identity(); ``` -------------------------------- ### Create Perspective Projection Matrix Source: https://context7.com/devkitpro/citro3d/llms.txt Generates a perspective projection matrix suitable for the 3DS top screen, considering aspect ratio and field of view. Adjust near and far planes for clipping. ```c // Perspective projection for 3DS top screen (with tilt for screen rotation) Mtx_PerspTilt(&projection, C3D_AngleFromDegrees(60.0f), // Field of view C3D_AspectRatioTop, // 400/240 aspect ratio 0.1f, // Near plane 100.0f, // Far plane false); // Right-handed coordinates ``` -------------------------------- ### Configure Texture Environment Stages with Citro3D Source: https://context7.com/devkitpro/citro3d/llms.txt Use C3D_TexEnv functions to configure fragment combiner stages, controlling how textures and vertex colors are combined. This allows for effects like texture modulation, replacement, and separate RGB/Alpha operations. You can also set constant colors and operand selections for these stages. ```c #include // Get texture environment stage C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvInit(env); // Simple texture with vertex color modulation C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); // Texture only (no vertex color) C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_TEXTURE0, GPU_TEXTURE0); C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); // Separate RGB and Alpha operations C3D_TexEnvSrc(env, C3D_RGB, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); C3D_TexEnvFunc(env, C3D_RGB, GPU_MODULATE); C3D_TexEnvSrc(env, C3D_Alpha, GPU_CONSTANT, GPU_CONSTANT, GPU_CONSTANT); C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE); // Set constant color for TexEnv C3D_TexEnvColor(env, 0xFF0000FF); // Red with full alpha // Configure operand selection C3D_TexEnvOpRgb(env, GPU_TEVOP_RGB_SRC_COLOR, GPU_TEVOP_RGB_SRC_COLOR, GPU_TEVOP_RGB_SRC_COLOR); C3D_TexEnvOpAlpha(env, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA); // Set output scale C3D_TexEnvScale(env, C3D_Both, GPU_TEVSCALE_2); // Multiple TexEnv stages for complex effects C3D_TexEnv* env1 = C3D_GetTexEnv(1); C3D_TexEnvInit(env1); C3D_TexEnvSrc(env1, C3D_Both, GPU_PREVIOUS, GPU_TEXTURE1, GPU_PREVIOUS); C3D_TexEnvFunc(env1, C3D_Both, GPU_ADD); // Set buffer color and update mode C3D_TexEnvBufColor(0xFFFFFFFF); C3D_TexEnvBufUpdate(C3D_RGB, 0x1); ``` -------------------------------- ### Configure Vertex Attributes Source: https://context7.com/devkitpro/citro3d/llms.txt Map vertex buffer elements to shader input registers using AttrInfo. Fixed attributes can be set globally for all vertices. ```c #include // Define vertex structure typedef struct { float position[3]; float texcoord[2]; float normal[3]; } Vertex; // Configure vertex attributes C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); AttrInfo_Init(attrInfo); // Add attribute loaders: regId, format, count AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // v0 = position (3 floats) AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2); // v1 = texcoord (2 floats) AttrInfo_AddLoader(attrInfo, 2, GPU_FLOAT, 3); // v2 = normal (3 floats) // For fixed attributes (constant value) AttrInfo_AddFixed(attrInfo, 3); // v3 = fixed value // Set fixed attribute value C3D_FixedAttribSet(3, 1.0f, 1.0f, 1.0f, 1.0f); ``` -------------------------------- ### Set Shader Uniform Values with Citro3D Source: https://context7.com/devkitpro/citro3d/llms.txt Use C3D_FVUnif and related functions to set uniform values in shaders. This includes matrices, float vectors, integer vectors, and booleans. Ensure uniform locations are retrieved from the compiled shader program before setting values. ```c #include // Get uniform locations from compiled shader int uLoc_projection = shaderInstanceGetUniformLocation(program->vertexShader, "projection"); int uLoc_modelView = shaderInstanceGetUniformLocation(program->vertexShader, "modelView"); int uLoc_lightVec = shaderInstanceGetUniformLocation(program->vertexShader, "lightVec"); int uLoc_lightClr = shaderInstanceGetUniformLocation(program->vertexShader, "lightClr"); // Set 4x4 matrix uniform C3D_Mtx projection, modelView; Mtx_PerspTilt(&projection, C3D_AngleFromDegrees(60.0f), C3D_AspectRatioTop, 0.1f, 100.0f, false); Mtx_Identity(&modelView); C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projection); C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_modelView, &modelView); // Set 3x4 matrix (for normal transforms) C3D_FVUnifMtx3x4(GPU_VERTEX_SHADER, uLoc_normalMatrix, &normalMtx); // Set float vector uniform C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightVec, 0.0f, 0.0f, -1.0f, 0.0f); C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightClr, 1.0f, 1.0f, 1.0f, 1.0f); // Set integer vector uniform (for loop counters, etc.) C3D_IVUnifSet(GPU_VERTEX_SHADER, 0x60, 4, 0, 0, 0); // Set boolean uniform C3D_BoolUnifSet(GPU_VERTEX_SHADER, 0x68, true); // Direct access to uniform arrays C3D_FVec* uniformPtr = C3D_FVUnifWritePtr(GPU_VERTEX_SHADER, uLoc_boneMatrices, 4); uniformPtr[0] = FVec4_New(1.0f, 0.0f, 0.0f, 0.0f); ``` -------------------------------- ### Create Orthographic Projection Matrix Source: https://context7.com/devkitpro/citro3d/llms.txt Generates an orthographic projection matrix, useful for 2D rendering or UI elements. Defines the boundaries of the view frustum. ```c // Orthographic projection Mtx_OrthoTilt(&projection, 0.0f, 400.0f, // Left, Right 0.0f, 240.0f, // Bottom, Top -100.0f, 100.0f, // Near, Far false); // Right-handed ``` -------------------------------- ### Multiply Matrices Source: https://context7.com/devkitpro/citro3d/llms.txt Combines two matrices, typically a projection and a model-view matrix, into a single Model-View-Projection (MVP) matrix for rendering. ```c // Matrix multiplication C3D_Mtx mvp; Mtx_Multiply(&mvp, &projection, &modelView); ``` -------------------------------- ### Invert and Transpose Matrix Source: https://context7.com/devkitpro/citro3d/llms.txt Calculates the inverse of a matrix, useful for un-transforming points or normals. Also demonstrates transposing a matrix. ```c // Matrix inverse float determinant = Mtx_Inverse(&modelView); // Returns 0 if degenerate // Matrix transpose Mtx_Transpose(&modelView); ``` -------------------------------- ### Create Quaternion from Axis-Angle Source: https://context7.com/devkitpro/citro3d/llms.txt Constructs a quaternion representing a rotation around a specified axis by a given angle. ```c // Create from axis-angle C3D_FVec axis = FVec3_New(0.0f, 1.0f, 0.0f); // Y-axis C3D_FQuat rotation = Quat_FromAxisAngle(axis, C3D_AngleFromDegrees(45.0f)); ``` -------------------------------- ### Create Quaternion from Euler Angles Source: https://context7.com/devkitpro/citro3d/llms.txt Generates a quaternion from Euler angles (pitch, yaw, roll). The `true` parameter indicates right-side multiplication for the order of rotations. ```c // Create from Euler angles (pitch, yaw, roll) C3D_FQuat euler = Quat_FromPitchYawRoll( C3D_AngleFromDegrees(30.0f), // Pitch C3D_AngleFromDegrees(45.0f), // Yaw C3D_AngleFromDegrees(0.0f), // Roll true); // Right-side multiplication ``` -------------------------------- ### Import Tex3DS Texture Formats Source: https://context7.com/devkitpro/citro3d/llms.txt Import textures from memory, file descriptors, or standard file streams. Tex3DS supports subtexture metadata useful for sprite sheets. ```c #include #include C3D_Tex texture; Tex3DS_Texture t3x; // Import from memory buffer t3x = Tex3DS_TextureImport(textureData, textureSize, &texture, NULL, false); // Import from file descriptor int fd = open("texture.t3x", O_RDONLY); t3x = Tex3DS_TextureImportFD(fd, &texture, NULL, false); close(fd); // Import from FILE stream FILE* fp = fopen("texture.t3x", "rb"); t3x = Tex3DS_TextureImportStdio(fp, &texture, NULL, false); fclose(fp); // Get subtexture count (for sprite sheets) size_t numSubTex = Tex3DS_GetNumSubTextures(t3x); // Get subtexture info const Tex3DS_SubTexture* subtex = Tex3DS_GetSubTexture(t3x, 0); printf("Subtexture: %dx%d\n", subtex->width, subtex->height); // Get texture coordinates float u, v; Tex3DS_SubTextureTopLeft(subtex, &u, &v); Tex3DS_SubTextureBottomRight(subtex, &u, &v); // Check if subtexture is rotated if (Tex3DS_SubTextureRotated(subtex)) { // Handle rotated sprite } // Free Tex3DS metadata (texture remains valid) Tex3DS_TextureFree(t3x); C3D_TexDelete(&texture); ``` -------------------------------- ### Convert Matrix to Quaternion Source: https://context7.com/devkitpro/citro3d/llms.txt Extracts a quaternion rotation from a given 4x4 matrix. Useful when dealing with matrices that represent rotations. ```c // Convert matrix back to quaternion C3D_FQuat fromMatrix = Quat_FromMtx(&rotationMatrix); ``` -------------------------------- ### Create Stereoscopic 3D Projection Matrices Source: https://context7.com/devkitpro/citro3d/llms.txt Generates separate perspective projection matrices for the left and right eyes to achieve stereoscopic 3D effect. Interocular distance is derived from the 3D slider. ```c // Stereoscopic 3D projection float iod = osGet3DSliderState(); // Interocular distance from 3D slider float focalLength = 2.0f; Mtx_PerspStereoTilt(&projLeft, C3D_AngleFromDegrees(60.0f), C3D_AspectRatioTop, 0.1f, 100.0f, -iod, focalLength, false); Mtx_PerspStereoTilt(&projRight, C3D_AngleFromDegrees(60.0f), C3D_AspectRatioTop, 0.1f, 100.0f, iod, focalLength, false); ``` -------------------------------- ### Set Viewport and Scissor Regions Source: https://context7.com/devkitpro/citro3d/llms.txt Control the rendering viewport and scissor test regions using C3D_SetViewport and C3D_SetScissor. The scissor test can be enabled, disabled, or inverted. ```c #include // Set viewport (x, y, width, height) C3D_SetViewport(0, 0, 400, 240); // Enable scissor test (rectangular clipping) C3D_SetScissor(GPU_SCISSOR_NORMAL, 50, 50, 350, 190); // Disable scissor test C3D_SetScissor(GPU_SCISSOR_DISABLE, 0, 0, 0, 0); // Inverted scissor (draw outside rectangle) C3D_SetScissor(GPU_SCISSOR_INVERT, 100, 100, 300, 140); ``` -------------------------------- ### Rotate Vector with Quaternion Source: https://context7.com/devkitpro/citro3d/llms.txt Applies a quaternion rotation to a 3D vector, transforming its orientation. ```c // Apply rotation to vector C3D_FVec point = FVec3_New(1.0f, 0.0f, 0.0f); C3D_FVec rotated = Quat_CrossFVec3(rotation, point); ``` -------------------------------- ### Calculate Vector Cross Product Source: https://context7.com/devkitpro/citro3d/llms.txt Computes the cross product of two 3D vectors, resulting in a vector perpendicular to both input vectors. ```c // Cross product (perpendicular vector) C3D_FVec cross = FVec3_Cross(v1, v2); ``` -------------------------------- ### Interpolate Quaternions Source: https://context7.com/devkitpro/citro3d/llms.txt Calculates an intermediate quaternion rotation using the power function, useful for smooth interpolation between two rotations (e.g., animation). ```c // Interpolation using power function C3D_FQuat halfRotation = Quat_Pow(rotation, 0.5f); ``` -------------------------------- ### Multiply Matrix and Vector Source: https://context7.com/devkitpro/citro3d/llms.txt Applies a 4x4 transformation matrix to a 4D or 3D vector. For 3D vectors, the 'w' component is implicitly treated as 1.0. ```c // Matrix-vector multiplication C3D_Mtx transform; Mtx_Identity(&transform); C3D_FVec transformed = Mtx_MultiplyFVec4(&transform, v4); C3D_FVec transformed3 = Mtx_MultiplyFVec3(&transform, v1); ``` -------------------------------- ### Perform Perspective Divide Source: https://context7.com/devkitpro/citro3d/llms.txt Divides the components of a 4D vector by its 'w' component, a common step after matrix multiplication to convert from clip space to normalized device coordinates (NDC). ```c // Perspective divide for clip-space to NDC C3D_FVec ndc = FVec4_PerspDivide(v4); ``` -------------------------------- ### Convert Quaternion to Matrix Source: https://context7.com/devkitpro/citro3d/llms.txt Converts a quaternion representing a rotation into a 4x4 rotation matrix, which can then be used in standard matrix transformations. ```c // Convert to rotation matrix C3D_Mtx rotationMatrix; Mtx_FromQuat(&rotationMatrix, rotation); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.