void GPU_invalid_tex_init(void) { float color[4] = {1.0f, 0.0f, 1.0f, 1.0}; GG.invalid_tex_1D = GPU_texture_create_1D(1, color, NULL); GG.invalid_tex_2D = GPU_texture_create_2D(1, 1, color, NULL); GG.invalid_tex_3D = GPU_texture_create_3D(1, 1, 1, 4, color); }
GPUOffScreen *GPU_offscreen_create(int *width, int *height, char err_out[256]) { GPUOffScreen *ofs; ofs= MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen"); ofs->fb = GPU_framebuffer_create(); if(!ofs->fb) { GPU_offscreen_free(ofs); return NULL; } ofs->depth = GPU_texture_create_depth(*width, *height, err_out); if(!ofs->depth) { GPU_offscreen_free(ofs); return NULL; } if(*width!=ofs->depth->w || *height!=ofs->depth->h) { *width= ofs->depth->w; *height= ofs->depth->h; printf("Offscreen size differs from given size!\n"); } if(!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, err_out)) { GPU_offscreen_free(ofs); return NULL; } ofs->color = GPU_texture_create_2D(*width, *height, NULL, err_out); if(!ofs->color) { GPU_offscreen_free(ofs); return NULL; } if(!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, err_out)) { GPU_offscreen_free(ofs); return NULL; } GPU_framebuffer_restore(); return ofs; }
GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256]) { GPUOffScreen *ofs; ofs= MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen"); ofs->w= width; ofs->h= height; ofs->fb = GPU_framebuffer_create(); if (!ofs->fb) { GPU_offscreen_free(ofs); return NULL; } ofs->depth = GPU_texture_create_depth(width, height, err_out); if (!ofs->depth) { GPU_offscreen_free(ofs); return NULL; } if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, err_out)) { GPU_offscreen_free(ofs); return NULL; } ofs->color = GPU_texture_create_2D(width, height, NULL, err_out); if (!ofs->color) { GPU_offscreen_free(ofs); return NULL; } if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, err_out)) { GPU_offscreen_free(ofs); return NULL; } GPU_framebuffer_restore(); return ofs; }
bool GPU_fx_compositor_initialize_passes( GPUFX *fx, const rcti *rect, const rcti *scissor_rect, const GPUFXSettings *fx_settings) { int w = BLI_rcti_size_x(rect), h = BLI_rcti_size_y(rect); char err_out[256]; int num_passes = 0; char fx_flag; fx->effects = 0; if (!fx_settings) { cleanup_fx_gl_data(fx, true); return false; } fx_flag = fx_settings->fx_flag; /* disable effects if no options passed for them */ if (!fx_settings->dof) { fx_flag &= ~GPU_FX_FLAG_DOF; } if (!fx_settings->ssao || fx_settings->ssao->samples < 1) { fx_flag &= ~GPU_FX_FLAG_SSAO; } if (!fx_flag) { cleanup_fx_gl_data(fx, true); return false; } /* scissor is missing when drawing offscreen, in that case, dimensions match exactly. In opposite case * add one to match viewport dimensions */ if (scissor_rect) { w++, h++; } fx->num_passes = 0; /* dof really needs a ping-pong buffer to work */ if (fx_flag & GPU_FX_FLAG_DOF) num_passes++; if (fx_flag & GPU_FX_FLAG_SSAO) num_passes++; if (!fx->gbuffer) fx->gbuffer = GPU_framebuffer_create(); /* try creating the jitter texture */ if (!fx->jitter_buffer) fx->jitter_buffer = create_jitter_texture(); if (!fx->gbuffer) return false; /* check if color buffers need recreation */ if (!fx->color_buffer || !fx->depth_buffer || w != fx->gbuffer_dim[0] || h != fx->gbuffer_dim[1]) { cleanup_fx_gl_data(fx, false); if (!(fx->color_buffer = GPU_texture_create_2D(w, h, NULL, GPU_HDR_NONE, err_out))) { printf(".256%s\n", err_out); cleanup_fx_gl_data(fx, true); return false; } if (!(fx->depth_buffer = GPU_texture_create_depth(w, h, err_out))) { printf("%.256s\n", err_out); cleanup_fx_gl_data(fx, true); return false; } } if (fx_flag & GPU_FX_FLAG_SSAO) { if (fx_settings->ssao->samples != fx->ssao_sample_count || !fx->ssao_concentric_samples_tex) { if (fx_settings->ssao->samples < 1) fx_settings->ssao->samples = 1; fx->ssao_sample_count = fx_settings->ssao->samples; if (fx->ssao_concentric_samples_tex) { GPU_texture_free(fx->ssao_concentric_samples_tex); } fx->ssao_concentric_samples_tex = create_spiral_sample_texture(fx_settings->ssao->samples); } } else { if (fx->ssao_concentric_samples_tex) { GPU_texture_free(fx->ssao_concentric_samples_tex); fx->ssao_concentric_samples_tex = NULL; } } /* create textures for dof effect */ if (fx_flag & GPU_FX_FLAG_DOF) { if (!fx->dof_near_coc_buffer || !fx->dof_near_coc_blurred_buffer || !fx->dof_near_coc_final_buffer) { fx->dof_downsampled_w = w / 4; fx->dof_downsampled_h = h / 4; if (!(fx->dof_near_coc_buffer = GPU_texture_create_2D( fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_NONE, err_out))) { printf("%.256s\n", err_out); cleanup_fx_gl_data(fx, true); return false; } if (!(fx->dof_near_coc_blurred_buffer = GPU_texture_create_2D( fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_NONE, err_out))) { printf("%.256s\n", err_out); cleanup_fx_gl_data(fx, true); return false; } if (!(fx->dof_near_coc_final_buffer = GPU_texture_create_2D( fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_NONE, err_out))) { printf("%.256s\n", err_out); cleanup_fx_gl_data(fx, true); return false; } } } else { /* cleanup unnecessary buffers */ cleanup_fx_dof_buffers(fx); } /* we need to pass data between shader stages, allocate an extra color buffer */ if (num_passes > 1) { if(!fx->color_buffer_sec) { if (!(fx->color_buffer_sec = GPU_texture_create_2D(w, h, NULL, GPU_HDR_NONE, err_out))) { printf(".256%s\n", err_out); cleanup_fx_gl_data(fx, true); return false; } } } else { if (fx->color_buffer_sec) { GPU_framebuffer_texture_detach(fx->color_buffer_sec); GPU_texture_free(fx->color_buffer_sec); fx->color_buffer_sec = NULL; } } /* bind the buffers */ /* first depth buffer, because system assumes read/write buffers */ if(!GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, err_out)) printf("%.256s\n", err_out); if(!GPU_framebuffer_texture_attach(fx->gbuffer, fx->color_buffer, 0, err_out)) printf("%.256s\n", err_out); if(!GPU_framebuffer_check_valid(fx->gbuffer, err_out)) printf("%.256s\n", err_out); GPU_texture_bind_as_framebuffer(fx->color_buffer); /* enable scissor test. It's needed to ensure sculpting works correctly */ if (scissor_rect) { int w_sc = BLI_rcti_size_x(scissor_rect) + 1; int h_sc = BLI_rcti_size_y(scissor_rect) + 1; glPushAttrib(GL_SCISSOR_BIT); glEnable(GL_SCISSOR_TEST); glScissor(scissor_rect->xmin - rect->xmin, scissor_rect->ymin - rect->ymin, w_sc, h_sc); fx->restore_stencil = true; } else { fx->restore_stencil = false; } fx->effects = fx_flag; if (fx_settings) fx->settings = *fx_settings; fx->gbuffer_dim[0] = w; fx->gbuffer_dim[1] = h; fx->num_passes = num_passes; return true; }
static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type) { GPUInput *input; GPUNode *outnode; const char *name; if (link->output) { outnode = link->output->node; name = outnode->name; if (strcmp(name, "set_value")==0 || strcmp(name, "set_rgb")==0) { input = MEM_dupallocN(outnode->inputs.first); input->type = type; if (input->link) input->link->users++; BLI_addtail(&node->inputs, input); return; } } input = MEM_callocN(sizeof(GPUInput), "GPUInput"); input->node = node; if (link->builtin) { /* builtin uniform */ input->type = type; input->source = GPU_SOURCE_BUILTIN; input->builtin = link->builtin; MEM_freeN(link); } else if (link->output) { /* link to a node output */ input->type = type; input->source = GPU_SOURCE_TEX_PIXEL; input->link = link; link->users++; } else if (link->dynamictex) { /* dynamic texture, GPUTexture is updated/deleted externally */ input->type = type; input->source = GPU_SOURCE_TEX; input->tex = link->dynamictex; input->textarget = GL_TEXTURE_2D; input->textype = type; input->dynamictex = 1; input->dynamicdata = link->ptr2; MEM_freeN(link); } else if (link->texture) { /* small texture created on the fly, like for colorbands */ input->type = GPU_VEC4; input->source = GPU_SOURCE_TEX; input->textype = type; //input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL); input->tex = GPU_texture_create_2D(link->texturesize, 1, link->ptr1, NULL); input->textarget = GL_TEXTURE_2D; MEM_freeN(link->ptr1); MEM_freeN(link); } else if (link->image) { /* blender image */ input->type = GPU_VEC4; input->source = GPU_SOURCE_TEX; if (link->image == LINK_IMAGE_PREVIEW) input->prv = link->ptr1; else { input->ima = link->ptr1; input->iuser = link->ptr2; input->image_isdata = link->image_isdata; } input->textarget = GL_TEXTURE_2D; input->textype = GPU_TEX2D; MEM_freeN(link); } else if (link->attribtype) { /* vertex attribute */ input->type = type; input->source = GPU_SOURCE_ATTRIB; input->attribtype = link->attribtype; BLI_strncpy(input->attribname, link->attribname, sizeof(input->attribname)); MEM_freeN(link); } else { /* uniform vector */ input->type = type; input->source = GPU_SOURCE_VEC_UNIFORM; memcpy(input->vec, link->ptr1, type*sizeof(float)); if (link->dynamic) { input->dynamicvec= link->ptr1; input->dynamictype= link->dynamictype; input->dynamicdata= link->ptr2; } MEM_freeN(link); } BLI_addtail(&node->inputs, input); }