/** * Make a snapshot of the screen in a texture WITHOUT ALPHA LAYER. * @param posx top left corner of the grabbed part. * @param posy top left corner of the grabbed part. * @param tex A pointer to a texture representing the screen or NULL if an error occurs. * @param clear When this flag is set to true, the screen is cleared after copy. */ void GRRLIB_Screen2Texture (int posx, int posy, GRRLIB_texImg *tex, bool clear) { if(tex->data != NULL) { GX_SetTexCopySrc(posx, posy, tex->w, tex->h); GX_SetTexCopyDst(tex->w, tex->h, GX_TF_RGBA8, GX_FALSE); GX_CopyTex(tex->data, GX_FALSE); GX_PixModeSync(); GRRLIB_FlushTex(tex); if(clear) { GX_CopyDisp(xfb[!fb], GX_TRUE); } } }
void reduce_cubemap (cubemap_info *cubemap, int subdiv) { int x, y, face; const u32 vtxfmt = GX_VTXFMT0; Mtx mvtmp; Mtx44 ortho; object_loc rect_loc; scene_info rect_scene; int half_subdiv = subdiv / 2; float scale_factor = 1.0 / ((float) half_subdiv - 0.5); /* Using an even number of subdivisions and spreading evenly from -1...1 ensures we don't try to evaluate the singularity point at the back of the sphere. */ assert ((subdiv & 1) == 0); scene_set_pos (&rect_scene, (guVector) { 0, 0, -5 }); scene_set_lookat (&rect_scene, (guVector) { 0, 0, 0 }); scene_set_up (&rect_scene, (guVector) { 0, 1, 0 }); scene_update_camera (&rect_scene); guOrtho (ortho, -1, 1, -1, 1, 1, 15); object_loc_initialise (&rect_loc, GX_PNMTX0); guMtxIdentity (mvtmp); object_set_matrices (&rect_scene, &rect_loc, rect_scene.camera, mvtmp, NULL, ortho, GX_ORTHOGRAPHIC); GX_ClearVtxDesc (); GX_SetVtxDesc (GX_VA_POS, GX_DIRECT); GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT); GX_SetVtxAttrFmt (vtxfmt, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt (vtxfmt, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); GX_SetCullMode (GX_CULL_BACK); rendertarget_texture (cubemap->sphsize, cubemap->sphsize, cubemap->sphfmt, GX_FALSE, GX_PF_RGB8_Z24, GX_ZC_LINEAR); for (face = 0; face < 6; face++) { shader_load (cubemap->face_shader[face]); for (x = -half_subdiv; x < half_subdiv - 1; x++) { float a = ((float) x + 0.5) * scale_factor; float a1 = ((float) x + 1.5) * scale_factor; GX_Begin (GX_TRIANGLESTRIP, vtxfmt, subdiv * 2); for (y = -half_subdiv; y < half_subdiv; y++) { float b = ((float) y + 0.5) * scale_factor; guVector tmp; face_to_sphere (&tmp, face, a, b); GX_Position3f32 (tmp.x, tmp.y, tmp.z); GX_TexCoord2f32 ((a + 1.0) / 2.0, (b + 1.0) / 2.0); face_to_sphere (&tmp, face, a1, b); GX_Position3f32 (tmp.x, tmp.y, tmp.z); GX_TexCoord2f32 ((a1 + 1.0) / 2.0, (b + 1.0) / 2.0); } GX_End (); } } GX_CopyTex (cubemap->sphtexels, GX_TRUE); GX_PixModeSync (); }
static display_target ghost_prepare_frame (sync_info *sync, void *params, int iparam) { glass_data *gdata = (glass_data *) params; /*GXTexObj spiderweb_tex_obj;*/ Mtx mvtmp, rot, mvtmp2; Mtx sep_scale; /*TPL_GetTexture (&spiderwebTPL, spiderweb, &spiderweb_tex_obj);*/ GX_InvalidateTexAll (); rendertarget_texture (RTT_WIDTH, RTT_HEIGHT, COPYFMT, GX_FALSE, GX_PF_RGB8_Z24, GX_ZC_LINEAR); GX_SetZMode (GX_FALSE, GX_LEQUAL, GX_FALSE); GX_SetBlendMode (GX_BM_NONE, GX_BL_ONE, GX_BL_ONE, GX_LO_SET); GX_SetColorUpdate (GX_TRUE); GX_SetAlphaUpdate (GX_FALSE); screenspace_rect (gdata->plain_texture_shader, GX_VTXFMT1, 0); GX_SetCopyClear ((GXColor) { 128, 128, 128, 0 }, 0x00ffffff); GX_CopyTex (gdata->grabbed_texture, GX_TRUE); GX_PixModeSync (); rendertarget_texture (RTT_WIDTH, RTT_HEIGHT, COPYFMT, GX_FALSE, GX_PF_RGB8_Z24, GX_ZC_LINEAR); GX_SetCopyClear ((GXColor) { 128, 128, 128, 0 }, 0x00ffffff); GX_SetColorUpdate (GX_TRUE); GX_SetAlphaUpdate (GX_FALSE); /* We need a grey background! This isn't very efficient though. */ GX_CopyTex (gdata->grabbed_texture, GX_TRUE); GX_SetCopyClear ((GXColor) { 0, 0, 0, 0 }, 0x00ffffff); GX_SetZMode (GX_FALSE, GX_LEQUAL, GX_FALSE); GX_SetBlendMode (GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GX_SetColorUpdate (GX_TRUE); GX_SetAlphaUpdate (GX_FALSE); GX_SetCullMode (GX_CULL_NONE); guMtxIdentity (mvtmp); guMtxRotAxisDeg (rot, &((guVector) { 0, 1, 0 }), gdata->thr); guMtxConcat (rot, mvtmp, mvtmp); guMtxRotAxisDeg (rot, &((guVector) { 1, 0, 0 }), gdata->thr * 0.7); guMtxConcat (rot, mvtmp, mvtmp); if (sync->time_offset < 1000) gdata->xoffset = -(float) (1000 - sync->time_offset) / 10.0; else if (sync->time_offset > 16000) gdata->xoffset = (float) (sync->time_offset - 16000) / 10.0; else gdata->xoffset = 0.0; /*guMtxScale (sep_scale, 6.0, 6.0, 6.0);*/ set_sep_scale (sep_scale, sync); guMtxTransApply (mvtmp, mvtmp2, gdata->xoffset, 0, 0); object_set_matrices (&scene, &gdata->obj_loc, scene.camera, mvtmp2, sep_scale, perspmat, GX_PERSPECTIVE); light_update (scene.camera, &light0); shader_load (gdata->refraction_shader); object_set_arrays (&blobby_thing_obj, OBJECT_POS | OBJECT_NORM, GX_VTXFMT0, 0); object_render (&blobby_thing_obj, OBJECT_POS | OBJECT_NORM, GX_VTXFMT0); /* guMtxTransApply (mvtmp, mvtmp2, 13, 0, 0); object_set_matrices (&scene, &gdata->obj_loc, scene.camera, mvtmp2, sep_scale, NULL, 0); object_render (&spooky_ghost_obj, OBJECT_POS | OBJECT_NORM, GX_VTXFMT0); guMtxTransApply (mvtmp, mvtmp2, -13, 0, 0); object_set_matrices (&scene, &gdata->obj_loc, scene.camera, mvtmp2, sep_scale, NULL, 0); object_render (&spooky_ghost_obj, OBJECT_POS | OBJECT_NORM, GX_VTXFMT0); */ GX_CopyTex (gdata->grabbed_texture, GX_TRUE); GX_PixModeSync (); return MAIN_BUFFER; }