static void drawFrame(glw_ps3_t *gp, int buffer) { gcmContextData *ctx = gp->gr.gr_be.be_ctx; realityViewportTranslate(ctx, gp->res.width/2, gp->res.height/2, 0.0, 0.0); realityViewportScale(ctx, gp->res.width/2, -gp->res.height/2, 1.0, 0.0); realityZControl(ctx, 0, 1, 1); // disable viewport culling // Enable alpha blending. realityBlendFunc(ctx, NV30_3D_BLEND_FUNC_SRC_RGB_SRC_ALPHA | NV30_3D_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA, NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA | NV30_3D_BLEND_FUNC_DST_ALPHA_ZERO); realityBlendEquation(ctx, NV40_3D_BLEND_EQUATION_RGB_FUNC_ADD | NV40_3D_BLEND_EQUATION_ALPHA_FUNC_ADD); realityBlendEnable(ctx, 1); realityViewport(ctx, gp->res.width, gp->res.height); setupRenderTarget(gp, buffer); // set the clear color realitySetClearColor(ctx, 0x00000000); realitySetClearDepthValue(ctx, 0xffff); // Clear the buffers realityClearBuffers(ctx, REALITY_CLEAR_BUFFERS_COLOR_R | REALITY_CLEAR_BUFFERS_COLOR_G | REALITY_CLEAR_BUFFERS_COLOR_B | NV30_3D_CLEAR_BUFFERS_COLOR_A | REALITY_CLEAR_BUFFERS_DEPTH); // XMB may overwrite currently loaded shaders, so clear them out gp->gr.gr_be.be_vp_current = NULL; gp->gr.gr_be.be_fp_current = NULL; realityCullEnable(ctx, 1); realityFrontFace(ctx, REALITY_FRONT_FACE_CCW); realityCullFace(ctx, REALITY_CULL_FACE_BACK); glw_lock(&gp->gr); glw_prepare_frame(&gp->gr, 0); gp->gr.gr_width = gp->res.width; gp->gr.gr_height = gp->res.height; glw_rctx_t rc; glw_rctx_init(&rc, gp->gr.gr_width, gp->gr.gr_height); glw_layout0(gp->gr.gr_universe, &rc); glw_render0(gp->gr.gr_universe, &rc); glw_unlock(&gp->gr); }
void glw_frontface(struct glw_root *gr, int how) { realityFrontFace(gr->gr_be.be_ctx, how == GLW_CW ? REALITY_FRONT_FACE_CW : REALITY_FRONT_FACE_CCW); }
static void rsx_render_unlocked(glw_root_t *gr) { gcmContextData *ctx = gr->gr_be.be_ctx; const float *vertices = gr->gr_vertex_buffer; int current_blendmode = GLW_BLEND_NORMAL; realityBlendFunc(ctx, NV30_3D_BLEND_FUNC_SRC_RGB_SRC_ALPHA | NV30_3D_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA, NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA | NV30_3D_BLEND_FUNC_DST_ALPHA_ZERO); int current_frontface = GLW_CCW; realityFrontFace(ctx, REALITY_FRONT_FACE_CCW); for(int j = 0; j < gr->gr_num_render_jobs; j++) { const glw_render_order_t *ro = gr->gr_render_order + j; const glw_render_job_t *rj = ro->job; const struct glw_backend_texture *t0 = rj->t0; const struct glw_backend_texture *t1 = rj->t1; rsx_vp_t *rvp = gr->gr_be.be_vp_1; rsx_fp_t *rfp; float rgba[4]; if(unlikely(rj->gpa != NULL)) { glw_program_args_t *gpa = rj->gpa; if(t1 != NULL) { if(gpa->gpa_load_texture != NULL) { // Program has specialized code to load textures, run it gpa->gpa_load_texture(gr, gpa->gpa_prog, gpa->gpa_aux, t1, 1); } else { // not supported } } if(t0 != NULL) { if(gpa->gpa_load_texture != NULL) { // Program has specialized code to load textures, run it gpa->gpa_load_texture(gr, gpa->gpa_prog, gpa->gpa_aux, t0, 0); } else { // not supported } } rfp = gpa->gpa_prog->gp_fragment_program; rvp = gpa->gpa_prog->gp_vertex_program; rsx_set_vp(gr, rvp); if(gpa->gpa_load_uniforms != NULL) gpa->gpa_load_uniforms(gr, gpa->gpa_prog, gpa->gpa_aux, rj); } else { if(t0 == NULL) { if(t1 != NULL) { rfp = gr->gr_be.be_fp_flat_stencil; if(t1->tex.offset == 0 || t1->size == 0) continue; realitySetTexture(ctx, 0, &t1->tex); } else { rfp = gr->gr_be.be_fp_flat; } } else { if(t0->tex.offset == 0 || t0->size == 0) continue; const int doblur = rj->blur > 0.05 || rj->flags & GLW_RENDER_BLUR_ATTRIBUTE; realitySetTexture(ctx, 0, &t0->tex); if(t1 != NULL) { rfp = doblur ? gr->gr_be.be_fp_tex_stencil_blur : gr->gr_be.be_fp_tex_stencil; if(t1->tex.offset == 0 || t1->size == 0) continue; realitySetTexture(ctx, 1, &t1->tex); } else { rfp = doblur ? gr->gr_be.be_fp_tex_blur : gr->gr_be.be_fp_tex; } } rsx_set_vp(gr, rvp); } realitySetVertexProgramConstant4fBlock(ctx, rvp->rvp_binary, rvp->rvp_u_modelview, 4, rj->eyespace ? identitymtx : rj->m); const float alpha = rj->alpha; if(likely(rj->blendmode == GLW_BLEND_NORMAL)) { rgba[0] = rj->rgb_mul.r; rgba[1] = rj->rgb_mul.g; rgba[2] = rj->rgb_mul.b; rgba[3] = alpha; } else { rgba[0] = rj->rgb_mul.r * alpha; rgba[1] = rj->rgb_mul.g * alpha; rgba[2] = rj->rgb_mul.b * alpha; rgba[3] = 1; } if(likely(rvp->rvp_u_color != -1)) realitySetVertexProgramConstant4f(ctx, rvp->rvp_u_color, rgba); if(unlikely(current_blendmode != rj->blendmode)) { current_blendmode = rj->blendmode; switch(rj->blendmode) { case GLW_BLEND_ADDITIVE: realityBlendFunc(ctx, NV30_3D_BLEND_FUNC_SRC_RGB_SRC_COLOR, NV30_3D_BLEND_FUNC_DST_RGB_ONE); break; case GLW_BLEND_NORMAL: realityBlendFunc(ctx, NV30_3D_BLEND_FUNC_SRC_RGB_SRC_ALPHA | NV30_3D_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA, NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA | NV30_3D_BLEND_FUNC_DST_ALPHA_ZERO); break; } } if(unlikely(current_frontface != rj->frontface)) { current_frontface = rj->frontface; realityFrontFace(ctx, current_frontface == GLW_CW ? REALITY_FRONT_FACE_CW : REALITY_FRONT_FACE_CCW); } if(rvp->rvp_u_color_offset != -1) { rgba[0] = rj->rgb_off.r; rgba[1] = rj->rgb_off.g; rgba[2] = rj->rgb_off.b; rgba[3] = 0; realitySetVertexProgramConstant4f(ctx, rvp->rvp_u_color_offset, rgba); } if(rfp == gr->gr_be.be_fp_tex_blur) { float v[4]; v[0] = rj->blur; v[1] = 1.5 / t0->tex.width; v[2] = 1.5 / t0->tex.height; v[3] = 0; realitySetVertexProgramConstant4f(ctx, rvp->rvp_u_blur, v); } rsx_set_fp(gr, rfp); realityVertexBegin(ctx, rj->primitive_type); const float *v = &vertices[rj->vertex_offset * VERTEX_SIZE]; for(int i = 0; i < rj->num_vertices; i++) { realityAttr4f(ctx, rvp->rvp_a_texcoord, v[8], v[9], v[10], v[11]); if(unlikely(rvp->rvp_a_color) != -1) realityAttr4f(ctx, rvp->rvp_a_color, v[4], v[5], v[6], v[7]); realityVertex4f(ctx, v[0], v[1], v[2], v[3]); v+= VERTEX_SIZE; } realityVertexEnd(ctx); } }