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;
	}
}
示例#2
0
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);
}