void R_InitFBObjects (void) { unsigned int filters[2]; float scales[DOWNSAMPLE_PASSES]; int i; if (!r_config.frameBufferObject || !r_programs->integer) return; frameBufferObjectCount = 0; OBJZERO(frameBufferObjects); OBJZERO(frameBufferTextures); r_state.frameBufferObjectsInitialized = true; for (i = 0; i < DOWNSAMPLE_PASSES; i++) scales[i] = powf(DOWNSAMPLE_SCALE, i + 1); /* setup default screen framebuffer */ screenBuffer.fbo = 0; screenBuffer.depth = 0; screenBuffer.nTextures = 0; screenBuffer.width = viddef.context.width; screenBuffer.height = viddef.context.height; R_SetupViewport(&screenBuffer, 0, 0, viddef.context.width, viddef.context.height); Vector4Clear(screenBuffer.clearColor); /* use default framebuffer */ qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); r_state.activeFramebuffer = &screenBuffer; colorAttachments = Mem_AllocTypeN(GLenum, r_config.maxDrawBuffers); for (i = 0; i < r_config.maxDrawBuffers; i++) colorAttachments[i] = GL_COLOR_ATTACHMENT0_EXT + i; filters[0] = GL_NEAREST; filters[1] = GL_LINEAR_MIPMAP_LINEAR; /* setup main 3D render target */ r_state.renderBuffer = R_CreateFramebuffer(viddef.context.width, viddef.context.height, 2, true, false, filters); /* setup bloom render targets */ fbo_bloom0 = R_CreateFramebuffer(viddef.context.width, viddef.context.height, 1, false, false, filters); fbo_bloom1 = R_CreateFramebuffer(viddef.context.width, viddef.context.height, 1, false, false, filters); filters[0] = GL_LINEAR; /* setup extra framebuffers */ for (i = 0; i < DOWNSAMPLE_PASSES; i++) { const int h = (int)((float)viddef.context.height / scales[i]); const int w = (int)((float)viddef.context.width / scales[i]); r_state.buffers0[i] = R_CreateFramebuffer(w, h, 1, false, false, filters); r_state.buffers1[i] = R_CreateFramebuffer(w, h, 1, false, false, filters); r_state.buffers2[i] = R_CreateFramebuffer(w, h, 1, false, false, filters); R_CheckError(); } }
/** * @brief Allocate handles for the stainmap */ static void R_AllocStainmap_(const uint32_t width, const uint32_t height, r_stainmap_t *out) { out->image = R_AllocLightmap_(IT_STAINMAP, width, height); R_UploadImage(out->image, GL_RGBA, NULL); out->fb = R_CreateFramebuffer(va("%s_fb", out->image->media.name)); R_AttachFramebufferImage(out->fb, out->image); if (!R_FramebufferReady(out->fb)) { Com_Warn("Unable to allocate a stainmap framebuffer"); memset(out, 0, sizeof(r_stainmap_t)); } Matrix4x4_FromOrtho(&out->projection, 0.0, width, height, 0.0, -1.0, 1.0); R_BindFramebuffer(FRAMEBUFFER_DEFAULT); }