예제 #1
0
/* 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);
  }
}
예제 #2
0
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();
}
예제 #3
0
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);
	}
}
예제 #4
0
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);
    }
예제 #5
0
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);
	}
}
예제 #6
0
파일: wm_draw.c 프로젝트: dfelinto/blender
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);
  }
}