Support Blender 4.0

This commit is contained in:
akaneyu 2024-03-06 20:36:45 +09:00
parent 91cb6a9356
commit 9913ae8c35
4 changed files with 62 additions and 66 deletions

View File

@ -1,5 +1,5 @@
'''
Copyright (C) 2021 - 2023 Akaneyu
Copyright (C) 2021 - 2024 Akaneyu
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -18,8 +18,8 @@
bl_info = {
"name": "Image Editor Plus",
"author": "akaneyu",
"version": (1, 7, 3),
"blender": (2, 93, 0),
"version": (1, 8, 0),
"blender": (3, 3, 0),
"location": "Image",
"warning": "",
"description": "",

View File

@ -1,5 +1,5 @@
'''
Copyright (C) 2021 - 2023 Akaneyu
Copyright (C) 2021 - 2024 Akaneyu
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -152,22 +152,23 @@ def draw_handler():
or area_session.layer_rotating \
or area_session.layer_scaling:
info_text = "LMB: Perform\n" \
info_text = "LMB: Perform " \
+ "RMB: Cancel"
area_height = context.area.height
area_width = context.area.width
# info text
if info_text:
blf.enable(0, blf.WORD_WRAP)
blf.word_wrap(0, 100)
ui_scale = context.preferences.system.ui_scale
blf.position(0, 30, area_height - 70, 0)
blf.size(0, 14, 72)
session.ui_renderer.render_info_box((0, 0), (area_width, 20 * ui_scale))
blf.position(0, 8 * ui_scale, 6 * ui_scale, 0)
blf.size(0, 11 * ui_scale) if bpy.app.version >= (3, 6) \
else blf.size(0, 11 * ui_scale, 72)
blf.color(0, 0.7, 0.7, 0.7, 1.0)
blf.draw(0, info_text)
blf.disable(0, blf.WORD_WRAP)
def get_curve_node():
node_group = bpy.data.node_groups.get('imageeditorplus')
if not node_group:
@ -392,7 +393,7 @@ def apply_layer_transform(img, rot, scale):
buff, width, height = session.ui_renderer.render_image_offscreen(img, rot, scale)
pixels = np.reshape(buff, (height, width, 4)).astype(np.float32) / 255.0
pixels = np.array([[pixel for pixel in row] for row in buff], np.float32) / 255.0
# gamma correction
utils.convert_colorspace(pixels, 'Linear',

View File

@ -1,5 +1,5 @@
'''
Copyright (C) 2020 Akaneyu
Copyright (C) 2020 - 2024 Akaneyu
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -17,10 +17,6 @@
import sys
import math
import time
import bpy
import bgl
import blf
import gpu
from gpu_extras.batch import batch_for_shader
from mathutils import Matrix, Vector
@ -138,8 +134,10 @@ class UIRenderer:
def render_selection_frame(self, pos, size, rot=0, scale=(1.0, 1.0)):
width, height = size[0], size[1]
bgl.glEnable(bgl.GL_BLEND)
bgl.glLineWidth(2.0)
prev_blend = gpu.state.blend_get()
gpu.state.blend_set('ALPHA')
gpu.state.line_width_set(2.0)
with gpu.matrix.push_pop():
verts = [[0, 0], [0, height], [width, height], [width, 0], [0, 0]]
@ -172,20 +170,12 @@ class UIRenderer:
batch.draw(self.dotted_line_shader)
err = bgl.glGetError()
if err != bgl.GL_NO_ERROR:
print('render_selection_frame')
print('OpenGL error:', err)
gpu.state.blend_set(prev_blend)
def render_image_sub(self, img, pos, size, rot, scale):
width, height = size[0], size[1]
img.gl_load()
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, img.bindcode)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_NEAREST)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_NEAREST)
texture = gpu.texture.from_image(img)
with gpu.matrix.push_pop():
gpu.matrix.translate([pos[0] + width / 2.0, pos[1] + height / 2.0])
@ -207,24 +197,18 @@ class UIRenderer:
self.image_shader.bind()
self.image_shader.uniform_int('image', 0)
self.image_shader.uniform_sampler('image', texture)
batch.draw(self.image_shader)
err = bgl.glGetError()
if err != bgl.GL_NO_ERROR:
print('render_image')
print('OpenGL error:', err)
def render_image(self, img, pos, size, rot=0, scale=(1.0, 1.0)):
bgl.glEnable(bgl.GL_BLEND)
# FIXME: glBlendFuncSeparate does not seem to be implemented,
# but we believe this blend mode was already applied
#bgl.glBlendFuncSeparate(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA,
# bgl.GL_ONE, bgl.GL_ONE_MINUS_SRC_ALPHA);
prev_blend = gpu.state.blend_get()
gpu.state.blend_set('ALPHA')
self.render_image_sub(img, pos, size, rot, scale)
gpu.state.blend_set(prev_blend)
def render_image_offscreen(self, img, rot=0, scale=(1.0, 1.0)):
width, height = img.size[0], img.size[1]
@ -248,10 +232,8 @@ class UIRenderer:
ofs = gpu.types.GPUOffScreen(ofs_width, ofs_height)
with ofs.bind():
bgl.glDisable(bgl.GL_BLEND)
bgl.glClearColor(0, 0, 0, 0)
bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
fb = gpu.state.active_framebuffer_get()
fb.clear(color=(0.0, 0.0, 0.0, 0.0))
with gpu.matrix.push_pop():
gpu.matrix.load_projection_matrix(Matrix.Identity(4))
@ -262,16 +244,36 @@ class UIRenderer:
self.render_image_sub(img, [0, 0], [width, height], rot, scale)
buff = bgl.Buffer(bgl.GL_BYTE, ofs_width * ofs_height * 4)
bgl.glReadBuffer(bgl.GL_BACK)
bgl.glReadPixels(0, 0, ofs_width, ofs_height, bgl.GL_RGBA,
bgl.GL_UNSIGNED_BYTE, buff)
buff = fb.read_color(0, 0, ofs_width, ofs_height, 4, 0, 'UBYTE')
ofs.free()
err = bgl.glGetError()
if err != bgl.GL_NO_ERROR:
print('render_image_offscreen')
print('OpenGL error:', err)
return buff, ofs_width, ofs_height
def render_info_box(self, pos1, pos2):
prev_blend = gpu.state.blend_get()
gpu.state.blend_set('ALPHA')
verts = [
pos1,
(pos2[0], pos1[1]),
(pos1[0], pos2[1]),
pos2
]
indices = [
(0, 1, 2),
(2, 1, 3)
]
batch = batch_for_shader(self.default_shader, 'TRIS',
{"pos": verts}, indices=indices)
self.default_shader.bind()
self.default_shader.uniform_vector_float(self.default_shader_u_color,
np.array([0, 0, 0, 0.7], 'f'), 4)
batch.draw(self.default_shader)
gpu.state.blend_set(prev_blend)

View File

@ -1,5 +1,5 @@
'''
Copyright (C) 2021 Akaneyu
Copyright (C) 2021 - 2024 Akaneyu
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -15,24 +15,17 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import bpy
import numpy as np
def read_pixels_from_image(img):
width, height = img.size[0], img.size[1]
if bpy.app.version >= (2, 83, 0):
pixels = np.empty(len(img.pixels), dtype=np.float32);
img.pixels.foreach_get(pixels)
return np.reshape(pixels, (height, width, 4))
else:
return np.reshape(img.pixels[:], (height, width, 4))
pixels = np.empty(len(img.pixels), dtype=np.float32);
img.pixels.foreach_get(pixels)
return np.reshape(pixels, (height, width, 4))
def write_pixels_to_image(img, pixels):
if bpy.app.version >= (2, 83, 0):
img.pixels.foreach_set(np.reshape(pixels, -1))
else:
img.pixels = np.reshape(pixels, -1)
img.pixels.foreach_set(np.reshape(pixels, -1))
if img.preview:
img.preview.reload()