Skip to content

Commit

Permalink
RPRBLND-2301: Fix addon enabling in Blender 4.0+ (#660)
Browse files Browse the repository at this point in the history
* RPRBLND-2301: Fix addon enabling in Blender 4.0+
Made RPR node visible in Add menu.

* Fixed sockets issue.

* Adjusted ShaderNodeBsdfPrincipled.

* Code improvements.

* Migration from bgl to gpu module.

* Remover redundant bgl code.
Fixed hardcoded channels.

* Fixed render pass dimension issue.

* Fixed Transmission input issue.

* Fixed Preview render.

* Performance drop fix.

* Refactored gl.py to gpu.py and removed redundant bgl code.

* Removed entire gpu.py. Moved set_image method to ViewportEngine.

* Improved node category registration.
Added register_rpr_node_categories, unregister_rpr_node_categories with condition for blender version >=4.0

* Code improvements
  • Loading branch information
VascoPi committed Dec 30, 2023
1 parent 618066d commit 1db4850
Show file tree
Hide file tree
Showing 17 changed files with 266 additions and 424 deletions.
32 changes: 0 additions & 32 deletions src/bindings/pyrpr/src/pyrpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
import numpy as np
from typing import List

import bgl

import pyrprwrap
from pyrprwrap import *

Expand Down Expand Up @@ -966,36 +964,6 @@ def get_cl_mem(self):
return cl_mem[0]


class FrameBufferGL(FrameBuffer):
def __init__(self, context, width, height):
super().__init__(context, width, height)

def _create(self):
textures = bgl.Buffer(bgl.GL_INT, [1,])
bgl.glGenTextures(1, textures)
self.texture_id = textures[0]

bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture_id)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_REPEAT)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_REPEAT)

bgl.glTexImage2D(
bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA if platform.system() == 'Darwin' else bgl.GL_RGBA16F,
self.width, self.height, 0,
bgl.GL_RGBA, bgl.GL_FLOAT,
bgl.Buffer(bgl.GL_FLOAT, [self.width, self.height, self.channels])
)

ContextCreateFramebufferFromGLTexture2D(self.context, bgl.GL_TEXTURE_2D, 0, self.texture_id, self)

def delete(self):
super().delete()
textures = bgl.Buffer(bgl.GL_INT, [1,], [self.texture_id, ])
bgl.glDeleteTextures(1, textures)


class Composite(Object):
core_type_name = 'rpr_composite'

Expand Down
14 changes: 0 additions & 14 deletions src/bindings/pyrpr/src/pyrprimagefilters.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@

import pyrpr

import bgl


class _init_data:
log_fun = None
Expand Down Expand Up @@ -146,9 +144,6 @@ def create_image(self, width, height, components=4):
def create_frame_buffer_image(self, frame_buffer):
return FrameBufferImage(self, frame_buffer)

def create_frame_buffer_image_gl(self, frame_buffer):
return FrameBufferImageGL(self, frame_buffer)

def create_command_queue(self):
return CommandQueue(self)

Expand Down Expand Up @@ -257,15 +252,6 @@ def update(self):
pass


class FrameBufferImageGL(FrameBufferImage):
def _create(self):
ContextCreateImageFromOpenGlTexture(self.context, bgl.GL_TEXTURE_2D, 0, self.frame_buffer.gl_texture, self)

def update(self):
# image is updated directly
pass


