void drawFrame(int buffer, long frame) { realityViewportTranslate(context, 0.0, 0.0, 0.0, 0.0); realityViewportScale(context, 1.0, 1.0, 1.0, 0.0); realityZControl(context, 0, 1, 1); // disable viewport culling // Enable alpha blending. realityBlendFunc(context, 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(context, NV40_3D_BLEND_EQUATION_RGB_FUNC_ADD | NV40_3D_BLEND_EQUATION_ALPHA_FUNC_ADD); realityBlendEnable(context, 1); realityViewport(context, res.width, res.height); setupRenderTarget(buffer); // set the clear color realitySetClearColor(context, 0x00000000); // Black, because it looks cool // and the depth clear value realitySetClearDepthValue(context, 0xffff); // Clear the buffers realityClearBuffers(context, REALITY_CLEAR_BUFFERS_COLOR_R | REALITY_CLEAR_BUFFERS_COLOR_G | REALITY_CLEAR_BUFFERS_COLOR_B | NV30_3D_CLEAR_BUFFERS_COLOR_A | NV30_3D_CLEAR_BUFFERS_STENCIL | REALITY_CLEAR_BUFFERS_DEPTH); // Load shaders, because the rsx won't do anything without them. realityLoadVertexProgram_old(context, &nv40_vp); realityLoadFragmentProgram_old(context, &nv30_fp); // Load texture load_tex(0, tx_offset, dice.width, dice.height, dice.width*4, NV40_3D_TEX_FORMAT_FORMAT_A8R8G8B8, 1); // Generate quad realityVertexBegin(context, REALITY_QUADS); { realityTexCoord2f(context, 0.0, 0.0); realityVertex4f(context, 600.0, 300.0, 0.0, 1.0); realityTexCoord2f(context, 1.0, 0.0); realityVertex4f(context, 1400.0, 300.0, 0.0, 1.0); realityTexCoord2f(context, 1.0, 1.0); realityVertex4f(context, 1400.0, 900.0, 0.0, 1.0); realityTexCoord2f(context, 0.0, 1.0); realityVertex4f(context, 600.0, 900.0, 0.0, 1.0); } realityVertexEnd(context); }
/** * Video widget render */ static void render_video_quad(int interlace, int width, int height, int bob1, int bob2, glw_root_t *root, rsx_fp_t *rfp, const glw_video_t *gv, glw_rctx_t *rc) { glw_backend_root_t *be = &root->gr_be; gcmContextData *ctx = be->be_ctx; rsx_vp_t *rvp = be->be_vp_yuv2rgb; float x1, x2, y1, y2; float b1 = 0, b2 = 0; const int bordersize = 0; float rgba[4]; float tc[12]; if(interlace) { x1 = 0 + (bordersize / (float)width); y1 = 0 + (bordersize / (float)height); x2 = 1 - (bordersize / (float)width); y2 = 1 - (bordersize / (float)height); b1 = (0.5 * bob1) / (float)height; b2 = (0.5 * bob2) / (float)height; } else { x1 = 0; y1 = 0; x2 = 1; y2 = 1; } tc[0] = x1; tc[1] = y2 - b1; tc[2] = y2 - b2; tc[3] = x2; tc[4] = y2 - b1; tc[5] = y2 - b2; tc[6] = x2; tc[7] = y1 - b1; tc[8] = y1 - b2; tc[9] = x1; tc[10] = y1 - b1; tc[11] = y1 - b2; rsx_set_vp(root, rvp); realitySetVertexProgramConstant4fBlock(ctx, rvp->rvp_binary, rvp->rvp_u_modelview, 4, rc->rc_mtx); if(rfp->rfp_u_color != -1) { rgba[0] = 0; rgba[1] = 0; rgba[2] = 0; rgba[3] = rc->rc_alpha; realitySetFragmentProgramParameter(ctx, rfp->rfp_binary, rfp->rfp_u_color, rgba, rfp->rfp_rsx_location); } if(rfp->rfp_u_blend != -1) { rgba[0] = gv->gv_blend; rgba[1] = 0; rgba[2] = 0; rgba[3] = 0; realitySetFragmentProgramParameter(ctx, rfp->rfp_binary, rfp->rfp_u_blend, rgba, rfp->rfp_rsx_location); } if(rfp->rfp_u_color_matrix != -1) realitySetFragmentProgramParameter(ctx, rfp->rfp_binary, rfp->rfp_u_color_matrix, gv->gv_cmatrix_cur, rfp->rfp_rsx_location); rsx_set_fp(root, rfp, 1); realityVertexBegin(ctx, REALITY_QUADS); realityAttr4f(ctx, rvp->rvp_a_texcoord, tc[0], tc[1], tc[2], 0); realityVertex4f(ctx, -1, -1, 0, 1); realityAttr4f(ctx, rvp->rvp_a_texcoord, tc[3], tc[4], tc[5], 0); realityVertex4f(ctx, 1, -1, 0, 1); realityAttr4f(ctx, rvp->rvp_a_texcoord, tc[6], tc[7], tc[8], 0); realityVertex4f(ctx, 1, 1, 0, 1); realityAttr4f(ctx, rvp->rvp_a_texcoord, tc[9], tc[10], tc[11], 0); realityVertex4f(ctx, -1, 1, 0, 1); realityVertexEnd(ctx); }
static void rsx_render(struct glw_root *gr, Mtx m, struct glw_backend_texture *tex, const struct glw_rgb *rgb_mul, const struct glw_rgb *rgb_off, float alpha, float blur, const float *vertices, int num_vertices, const uint16_t *indices, int num_triangles, int flags) { gcmContextData *ctx = gr->gr_be.be_ctx; rsx_vp_t *rvp = gr->gr_be.be_vp_1; rsx_fp_t *rfp; float rgba[4]; if(tex == NULL) { rfp = gr->gr_be.be_fp_flat; } else { if(tex->tex.offset == 0 || tex->size == 0) return; realitySetTexture(ctx, 0, &tex->tex); if(blur > 0.05) { rfp = gr->gr_be.be_fp_tex_blur; } else { rfp = gr->gr_be.be_fp_tex; } } rsx_set_vp(gr, rvp); realitySetVertexProgramConstant4fBlock(ctx, rvp->rvp_binary, rvp->rvp_u_modelview, 4, m ?: identitymtx); switch(gr->gr_be.be_blendmode) { case GLW_BLEND_NORMAL: rgba[0] = rgb_mul->r; rgba[1] = rgb_mul->g; rgba[2] = rgb_mul->b; rgba[3] = alpha; break; case GLW_BLEND_ADDITIVE: rgba[0] = rgb_mul->r * alpha; rgba[1] = rgb_mul->g * alpha; rgba[2] = rgb_mul->b * alpha; rgba[3] = 1; break; } realitySetVertexProgramConstant4f(ctx, rvp->rvp_u_color, rgba); if(rvp->rvp_u_color_offset != -1) { if(rgb_off != NULL) { rgba[0] = rgb_off->r; rgba[1] = rgb_off->g; rgba[2] = rgb_off->b; } else { rgba[0] = 0; rgba[1] = 0; rgba[2] = 0; } rgba[3] = 0; realitySetVertexProgramConstant4f(ctx, rvp->rvp_u_color_offset, rgba); } if(blur > 0.05 && tex != NULL) { float v[4]; v[0] = 1.5 * blur / tex->tex.width; v[1] = 1.5 * blur / tex->tex.height; v[2] = 0; v[3] = 0; realitySetVertexProgramConstant4f(ctx, rvp->rvp_u_blur_amount, v); } rsx_set_fp(gr, rfp, 0); // TODO: Get rid of immediate mode realityVertexBegin(ctx, REALITY_TRIANGLES); int i; if(indices != NULL) { for(i = 0; i < num_triangles * 3; i++) { const float *v = &vertices[indices[i] * VERTEX_SIZE]; realityAttr2f(ctx, rvp->rvp_a_texcoord, v[3], v[4]); realityAttr4f(ctx, rvp->rvp_a_color, v[5], v[6], v[7], v[8]); realityVertex4f(ctx, v[0], v[1], v[2], 1); } } else { for(i = 0; i < num_vertices; i++) { const float *v = &vertices[i * VERTEX_SIZE]; realityAttr2f(ctx, rvp->rvp_a_texcoord, v[3], v[4]); realityAttr4f(ctx, rvp->rvp_a_color, v[5], v[6], v[7], v[8]); realityVertex4f(ctx, v[0], v[1], v[2], 1); } } realityVertexEnd(ctx); }
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); } }
static void rsx_render(struct glw_root *gr, const Mtx m, const struct glw_backend_texture *t0, const struct glw_backend_texture *t1, const struct glw_rgb *rgb_mul, const struct glw_rgb *rgb_off, float alpha, float blur, const float *vertices, int num_vertices, const uint16_t *indices, int num_triangles, int flags, glw_program_t *p, const glw_rctx_t *rc) { gcmContextData *ctx = gr->gr_be.be_ctx; rsx_vp_t *rvp = gr->gr_be.be_vp_1; rsx_fp_t *rfp; float rgba[4]; if(t0 == NULL) { if(t1 != NULL) { rfp = gr->gr_be.be_fp_flat_stencil; if(t1->tex.offset == 0 || t1->size == 0) return; realitySetTexture(ctx, 0, &t1->tex); } else { rfp = gr->gr_be.be_fp_flat; } } else { if(t0->tex.offset == 0 || t0->size == 0) return; const int doblur = blur > 0.05 || 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) return; 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, m ?: identitymtx); switch(gr->gr_be.be_blendmode) { case GLW_BLEND_NORMAL: rgba[0] = rgb_mul->r; rgba[1] = rgb_mul->g; rgba[2] = rgb_mul->b; rgba[3] = alpha; break; case GLW_BLEND_ADDITIVE: rgba[0] = rgb_mul->r * alpha; rgba[1] = rgb_mul->g * alpha; rgba[2] = rgb_mul->b * alpha; rgba[3] = 1; break; } realitySetVertexProgramConstant4f(ctx, rvp->rvp_u_color, rgba); if(rvp->rvp_u_color_offset != -1) { if(rgb_off != NULL) { rgba[0] = rgb_off->r; rgba[1] = rgb_off->g; rgba[2] = rgb_off->b; } else { rgba[0] = 0; rgba[1] = 0; rgba[2] = 0; } 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] = 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, 0); // TODO: Get rid of immediate mode realityVertexBegin(ctx, REALITY_TRIANGLES); int i; if(indices != NULL) { for(i = 0; i < num_triangles * 3; i++) { const float *v = &vertices[indices[i] * VERTEX_SIZE]; realityAttr4f(ctx, rvp->rvp_a_texcoord, v[8], v[9], v[10], v[11]); realityAttr4f(ctx, rvp->rvp_a_color, v[4], v[5], v[6], v[7]); realityVertex4f(ctx, v[0], v[1], v[2], v[3]); } } else { for(i = 0; i < num_vertices; i++) { const float *v = &vertices[i * VERTEX_SIZE]; realityAttr4f(ctx, rvp->rvp_a_texcoord, v[8], v[9], v[10], v[11]); realityAttr4f(ctx, rvp->rvp_a_color, v[4], v[5], v[6], v[7]); realityVertex4f(ctx, v[0], v[1], v[2], v[3]); } } realityVertexEnd(ctx); }