Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c15
-rw-r--r--source/blender/gpu/intern/gpu_draw.c45
-rw-r--r--source/blender/gpu/intern/gpu_material.c6
-rw-r--r--source/blender/gpu/intern/gpu_texture.c113
4 files changed, 139 insertions, 40 deletions
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index df8dbb03284..688386810ea 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -791,11 +791,14 @@ void GPU_pbvh_bmesh_buffers_update(
tottri = gpu_bmesh_face_visible_count(bm_faces);
if (buffers->smooth) {
+ /* Smooth needs to recreate index buffer, so we have to invalidate the batch. */
+ GWN_BATCH_DISCARD_SAFE(buffers->triangles);
/* Count visible vertices */
totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
}
- else
+ else {
totvert = tottri * 3;
+ }
if (!tottri) {
buffers->tot_tri = 0;
@@ -905,13 +908,11 @@ void GPU_pbvh_bmesh_buffers_update(
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- BMLoop *l_iter;
- BMLoop *l_first;
+ BMVert *v[3];
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- GWN_indexbuf_add_generic_vert(&elb, BM_elem_index_get(l_iter->v));
- } while ((l_iter = l_iter->next) != l_first);
+ BM_face_as_array_vert_tri(f, v);
+ GWN_indexbuf_add_tri_verts(
+ &elb, BM_elem_index_get(v[0]), BM_elem_index_get(v[1]), BM_elem_index_get(v[2]));
}
}
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 83fd689e3b7..7383868843d 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -140,7 +140,7 @@ static struct GPUTextureState {
/* Mipmap settings */
-void GPU_set_gpu_mipmapping(int gpu_mipmap)
+void GPU_set_gpu_mipmapping(Main *bmain, int gpu_mipmap)
{
int old_value = GTS.gpu_mipmap;
@@ -148,14 +148,14 @@ void GPU_set_gpu_mipmapping(int gpu_mipmap)
GTS.gpu_mipmap = gpu_mipmap;
if (old_value != GTS.gpu_mipmap) {
- GPU_free_images();
+ GPU_free_images(bmain);
}
}
-void GPU_set_mipmap(bool mipmap)
+void GPU_set_mipmap(Main *bmain, bool mipmap)
{
if (GTS.domipmap != mipmap) {
- GPU_free_images();
+ GPU_free_images(bmain);
GTS.domipmap = mipmap;
}
}
@@ -203,10 +203,10 @@ static GLenum gpu_get_mipmap_filter(bool mag)
}
/* Anisotropic filtering settings */
-void GPU_set_anisotropic(float value)
+void GPU_set_anisotropic(Main *bmain, float value)
{
if (GTS.anisotropic != value) {
- GPU_free_images();
+ GPU_free_images(bmain);
/* Clamp value to the maximum value the graphics card supports */
const float max = GPU_max_texture_anisotropy();
@@ -682,7 +682,7 @@ void GPU_create_gl_tex_compressed(
* temporary disabling/enabling mipmapping on all images for quick texture
* updates with glTexSubImage2D. images that didn't change don't have to be
* re-uploaded to OpenGL */
-void GPU_paint_set_mipmap(bool mipmap)
+void GPU_paint_set_mipmap(Main *bmain, bool mipmap)
{
if (!GTS.domipmap)
return;
@@ -690,7 +690,7 @@ void GPU_paint_set_mipmap(bool mipmap)
GTS.texpaint = !mipmap;
if (mipmap) {
- for (Image *ima = G.main->image.first; ima; ima = ima->id.next) {
+ for (Image *ima = bmain->image.first; ima; ima = ima->id.next) {
if (BKE_image_has_opengl_texture(ima)) {
if (ima->tpageflag & IMA_MIPMAP_COMPLETE) {
if (ima->gputexture[TEXTARGET_TEXTURE_2D]) {
@@ -709,7 +709,7 @@ void GPU_paint_set_mipmap(bool mipmap)
}
else {
- for (Image *ima = G.main->image.first; ima; ima = ima->id.next) {
+ for (Image *ima = bmain->image.first; ima; ima = ima->id.next) {
if (BKE_image_has_opengl_texture(ima)) {
if (ima->gputexture[TEXTARGET_TEXTURE_2D]) {
GPU_texture_bind(ima->gputexture[TEXTARGET_TEXTURE_2D], 0);
@@ -980,7 +980,7 @@ static void gpu_queue_image_for_free(Image *ima)
BLI_thread_unlock(LOCK_OPENGL);
}
-void GPU_free_unused_buffers(void)
+void GPU_free_unused_buffers(Main *bmain)
{
if (!BLI_thread_is_main())
return;
@@ -992,7 +992,7 @@ void GPU_free_unused_buffers(void)
Image *ima = node->link;
/* check in case it was freed in the meantime */
- if (G.main && BLI_findindex(&G.main->image, ima) != -1)
+ if (bmain && BLI_findindex(&bmain->image, ima) != -1)
GPU_free_image(ima);
}
@@ -1020,24 +1020,29 @@ void GPU_free_image(Image *ima)
ima->tpageflag &= ~(IMA_MIPMAP_COMPLETE | IMA_GLBIND_IS_DATA);
}
-void GPU_free_images(void)
+void GPU_free_images(Main *bmain)
{
- if (G.main)
- for (Image *ima = G.main->image.first; ima; ima = ima->id.next)
+ if (bmain) {
+ for (Image *ima = bmain->image.first; ima; ima = ima->id.next) {
GPU_free_image(ima);
+ }
+ }
}
/* same as above but only free animated images */
-void GPU_free_images_anim(void)
+void GPU_free_images_anim(Main *bmain)
{
- if (G.main)
- for (Image *ima = G.main->image.first; ima; ima = ima->id.next)
- if (BKE_image_is_animated(ima))
+ if (bmain) {
+ for (Image *ima = bmain->image.first; ima; ima = ima->id.next) {
+ if (BKE_image_is_animated(ima)) {
GPU_free_image(ima);
+ }
+ }
+ }
}
-void GPU_free_images_old(void)
+void GPU_free_images_old(Main *bmain)
{
static int lasttime = 0;
int ctime = (int)PIL_check_seconds_timer();
@@ -1055,7 +1060,7 @@ void GPU_free_images_old(void)
lasttime = ctime;
- Image *ima = G.main->image.first;
+ Image *ima = bmain->image.first;
while (ima) {
if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) {
/* If it's in GL memory, deallocate and set time tag to current time
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 302ddc62188..9c776e64ba0 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -723,16 +723,16 @@ void GPU_material_compile(GPUMaterial *mat)
}
}
-void GPU_materials_free(void)
+void GPU_materials_free(Main *bmain)
{
Material *ma;
World *wo;
extern Material defmaterial;
- for (ma = G.main->mat.first; ma; ma = ma->id.next)
+ for (ma = bmain->mat.first; ma; ma = ma->id.next)
GPU_material_free(&ma->gpumaterial);
- for (wo = G.main->world.first; wo; wo = wo->id.next)
+ for (wo = bmain->world.first; wo; wo = wo->id.next)
GPU_material_free(&wo->gpumaterial);
GPU_material_free(&defmaterial.gpumaterial);
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index ee00a1381f4..21a3aee5f57 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -171,6 +171,10 @@ static GLenum gpu_texture_get_format(
default: break;
}
}
+ else if (ELEM(data_type, GPU_R8)) {
+ *data_format = GL_UNSIGNED_BYTE;
+ *format = GL_RED;
+ }
else {
*data_format = GL_FLOAT;
*format_flag |= GPU_FORMAT_FLOAT;
@@ -882,37 +886,58 @@ GPUTexture *GPU_texture_create_from_vertbuf(Gwn_VertBuf *vert)
return GPU_texture_create_buffer(data_type, vert->vbo_id);
}
-void GPU_texture_update(GPUTexture *tex, const float *pixels)
+void GPU_texture_update_sub(
+ GPUTexture *tex, const void *pixels,
+ int offset_x, int offset_y, int offset_z, int width, int height, int depth)
{
- BLI_assert(tex->format > -1);
+ BLI_assert((int)tex->format > -1);
BLI_assert(tex->components > -1);
GLenum format, data_format;
+ GLint alignment;
gpu_texture_get_format(tex->components, tex->format, &format, &data_format,
- &tex->format_flag, &tex->bytesize);
+ &tex->format_flag, &tex->bytesize);
- glBindTexture(tex->target, tex->bindcode);
+ /* The default pack size for textures is 4, which won't work for byte based textures */
+ if (tex->bytesize == 1) {
+ glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ }
+ glBindTexture(tex->target, tex->bindcode);
switch (tex->target) {
case GL_TEXTURE_2D:
case GL_TEXTURE_2D_MULTISAMPLE:
case GL_TEXTURE_1D_ARRAY:
- glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, format, data_format, pixels);
+ glTexSubImage2D(
+ tex->target, 0, offset_x, offset_y,
+ width, height, format, data_format, pixels);
break;
case GL_TEXTURE_1D:
- glTexSubImage1D(tex->target, 0, 0, tex->w, format, data_format, pixels);
+ glTexSubImage1D(tex->target, 0, offset_x, width, format, data_format, pixels);
break;
case GL_TEXTURE_3D:
case GL_TEXTURE_2D_ARRAY:
- glTexSubImage3D(tex->target, 0, 0, 0, 0, tex->w, tex->h, tex->d, format, data_format, pixels);
+ glTexSubImage3D(
+ tex->target, 0, offset_x, offset_y, offset_z,
+ width, height, depth, format, data_format, pixels);
break;
default:
BLI_assert(!"tex->target mode not supported");
}
+ if (tex->bytesize == 1) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
+ }
+
glBindTexture(tex->target, 0);
}
+void GPU_texture_update(GPUTexture *tex, const void *pixels)
+{
+ GPU_texture_update_sub(tex, pixels, 0, 0, 0, tex->w, tex->h, tex->d);
+}
+
void GPU_invalid_tex_init(void)
{
memory_usage = 0;
@@ -1045,9 +1070,10 @@ void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter)
BLI_assert((!use_filter && !use_mipmap) || !(GPU_texture_stencil(tex) || GPU_texture_integer(tex)));
GLenum filter = (use_filter) ? GL_LINEAR : GL_NEAREST;
- GLenum mipmap = (use_filter)
- ? (use_mipmap) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR
- : (use_mipmap) ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST;
+ GLenum mipmap = (
+ (use_filter) ?
+ (use_mipmap) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR :
+ (use_mipmap) ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST);
glActiveTexture(GL_TEXTURE0 + tex->number);
glTexParameteri(tex->target_base, GL_TEXTURE_MIN_FILTER, mipmap);
@@ -1068,6 +1094,33 @@ void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat)
glTexParameteri(tex->target_base, GL_TEXTURE_WRAP_R, repeat);
}
+static GLenum gpu_get_gl_filterfunction(GPUFilterFunction filter)
+{
+ switch (filter) {
+ case GPU_NEAREST:
+ return GL_NEAREST;
+ case GPU_LINEAR:
+ return GL_LINEAR;
+ default:
+ BLI_assert(!"Unhandled filter mode");
+ return GL_NEAREST;
+ }
+}
+
+void GPU_texture_filters(GPUTexture *tex, GPUFilterFunction min_filter, GPUFilterFunction mag_filter)
+{
+ WARN_NOT_BOUND(tex);
+
+ /* Stencil and integer format does not support filtering. */
+ BLI_assert(!(GPU_texture_stencil(tex) || GPU_texture_integer(tex)));
+ BLI_assert(mag_filter == GPU_NEAREST || mag_filter == GPU_LINEAR);
+
+ glActiveTexture(GL_TEXTURE0 + tex->number);
+ glTexParameteri(tex->target_base, GL_TEXTURE_MIN_FILTER, gpu_get_gl_filterfunction(min_filter));
+ glTexParameteri(tex->target_base, GL_TEXTURE_MAG_FILTER, gpu_get_gl_filterfunction(mag_filter));
+}
+
+
static void gpu_texture_delete(GPUTexture *tex)
{
if (tex->bindcode)
@@ -1207,3 +1260,43 @@ int GPU_texture_detach_framebuffer(GPUTexture *tex, GPUFrameBuffer *fb)
BLI_assert(!"Error: Texture: Framebuffer is not attached");
return 0;
}
+
+void GPU_blend(bool enable)
+{
+ if (enable) {
+ glEnable(GL_BLEND);
+ }
+ else {
+ glDisable(GL_BLEND);
+ }
+}
+
+static GLenum gpu_get_gl_blendfunction(GPUBlendFunction blend)
+{
+ switch (blend) {
+ case GPU_ONE:
+ return GL_ONE;
+ case GPU_SRC_ALPHA:
+ return GL_SRC_ALPHA;
+ case GPU_ONE_MINUS_SRC_ALPHA:
+ return GL_ONE_MINUS_SRC_ALPHA;
+ default:
+ BLI_assert(!"Unhandled blend mode");
+ return GL_ZERO;
+ }
+}
+
+void GPU_blend_set_func_separate(
+ GPUBlendFunction src_rgb, GPUBlendFunction dst_rgb,
+ GPUBlendFunction src_alpha, GPUBlendFunction dst_alpha)
+{
+ glBlendFuncSeparate(gpu_get_gl_blendfunction(src_rgb),
+ gpu_get_gl_blendfunction(dst_rgb),
+ gpu_get_gl_blendfunction(src_alpha),
+ gpu_get_gl_blendfunction(dst_alpha));
+}
+
+void GPU_blend_set_func(GPUBlendFunction sfactor, GPUBlendFunction dfactor)
+{
+ glBlendFunc(gpu_get_gl_blendfunction(sfactor), gpu_get_gl_blendfunction(dfactor));
+}