/* Init Textures, Framebuffers, Storage and Shaders. * It is called for every frames. * (Optional) */ static void EDIT_TEXT_engine_init(void *vedata) { EDIT_TEXT_TextureList *txl = ((EDIT_TEXT_Data *)vedata)->txl; EDIT_TEXT_FramebufferList *fbl = ((EDIT_TEXT_Data *)vedata)->fbl; EDIT_TEXT_StorageList *stl = ((EDIT_TEXT_Data *)vedata)->stl; UNUSED_VARS(txl, fbl, stl); /* Init Framebuffers like this: order is attachment order (for color texs) */ /* * DRWFboTexture tex[2] = {{&txl->depth, GPU_DEPTH_COMPONENT24, 0}, * {&txl->color, GPU_RGBA8, DRW_TEX_FILTER}}; */ /* DRW_framebuffer_init takes care of checking if * the framebuffer is valid and has the right size*/ /* * float *viewport_size = DRW_viewport_size_get(); * DRW_framebuffer_init(&fbl->occlude_wire_fb, * (int)viewport_size[0], (int)viewport_size[1], * tex, 2); */ if (!e_data.wire_sh) { e_data.wire_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); } if (!e_data.overlay_select_sh) { e_data.overlay_select_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); } if (!e_data.overlay_cursor_sh) { e_data.overlay_cursor_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); } }
void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *blurfb, GPUTexture *blurtex) { float scaleh[2] = {1.0f/GPU_texture_opengl_width(blurtex), 0.0f}; float scalev[2] = {0.0f, 1.0f/GPU_texture_opengl_height(tex)}; GPUShader *blur_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SEP_GAUSSIAN_BLUR); int scale_uniform, texture_source_uniform; if (!blur_shader) return; scale_uniform = GPU_shader_get_uniform(blur_shader, "ScaleU"); texture_source_uniform = GPU_shader_get_uniform(blur_shader, "textureSource"); /* Blurring horizontally */ /* We do the bind ourselves rather than using GPU_framebuffer_texture_bind() to avoid * pushing unnecessary matrices onto the OpenGL stack. */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, blurfb->object); GPU_shader_bind(blur_shader); GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float *)scaleh); GPU_shader_uniform_texture(blur_shader, texture_source_uniform, tex); glViewport(0, 0, GPU_texture_opengl_width(blurtex), GPU_texture_opengl_height(blurtex)); /* Peparing to draw quad */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); GPU_texture_bind(tex, 0); /* Drawing quad */ glBegin(GL_QUADS); glTexCoord2d(0, 0); glVertex2f(1, 1); glTexCoord2d(1, 0); glVertex2f(-1, 1); glTexCoord2d(1, 1); glVertex2f(-1, -1); glTexCoord2d(0, 1); glVertex2f(1, -1); glEnd(); /* Blurring vertically */ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object); glViewport(0, 0, GPU_texture_opengl_width(tex), GPU_texture_opengl_height(tex)); GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float *)scalev); GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex); GPU_texture_bind(blurtex, 0); glBegin(GL_QUADS); glTexCoord2d(0, 0); glVertex2f(1, 1); glTexCoord2d(1, 0); glVertex2f(-1, 1); glTexCoord2d(1, 1); glVertex2f(-1, -1); glTexCoord2d(0, 1); glVertex2f(1, -1); glEnd(); GPU_shader_unbind(); }
void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, const float min[3], const float max[3], const float viewnormal[3]) { if (!sds->tex || !sds->tex_shadow) { fprintf(stderr, "Could not allocate 3D texture for volume rendering!\n"); return; } const bool use_fire = (sds->active_fields & SM_ACTIVE_FIRE) && sds->tex_flame; GPUShader *shader = GPU_shader_get_builtin_shader( (use_fire) ? GPU_SHADER_SMOKE_FIRE : GPU_SHADER_SMOKE); if (!shader) { fprintf(stderr, "Unable to create GLSL smoke shader.\n"); return; } const float ob_sizei[3] = { 1.0f / fabsf(ob->size[0]), 1.0f / fabsf(ob->size[1]), 1.0f / fabsf(ob->size[2]) }; const float size[3] = { max[0] - min[0], max[1] - min[1], max[2] - min[2] }; const float invsize[3] = { 1.0f / size[0], 1.0f / size[1], 1.0f / size[2] }; #ifdef DEBUG_DRAW_TIME TIMEIT_START(draw); #endif /* setup smoke shader */ int soot_location = GPU_shader_get_uniform(shader, "soot_texture"); int spec_location = GPU_shader_get_uniform(shader, "spectrum_texture"); int shadow_location = GPU_shader_get_uniform(shader, "shadow_texture"); int flame_location = GPU_shader_get_uniform(shader, "flame_texture"); int actcol_location = GPU_shader_get_uniform(shader, "active_color"); int stepsize_location = GPU_shader_get_uniform(shader, "step_size"); int densityscale_location = GPU_shader_get_uniform(shader, "density_scale"); int invsize_location = GPU_shader_get_uniform(shader, "invsize"); int ob_sizei_location = GPU_shader_get_uniform(shader, "ob_sizei"); int min_location = GPU_shader_get_uniform(shader, "min"); GPU_shader_bind(shader); GPU_texture_bind(sds->tex, 0); GPU_shader_uniform_texture(shader, soot_location, sds->tex); GPU_texture_bind(sds->tex_shadow, 1); GPU_shader_uniform_texture(shader, shadow_location, sds->tex_shadow); GPUTexture *tex_spec = NULL; if (use_fire) { GPU_texture_bind(sds->tex_flame, 2); GPU_shader_uniform_texture(shader, flame_location, sds->tex_flame); tex_spec = create_flame_spectrum_texture(); GPU_texture_bind(tex_spec, 3); GPU_shader_uniform_texture(shader, spec_location, tex_spec); } float active_color[3] = { 0.9, 0.9, 0.9 }; float density_scale = 10.0f; if ((sds->active_fields & SM_ACTIVE_COLORS) == 0) mul_v3_v3(active_color, sds->active_color); GPU_shader_uniform_vector(shader, actcol_location, 3, 1, active_color); GPU_shader_uniform_vector(shader, stepsize_location, 1, 1, &sds->dx); GPU_shader_uniform_vector(shader, densityscale_location, 1, 1, &density_scale); GPU_shader_uniform_vector(shader, min_location, 3, 1, min); GPU_shader_uniform_vector(shader, ob_sizei_location, 3, 1, ob_sizei); GPU_shader_uniform_vector(shader, invsize_location, 3, 1, invsize); /* setup slicing information */ const int max_slices = 256; const int max_points = max_slices * 12; VolumeSlicer slicer; copy_v3_v3(slicer.min, min); copy_v3_v3(slicer.max, max); copy_v3_v3(slicer.size, size); slicer.verts = MEM_mallocN(sizeof(float) * 3 * max_points, "smoke_slice_vertices"); const int num_points = create_view_aligned_slices(&slicer, max_slices, viewnormal); /* setup buffer and draw */ int gl_depth = 0, gl_blend = 0; glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); GLuint vertex_buffer; glGenBuffers(1, &vertex_buffer); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * num_points, &slicer.verts[0][0], GL_STATIC_DRAW); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, NULL); glDrawArrays(GL_TRIANGLES, 0, num_points); glDisableClientState(GL_VERTEX_ARRAY); #ifdef DEBUG_DRAW_TIME printf("Draw Time: %f\n", (float)TIMEIT_VALUE(draw)); TIMEIT_END(draw); #endif /* cleanup */ glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &vertex_buffer); GPU_texture_unbind(sds->tex); GPU_texture_unbind(sds->tex_shadow); if (use_fire) { GPU_texture_unbind(sds->tex_flame); GPU_texture_unbind(tex_spec); GPU_texture_free(tex_spec); } MEM_freeN(slicer.verts); GPU_shader_unbind(); if (!gl_blend) { glDisable(GL_BLEND); } if (gl_depth) { glEnable(GL_DEPTH_TEST); } }
void DRW_draw_cursor(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); ARegion *ar = draw_ctx->ar; Scene *scene = draw_ctx->scene; ViewLayer *view_layer = draw_ctx->view_layer; glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); if (is_cursor_visible(draw_ctx, scene, view_layer)) { int co[2]; /* Get cursor data into quaternion form */ const View3DCursor *cursor = &scene->cursor; if (ED_view3d_project_int_global( ar, cursor->location, co, V3D_PROJ_TEST_NOP | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) { RegionView3D *rv3d = ar->regiondata; float cursor_quat[4]; BKE_scene_cursor_rot_to_quat(cursor, cursor_quat); /* Draw nice Anti Aliased cursor. */ GPU_line_width(1.0f); GPU_blend(true); GPU_line_smooth(true); float eps = 1e-5f; rv3d->viewquat[0] = -rv3d->viewquat[0]; bool is_aligned = compare_v4v4(cursor_quat, rv3d->viewquat, eps); if (is_aligned == false) { float tquat[4]; rotation_between_quats_to_quat(tquat, rv3d->viewquat, cursor_quat); is_aligned = tquat[0] - eps < -1.0f; } rv3d->viewquat[0] = -rv3d->viewquat[0]; /* Draw lines */ if (is_aligned == false) { uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColor3(TH_VIEW_OVERLAY); immBegin(GPU_PRIM_LINES, 12); const float scale = ED_view3d_pixel_size_no_ui_scale(rv3d, cursor->location) * U.widget_unit; #define CURSOR_VERT(axis_vec, axis, fac) \ immVertex3f(pos, \ cursor->location[0] + axis_vec[0] * (fac), \ cursor->location[1] + axis_vec[1] * (fac), \ cursor->location[2] + axis_vec[2] * (fac)) #define CURSOR_EDGE(axis_vec, axis, sign) \ { \ CURSOR_VERT(axis_vec, axis, sign 1.0f); \ CURSOR_VERT(axis_vec, axis, sign 0.25f); \ } \ ((void)0) for (int axis = 0; axis < 3; axis++) { float axis_vec[3] = {0}; axis_vec[axis] = scale; mul_qt_v3(cursor_quat, axis_vec); CURSOR_EDGE(axis_vec, axis, +); CURSOR_EDGE(axis_vec, axis, -); } #undef CURSOR_VERT #undef CURSOR_EDGE immEnd(); immUnbindProgram(); } float original_proj[4][4]; GPU_matrix_projection_get(original_proj); GPU_matrix_push(); ED_region_pixelspace(ar); GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f); GPU_matrix_scale_2f(U.widget_unit, U.widget_unit); GPUBatch *cursor_batch = DRW_cache_cursor_get(is_aligned); GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR); GPU_batch_program_set( cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader)); GPU_batch_draw(cursor_batch); GPU_blend(false); GPU_line_smooth(false); GPU_matrix_pop(); GPU_matrix_projection_set(original_proj); }
void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, const float min[3], const float max[3], const float viewnormal[3]) { if (!sds->tex || !sds->tex_shadow) { fprintf(stderr, "Could not allocate 3D texture for volume rendering!\n"); return; } const bool use_fire = (sds->active_fields & SM_ACTIVE_FIRE) && sds->tex_flame; GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_SMOKE); if (!shader) { fprintf(stderr, "Unable to create GLSL smoke shader.\n"); return; } GPUShader *fire_shader = NULL; if (use_fire) { fire_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SMOKE_FIRE); if (!fire_shader) { fprintf(stderr, "Unable to create GLSL fire shader.\n"); return; } } const float ob_sizei[3] = { 1.0f / fabsf(ob->size[0]), 1.0f / fabsf(ob->size[1]), 1.0f / fabsf(ob->size[2]) }; const float size[3] = { max[0] - min[0], max[1] - min[1], max[2] - min[2] }; const float invsize[3] = { 1.0f / size[0], 1.0f / size[1], 1.0f / size[2] }; #ifdef DEBUG_DRAW_TIME TIMEIT_START(draw); #endif /* setup slicing information */ const int max_slices = 256; const int max_points = max_slices * 12; VolumeSlicer slicer; copy_v3_v3(slicer.min, min); copy_v3_v3(slicer.max, max); copy_v3_v3(slicer.size, size); slicer.verts = MEM_mallocN(sizeof(float) * 3 * max_points, "smoke_slice_vertices"); const int num_points = create_view_aligned_slices(&slicer, max_slices, viewnormal); /* setup buffer and draw */ int gl_depth = 0, gl_blend = 0, gl_depth_write = 0; glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); glGetBooleanv(GL_DEPTH_WRITEMASK, (GLboolean *)&gl_depth_write); glEnable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); draw_buffer(sds, shader, &slicer, ob_sizei, invsize, num_points, false); /* Draw fire separately (T47639). */ if (use_fire) { glBlendFunc(GL_ONE, GL_ONE); draw_buffer(sds, fire_shader, &slicer, ob_sizei, invsize, num_points, true); } #ifdef DEBUG_DRAW_TIME printf("Draw Time: %f\n", (float)TIMEIT_VALUE(draw)); TIMEIT_END(draw); #endif MEM_freeN(slicer.verts); glDepthMask(gl_depth_write); if (!gl_blend) { glDisable(GL_BLEND); } if (gl_depth) { glEnable(GL_DEPTH_TEST); } }
void wm_draw_region_blend(ARegion *ar, int view, bool blend) { if (!ar->draw_buffer) { return; } /* Alpha is always 1, except when blend timer is running. */ float alpha = ED_region_blend_alpha(ar); if (alpha <= 0.0f) { return; } if (!blend) { alpha = 1.0f; } /* setup actual texture */ GPUTexture *texture = wm_draw_region_texture(ar, view); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture)); /* wmOrtho for the screen has this same offset */ const float halfx = GLA_PIXEL_OFS / (BLI_rcti_size_x(&ar->winrct) + 1); const float halfy = GLA_PIXEL_OFS / (BLI_rcti_size_y(&ar->winrct) + 1); if (blend) { /* GL_ONE because regions drawn offscreen have premultiplied alpha. */ GPU_blend(true); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR); GPU_shader_bind(shader); rcti rect_geo = ar->winrct; rect_geo.xmax += 1; rect_geo.ymax += 1; rctf rect_tex; rect_tex.xmin = halfx; rect_tex.ymin = halfy; rect_tex.xmax = 1.0f + halfx; rect_tex.ymax = 1.0f + halfy; float alpha_easing = 1.0f - alpha; alpha_easing = 1.0f - alpha_easing * alpha_easing; /* Slide vertical panels */ float ofs_x = BLI_rcti_size_x(&ar->winrct) * (1.0f - alpha_easing); if (ar->alignment == RGN_ALIGN_RIGHT) { rect_geo.xmin += ofs_x; rect_tex.xmax *= alpha_easing; alpha = 1.0f; } else if (ar->alignment == RGN_ALIGN_LEFT) { rect_geo.xmax -= ofs_x; rect_tex.xmin += 1.0f - alpha_easing; alpha = 1.0f; } glUniform1i(GPU_shader_get_uniform_ensure(shader, "image"), 0); glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_icon"), rect_tex.xmin, rect_tex.ymin, rect_tex.xmax, rect_tex.ymax); glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_geom"), rect_geo.xmin, rect_geo.ymin, rect_geo.xmax, rect_geo.ymax); glUniform4f( GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), alpha, alpha, alpha, alpha); GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4); glBindTexture(GL_TEXTURE_2D, 0); if (blend) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GPU_blend(false); } }