void GLES_GPU::SetRenderFrameBuffer() { if (!g_Config.bBufferedRendering) return; // Get parameters u32 fb_address = (gstate.fbptr & 0xFFE000) | ((gstate.fbwidth & 0xFF0000) << 8); int fb_stride = gstate.fbwidth & 0x3C0; u32 z_address = (gstate.zbptr & 0xFFE000) | ((gstate.zbwidth & 0xFF0000) << 8); int z_stride = gstate.zbwidth & 0x3C0; // Yeah this is not completely right. but it'll do for now. int drawing_width = ((gstate.region2) & 0x3FF) + 1; int drawing_height = ((gstate.region2 >> 10) & 0x3FF) + 1; int fmt = gstate.framebufpixformat & 3; // Find a matching framebuffer VirtualFramebuffer *vfb = 0; for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) { VirtualFramebuffer *v = *iter; if (v->fb_address == fb_address) { // Let's not be so picky for now. Let's say this is the one. vfb = v; // Update fb stride in case it changed vfb->fb_stride = fb_stride; break; } } // None found? Create one. if (!vfb) { vfb = new VirtualFramebuffer; vfb->fb_address = fb_address; vfb->fb_stride = fb_stride; vfb->z_address = z_address; vfb->z_stride = z_stride; vfb->width = drawing_width; vfb->height = drawing_height; vfb->format = fmt; vfb->fbo = fbo_create(vfb->width * widthFactor_, vfb->height * heightFactor_, 1, true); vfbs_.push_back(vfb); fbo_bind_as_render_target(vfb->fbo); glViewport(0, 0, renderWidth_, renderHeight_); currentRenderVfb_ = vfb; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); DEBUG_LOG(HLE, "Creating FBO for %08x", vfb->fb_address); return; } if (vfb != currentRenderVfb_) { // Use it as a render target. DEBUG_LOG(HLE, "Switching to FBO for %08x", vfb->fb_address); fbo_bind_as_render_target(vfb->fbo); glViewport(0, 0, renderWidth_, renderHeight_); currentRenderVfb_ = vfb; } }
void hmd_common_init(int w, int h) { /* Create the off-screen frame buffers. */ fbo_create(&L_fbo, 5 * w / 4 / 2, 5 * h / 4); fbo_create(&R_fbo, 5 * w / 4 / 2, 5 * h / 4); /* Create and initialize the distortion shader. */ glsl_create(&distortion, sizeof (hmd_vert) / sizeof (char *), hmd_vert, sizeof (hmd_frag) / sizeof (char *), hmd_frag); /* Initialize VBOs for the on-screen rectangles. */ glGenBuffers_(1, &L_vbo); glBindBuffer_(GL_ARRAY_BUFFER, L_vbo); glBufferData_(GL_ARRAY_BUFFER, sizeof (L_rect), L_rect, GL_STATIC_DRAW); glGenBuffers_(1, &R_vbo); glBindBuffer_(GL_ARRAY_BUFFER, R_vbo); glBufferData_(GL_ARRAY_BUFFER, sizeof (R_rect), R_rect, GL_STATIC_DRAW); glBindBuffer_(GL_ARRAY_BUFFER, 0); }