void ctrTextureBias(u32 color) { C3D_TexEnv* env = C3D_GetTexEnv(2); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvSrc(env, C3D_Both, GPU_PREVIOUS, GPU_CONSTANT, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_ADD); C3D_TexEnvColor(env, color); }
void TextEngine::setTextColor(u32 color) { C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvSrc(env, C3D_RGB, GPU_CONSTANT, 0, 0); C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_CONSTANT, 0); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE); C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE); C3D_TexEnvColor(env, color); }
void ctrActivateTexture(C3D_Tex* texture) { if (texture == activeTexture) { return; } if (activeTexture) { ctrFlushBatch(); } activeTexture = texture; C3D_TexBind(0, activeTexture); C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); if (texture->fmt < GPU_LA8) { C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); } else { C3D_TexEnvSrc(env, C3D_RGB, GPU_PRIMARY_COLOR, 0, 0); C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0); C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE); C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE); } env = C3D_GetTexEnv(1); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvSrc(env, C3D_Both, GPU_PREVIOUS, 0, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); env = C3D_GetTexEnv(2); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvSrc(env, C3D_Both, GPU_PREVIOUS, 0, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); C3D_Mtx textureMtx = { .m = { // Rows are in the order w z y x, because ctrulib 0.0f, 0.0f, 0.0f, 1.0f / activeTexture->width, 0.0f, 0.0f, 1.0f / activeTexture->height, 0.0f } }; C3D_FVUnifMtx2x4(GPU_GEOMETRY_SHADER, GSH_FVEC_textureMtx, &textureMtx); }
void OSystem_3DS::initGraphics() { _pfGame = Graphics::PixelFormat::createFormatCLUT8(); _pfGameTexture = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); // Initialize the render targets _renderTargetTop = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTargetSetClear(_renderTargetTop, C3D_CLEAR_ALL, 0x0000000, 0); C3D_RenderTargetSetOutput(_renderTargetTop, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); _renderTargetBottom = C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); C3D_RenderTargetSetClear(_renderTargetBottom, C3D_CLEAR_ALL, 0x00000000, 0); C3D_RenderTargetSetOutput(_renderTargetBottom, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); // Load and bind simple default shader (shader.v.pica) _dvlb = DVLB_ParseFile((u32*)shader_shbin, shader_shbin_size); shaderProgramInit(&_program); shaderProgramSetVsh(&_program, &_dvlb->DVLE[0]); C3D_BindProgram(&_program); _projectionLocation = shaderInstanceGetUniformLocation(_program.vertexShader, "projection"); _modelviewLocation = shaderInstanceGetUniformLocation(_program.vertexShader, "modelView"); C3D_AttrInfo *attrInfo = C3D_GetAttrInfo(); AttrInfo_Init(attrInfo); AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // v0=position AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2); // v1=texcoord Mtx_OrthoTilt(&_projectionTop, 0.0, 400.0, 240.0, 0.0, 0.0, 1.0); Mtx_OrthoTilt(&_projectionBottom, 0.0, 320.0, 240.0, 0.0, 0.0, 1.0); C3D_TexEnv *env = C3D_GetTexEnv(0); C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, 0, 0); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); C3D_DepthTest(false, GPU_GEQUAL, GPU_WRITE_ALL); C3D_CullFace(GPU_CULL_NONE); }
void CitroInit(size_t commandBufferSize) { C3D_Init(commandBufferSize); // Configure attributes for use with the vertex shader C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); AttrInfo_Init(attrInfo); AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 2); // v0=position AttrInfo_AddLoader(attrInfo, 1, GPU_UNSIGNED_BYTE, 4); // v1=color AttrInfo_AddLoader(attrInfo, 2, GPU_FLOAT, 2); // v2=texcoord C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR, 0, 0); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); C3D_DepthTest(false, GPU_GEQUAL, GPU_WRITE_ALL); C3D_CullFace(GPU_CULL_NONE); }
void initialize(void) { // Load the vertex shader, create a shader program and bind it vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size); shaderProgramInit(&program); shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]); C3D_BindProgram(&program); // Get the location of the uniforms uLoc_projection = shaderInstanceGetUniformLocation(program.vertexShader, "projection"); // Compute the projection matrix Mtx_OrthoTilt(&projection, -200.0, 200.0, -120.0, 120.0, 0.0, 1.0); // Update the uniforms C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projection); // Create the VBO (vertex buffer object) vbo_data = linearAlloc(sizeof(vertices)); memcpy(vbo_data, vertices, sizeof(vertices)); // Configure buffers C3D_BufInfo* bufInfo = C3D_GetBufInfo(); BufInfo_Init(bufInfo); BufInfo_Add(bufInfo, vbo_data, sizeof(vertices[0]), 2, 0x10); // Configure attributes for use with the vertex shader C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); AttrInfo_Init(attrInfo); AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 2); // v0=x,y AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 3); // v1=r,g,b // Configure the first fragment shading substage to just pass through the vertex color // See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR, 0, 0); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); }
static void sceneInit(void) { // Load the vertex shader, create a shader program and bind it vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size); shaderProgramInit(&program); shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]); C3D_BindProgram(&program); // Get the location of the uniforms uLoc_projection = shaderInstanceGetUniformLocation(program.vertexShader, "Projection"); // Configure attributes for use with the vertex shader 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); // Create the VBO (vertex buffer object) vbo_data = linearAlloc(sizeof(vertex_list)); memcpy(vbo_data, vertex_list, sizeof(vertex_list)); // Configure buffers C3D_BufInfo* bufInfo = C3D_GetBufInfo(); BufInfo_Init(bufInfo); BufInfo_Add(bufInfo, vbo_data, sizeof(vertex), 1, 0x0); // Configure the first fragment shading substage to just pass through the vertex color // See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR, 0, 0); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); }
static void sceneInit(void) { // Load the shaders and create a shader program // The geoshader stride is set to 6 so that it processes a triangle at a time program_dvlb = DVLB_ParseFile((u32*)program_shbin, program_shbin_size); shaderProgramInit(&program); shaderProgramSetVsh(&program, &program_dvlb->DVLE[0]); shaderProgramSetGsh(&program, &program_dvlb->DVLE[1], 6); C3D_BindProgram(&program); // Get the location of the projection matrix uniform uLoc_projection = shaderInstanceGetUniformLocation(program.geometryShader, "projection"); // Configure attributes for use with the vertex shader C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); AttrInfo_Init(attrInfo); AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // v0=position AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 4); // v1=color // Compute the projection matrix Mtx_OrthoTilt(&projection, 0.0, 400.0, 0.0, 240.0, 0.0, 1.0); // Create the VBO (vertex buffer object) vbo_data = linearAlloc(sizeof(vertex_list)); memcpy(vbo_data, vertex_list, sizeof(vertex_list)); // Configure buffers C3D_BufInfo* bufInfo = C3D_GetBufInfo(); BufInfo_Init(bufInfo); BufInfo_Add(bufInfo, vbo_data, sizeof(vertex), 2, 0x10); // Configure the first fragment shading substage to just pass through the vertex color // See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR, 0, 0); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); }
void ctrTextureMultiply(void) { C3D_TexEnv* env = C3D_GetTexEnv(1); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvSrc(env, C3D_Both, GPU_PREVIOUS, GPU_TEXTURE0, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); }
//--------------------------------------------------------------------------------- static void sceneInit(void) { //--------------------------------------------------------------------------------- int i; // Load the vertex shader, create a shader program and bind it vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size); shaderProgramInit(&program); shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]); C3D_BindProgram(&program); // Get the location of the uniforms uLoc_projection = shaderInstanceGetUniformLocation(program.vertexShader, "projection"); // Configure attributes for use with the vertex shader // Attribute format and element count are ignored in immediate mode C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); AttrInfo_Init(attrInfo); AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // v0=position AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2); // v2=texcoord // Compute the projection matrix // Note: we're setting top to 240 here so origin is at top left. Mtx_OrthoTilt(&projection, 0.0, 400.0, 240.0, 0.0, 0.0, 1.0); // Configure buffers C3D_BufInfo* bufInfo = C3D_GetBufInfo(); BufInfo_Init(bufInfo); unsigned char* image; unsigned width, height; lodepng_decode32(&image, &width, &height, ballsprites_png, ballsprites_png_size); u8 *gpusrc = linearAlloc(width*height*4); // GX_DisplayTransfer needs input buffer in linear RAM u8* src=image; u8 *dst=gpusrc; // lodepng outputs big endian rgba so we need to convert for(int i = 0; i<width*height; i++) { int r = *src++; int g = *src++; int b = *src++; int a = *src++; *dst++ = a; *dst++ = b; *dst++ = g; *dst++ = r; } // ensure data is in physical ram GSPGPU_FlushDataCache(gpusrc, width*height*4); // Load the texture and bind it to the first texture unit C3D_TexInit(&spritesheet_tex, width, height, GPU_RGBA8); // Convert image to 3DS tiled texture format C3D_SafeDisplayTransfer ((u32*)gpusrc, GX_BUFFER_DIM(width,height), (u32*)spritesheet_tex.data, GX_BUFFER_DIM(width,height), TEXTURE_TRANSFER_FLAGS); gspWaitForPPF(); C3D_TexSetFilter(&spritesheet_tex, GPU_LINEAR, GPU_NEAREST); C3D_TexBind(0, &spritesheet_tex); free(image); linearFree(gpusrc); // Configure the first fragment shading substage to just pass through the texture color // See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight C3D_TexEnv* env = C3D_GetTexEnv(0); C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, 0, 0); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); srand(time(NULL)); for(i = 0; i < NUM_SPRITES; i++) { //random place and speed sprites[i].x = (rand() % (400 - 32 )) << 8; sprites[i].y = (rand() % (240 - 32 )) << 8 ; sprites[i].dx = (rand() & 0xFF) + 0x100; sprites[i].dy = (rand() & 0xFF) + 0x100; sprites[i].image = rand() & 3; if(rand() & 1) sprites[i].dx = -sprites[i].dx; if(rand() & 1) sprites[i].dy = -sprites[i].dy; } // Configure depth test to overwrite pixels with the same depth (needed to draw overlapping sprites) C3D_DepthTest(true, GPU_GEQUAL, GPU_WRITE_ALL); }
bool gfxInit() { gfxInitDefault(); if(!C3D_Init(C3D_DEFAULT_CMDBUF_SIZE)) { gfxCleanup(); return false; } c3dInitialized = true; u32 displayFlags = 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); targetTop = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); if(targetTop == NULL) { gfxCleanup(); return false; } C3D_RenderTargetSetClear(targetTop, C3D_CLEAR_ALL, 0, 0); C3D_RenderTargetSetOutput(targetTop, GFX_TOP, GFX_LEFT, displayFlags); targetBottom = C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); if(targetBottom == NULL) { gfxCleanup(); return false; } C3D_RenderTargetSetClear(targetBottom, C3D_CLEAR_ALL, 0, 0); C3D_RenderTargetSetOutput(targetBottom, GFX_BOTTOM, GFX_LEFT, displayFlags); dvlb = DVLB_ParseFile((u32*) default_shbin, default_shbin_len); if(dvlb == NULL) { gfxCleanup(); return false; } Result progInitRes = shaderProgramInit(&program); if(R_FAILED(progInitRes)) { gfxCleanup(); return false; } shaderInitialized = true; Result progSetVshRes = shaderProgramSetVsh(&program, &dvlb->DVLE[0]); if(R_FAILED(progSetVshRes)) { gfxCleanup(); return false; } C3D_BindProgram(&program); C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); if(attrInfo == NULL) { gfxCleanup(); return false; } AttrInfo_Init(attrInfo); AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2); C3D_TexEnv* env = C3D_GetTexEnv(0); if(env == NULL) { gfxCleanup(); return false; } C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, 0, 0); C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); C3D_DepthTest(true, GPU_GEQUAL, GPU_WRITE_ALL); Mtx_OrthoTilt(&projectionTop, 0.0, 400.0, 240.0, 0.0, 0.0, 1.0); Mtx_OrthoTilt(&projectionBottom, 0.0, 320.0, 240.0, 0.0, 0.0, 1.0); screenInit = false; borderInit = false; // Allocate and clear the screen buffer. screenBuffer = (u32*) linearAlloc(256 * 256 * sizeof(u32)); memset(screenBuffer, 0, 256 * 256 * sizeof(u32)); // Allocate and clear the scale2x buffer. scale2xBuffer = (u32*) linearAlloc(512 * 512 * sizeof(u32)); memset(scale2xBuffer, 0, 512 * 512 * sizeof(u32)); return true; }