class FrameBufferImageMetal(FrameBufferImage):
def _create(self):
ContextCreateImageFromMetalMemory(self.context, self._get_desc(),
Expand Down
2 changes: 1 addition & 1 deletion src/rprblender/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"version": (3, 6, 9),
"blender": (2, 93, 0),
"location": "Info header, render engine menu",
"description": "Radeon ProRender rendering plugin for Blender 2.9x",
"description": "Radeon ProRender rendering plugin for Blender 2.9x+",
"warning": "",
"tracker_url": "",
"wiki_url": "",
Expand Down
24 changes: 2 additions & 22 deletions src/rprblender/engine/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ def __init__(self):
self.material_system = None
self.width = None
self.height = None
self.gl_interop = None
self.engine_type = None

# Here we'll store some useful blender data, which could be required to do some export
Expand Down Expand Up @@ -97,7 +96,6 @@ def __init__(self):
def init(self, context_flags, context_props):
self.context = self._Context(context_flags, context_props)
self.material_system = pyrpr.MaterialSystem(self.context)
self.gl_interop = pyrpr.CREATION_FLAGS_ENABLE_GL_INTEROP in context_flags

# context settings
self.set_parameter(pyrpr.CONTEXT_X_FLIP, False)
Expand Down Expand Up @@ -159,9 +157,6 @@ def get_frame_buffer(self, aov_type=None):
if aov_type is not None:
return self.frame_buffers_aovs[aov_type]['res']

if self.gl_interop:
return self.frame_buffers_aovs[pyrpr.AOV_COLOR]['gl']

if self.composite:
return self.frame_buffers_aovs[pyrpr.AOV_COLOR]['composite']

Expand All @@ -186,13 +181,8 @@ def enable_aov(self, aov_type):
fbs['aov'] = pyrpr.FrameBuffer(self.context, self.width, self.height)
fbs['aov'].set_name("%d_aov" % aov_type)
self.context.attach_aov(aov_type, fbs['aov'])
if aov_type == pyrpr.AOV_COLOR and self.gl_interop:
fbs['res'] = pyrpr.FrameBufferGL(self.context, self.width, self.height)
fbs['gl'] = fbs['res'] # resolved and gl framebuffers are the same
fbs['gl'].set_name("%d_gl" % aov_type)
else:
fbs['res'] = pyrpr.FrameBuffer(self.context, self.width, self.height)
fbs['res'].set_name("%d_res" % aov_type)
fbs['res'] = pyrpr.FrameBuffer(self.context, self.width, self.height)
fbs['res'].set_name("%d_res" % aov_type)

self.frame_buffers_aovs[aov_type] = fbs

Expand Down Expand Up @@ -300,11 +290,6 @@ def create_filter_composite(self):
self.frame_buffers_aovs[pyrpr.AOV_COLOR]['composite'] = pyrpr.FrameBuffer(
self.context, self.width, self.height)
self.frame_buffers_aovs[pyrpr.AOV_COLOR]['composite'].set_name('default_composite')
if self.gl_interop:
# splitting resolved and gl framebuffers
self.frame_buffers_aovs[pyrpr.AOV_COLOR]['res'] = pyrpr.FrameBuffer(
self.context, self.width, self.height)
self.frame_buffers_aovs[pyrpr.AOV_COLOR]['res'].set_name('default_res')
# Composite calculation elements frame buffers
color = self.create_composite(pyrpr.COMPOSITE_FRAMEBUFFER, {
'framebuffer.input': self.frame_buffers_aovs[pyrpr.AOV_COLOR]['res']
Expand Down Expand Up @@ -347,9 +332,6 @@ def create_filter_composite(self):

def _disable_catchers(self):
self.composite = None
if self.gl_interop:
# set resolved framebuffer be the same as gl
self.frame_buffers_aovs[pyrpr.AOV_COLOR]['res'] = self.frame_buffers_aovs[pyrpr.AOV_COLOR]['gl']
del self.frame_buffers_aovs[pyrpr.AOV_COLOR]['composite']

def sync_auto_adapt_subdivision(self, width=0, height=0):
Expand Down Expand Up @@ -613,8 +595,6 @@ def apply_filters(self):
if self.composite:
color_aov = self.frame_buffers_aovs[pyrpr.AOV_COLOR]
self.composite.compute(color_aov['composite'])
if self.gl_interop:
color_aov['composite'].resolve(color_aov['gl'])


class RPRContext2(RPRContext):
Expand Down
6 changes: 1 addition & 5 deletions src/rprblender/engine/image_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.
#********************************************************************
from abc import ABCMeta, abstractmethod
import os

import pyrpr
import pyhybrid
Expand Down Expand Up @@ -65,10 +64,7 @@ def __init__(self, rpr_context: pyrpr.Context, inputs, sigmas, params, width, he
self.inputs[input_id] = self.context.create_image(self.width, self.height)

self.command_queue = self.context.create_command_queue()
if frame_buffer_gl:
self.output_image = self.context.create_frame_buffer_image_gl(frame_buffer_gl)
else:
self.output_image = self.context.create_image(self.width, self.height)
self.output_image = self.context.create_image(self.width, self.height)

self._create_filter()

Expand Down
6 changes: 5 additions & 1 deletion src/rprblender/engine/preview_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,13 @@ def render(self):
# since version 3.4 result.layers[0].passes == ['Combined', 'Depth']
# we need to add Depth AOV to keep correct array size while using foreach_set
image = np.concatenate(
(image, self.rpr_context.get_image(pyrpr.AOV_DEPTH).flatten())
(image, self.rpr_context.get_image(pyrpr.AOV_DEPTH)[:, :, 0:1].flatten())
)

if BLENDER_VERSION >= '4.0':
# foreach_set requires every pass to be 4 channels, so we resize to reach desirable size
image.resize((len(result.layers[0].passes) * self.rpr_context.width * self.rpr_context.height * 4,))

result.layers[0].passes.foreach_set('rect', image)
self.rpr_engine.update_result(result)

Expand Down
16 changes: 13 additions & 3 deletions src/rprblender/engine/render_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from rprblender import utils
from .engine import Engine
from rprblender.export import world, camera, object, instance, particle
from rprblender.utils import render_stamp
from rprblender.utils import render_stamp, BLENDER_VERSION
from rprblender.utils.conversion import perfcounter_to_str, get_cryptomatte_hash
from rprblender.utils.user_settings import get_user_settings
from rprblender import bl_info
Expand Down Expand Up @@ -152,8 +152,13 @@ def set_render_result(render_passes: bpy.types.RenderPasses):

images.append(image.flatten())

images_data = np.concatenate(images)
if BLENDER_VERSION >= '4.0':
# foreach_set requires every pass to be 4 channels, so we resize to reach desirable size
images_data.resize((len(render_passes) * self.width * self.height * 4,))

# efficient way to copy all AOV images
render_passes.foreach_set('rect', np.concatenate(images))
render_passes.foreach_set('rect', images_data)

result = self.rpr_engine.begin_result(*tile_pos, *tile_size, layer=layer_name, view="")
try:
Expand Down Expand Up @@ -203,8 +208,13 @@ def set_render_result(render_passes: bpy.types.RenderPasses):

images.append(image.flatten())

images_data = np.concatenate(images)
if BLENDER_VERSION >= '4.0':
# foreach_set requires every pass to be 4 channels, so we resize to reach desirable size
images_data.resize((len(render_passes) * self.width * self.height * 4,))

# efficient way to copy all AOV images
render_passes.foreach_set('rect', np.concatenate(images))
render_passes.foreach_set('rect', images_data)

result = self.rpr_engine.begin_result(*tile_pos, *tile_size, layer=layer_name, view="")
try:
Expand Down
Loading

0 comments on commit 1db4850

Please sign in to comment.