diff options
author | Hans Goudey <h.goudey@me.com> | 2022-02-16 18:02:30 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-02-16 18:02:30 +0300 |
commit | 5d0bd68cc06897c7e62988abe26268783cfb1bb9 (patch) | |
tree | 6642554c8927280a8ba49bd9c329f2a133afa60a | |
parent | 6d89120248f3dd24d2090814b29af0ca12d5d7c6 (diff) | |
parent | 5b3a415a59cef7183a2539fcc12de8fd1ebf8814 (diff) |
Merge branch 'master' into bli-math-basic-typesbli-math-basic-types
58 files changed, 1469 insertions, 611 deletions
diff --git a/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp b/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp index a8387dd9489..cbf35520c3d 100644 --- a/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp +++ b/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp @@ -71,7 +71,7 @@ void WASAPIDevice::runMixingThread() IAudioRenderClient* render_client = nullptr; - std::chrono::milliseconds sleep_duration; + std::chrono::milliseconds sleep_duration(0); bool run_init = true; diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt index 75ff7114dd7..ab38e103311 100644 --- a/intern/cycles/app/CMakeLists.txt +++ b/intern/cycles/app/CMakeLists.txt @@ -33,15 +33,13 @@ else() endif() if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI) - list(APPEND LIBRARIES ${GLUT_LIBRARIES}) + add_definitions(${GL_DEFINITIONS}) + list(APPEND INC_SYS ${GLEW_INCLUDE_DIR} ${SDL2_INCLUDE_DIRS}) + list(APPEND LIBRARIES ${CYCLES_GL_LIBRARIES} ${SDL2_LIBRARIES}) endif() -list(APPEND LIBRARIES ${CYCLES_GL_LIBRARIES}) - # Common configuration. -add_definitions(${GL_DEFINITIONS}) - include_directories(${INC}) include_directories(SYSTEM ${INC_SYS}) @@ -55,6 +53,18 @@ if(WITH_CYCLES_STANDALONE) oiio_output_driver.cpp oiio_output_driver.h ) + + if(WITH_CYCLES_STANDALONE_GUI) + list(APPEND SRC + opengl/display_driver.cpp + opengl/display_driver.h + opengl/shader.cpp + opengl/shader.h + opengl/window.cpp + opengl/window.h + ) + endif() + add_executable(cycles ${SRC} ${INC} ${INC_SYS}) unset(SRC) @@ -69,6 +79,10 @@ if(WITH_CYCLES_STANDALONE) # OpenImageDenoise uses BNNS from the Accelerate framework. set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS " -framework Accelerate") endif() + if(WITH_CYCLES_STANDALONE_GUI) + set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS + " -framework Cocoa -framework CoreAudio -framework AudioUnit -framework AudioToolbox -framework ForceFeedback -framework CoreVideo") + endif() endif() if(UNIX AND NOT APPLE) diff --git a/intern/cycles/app/cycles_standalone.cpp b/intern/cycles/app/cycles_standalone.cpp index 0e425ac3d8f..ef20f64debd 100644 --- a/intern/cycles/app/cycles_standalone.cpp +++ b/intern/cycles/app/cycles_standalone.cpp @@ -27,11 +27,10 @@ #include "app/oiio_output_driver.h" #ifdef WITH_CYCLES_STANDALONE_GUI -# include "util/view.h" +# include "opengl/display_driver.h" +# include "opengl/window.h" #endif -#include "app/cycles_xml.h" - CCL_NAMESPACE_BEGIN struct Options { @@ -117,7 +116,14 @@ static void session_init() options.output_pass = "combined"; options.session = new Session(options.session_params, options.scene_params); - if (!options.output_filepath.empty()) { +#ifdef WITH_CYCLES_STANDALONE_GUI + if (!options.session_params.background) { + options.session->set_display_driver(make_unique<OpenGLDisplayDriver>( + window_opengl_context_enable, window_opengl_context_disable)); + } + else +#endif + if (!options.output_filepath.empty()) { options.session->set_output_driver(make_unique<OIIOOutputDriver>( options.output_filepath, options.output_pass, session_print)); } @@ -126,7 +132,7 @@ static void session_init() options.session->progress.set_update_callback(function_bind(&session_print_status)); #ifdef WITH_CYCLES_STANDALONE_GUI else - options.session->progress.set_update_callback(function_bind(&view_redraw)); + options.session->progress.set_update_callback(function_bind(&window_redraw)); #endif /* load scene */ @@ -191,10 +197,10 @@ static void display_info(Progress &progress) sample_time, interactive.c_str()); - view_display_info(str.c_str()); + window_display_info(str.c_str()); if (options.show_help) - view_display_help(); + window_display_help(); } static void display() @@ -525,15 +531,15 @@ int main(int argc, const char **argv) string title = "Cycles: " + path_filename(options.filepath); /* init/exit are callback so they run while GL is initialized */ - view_main_loop(title.c_str(), - options.width, - options.height, - session_init, - session_exit, - resize, - display, - keyboard, - motion); + window_main_loop(title.c_str(), + options.width, + options.height, + session_init, + session_exit, + resize, + display, + keyboard, + motion); } #endif diff --git a/intern/cycles/app/opengl/display_driver.cpp b/intern/cycles/app/opengl/display_driver.cpp new file mode 100644 index 00000000000..6e610b8b02c --- /dev/null +++ b/intern/cycles/app/opengl/display_driver.cpp @@ -0,0 +1,385 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#include "app/opengl/display_driver.h" +#include "app/opengl/shader.h" + +#include "util/log.h" +#include "util/string.h" + +#include <GL/glew.h> +#include <SDL.h> + +CCL_NAMESPACE_BEGIN + +/* -------------------------------------------------------------------- + * OpenGLDisplayDriver. + */ + +OpenGLDisplayDriver::OpenGLDisplayDriver(const function<bool()> &gl_context_enable, + const function<void()> &gl_context_disable) + : gl_context_enable_(gl_context_enable), gl_context_disable_(gl_context_disable) +{ +} + +OpenGLDisplayDriver::~OpenGLDisplayDriver() +{ +} + +/* -------------------------------------------------------------------- + * Update procedure. + */ + +void OpenGLDisplayDriver::next_tile_begin() +{ + /* Assuming no tiles used in interactive display. */ +} + +bool OpenGLDisplayDriver::update_begin(const Params ¶ms, int texture_width, int texture_height) +{ + /* Note that it's the responsibility of OpenGLDisplayDriver to ensure updating and drawing + * the texture does not happen at the same time. This is achieved indirectly. + * + * When enabling the OpenGL context, it uses an internal mutex lock DST.gl_context_lock. + * This same lock is also held when do_draw() is called, which together ensure mutual + * exclusion. + * + * This locking is not performed on the Cycles side, because that would cause lock inversion. */ + if (!gl_context_enable_()) { + return false; + } + + if (gl_render_sync_) { + glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED); + } + + if (!gl_texture_resources_ensure()) { + gl_context_disable_(); + return false; + } + + /* Update texture dimensions if needed. */ + if (texture_.width != texture_width || texture_.height != texture_height) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_.gl_id); + glTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA16F, texture_width, texture_height, 0, GL_RGBA, GL_HALF_FLOAT, 0); + texture_.width = texture_width; + texture_.height = texture_height; + glBindTexture(GL_TEXTURE_2D, 0); + + /* Texture did change, and no pixel storage was provided. Tag for an explicit zeroing out to + * avoid undefined content. */ + texture_.need_clear = true; + } + + /* Update PBO dimensions if needed. + * + * NOTE: Allocate the PBO for the the size which will fit the final render resolution (as in, + * at a resolution divider 1. This was we don't need to recreate graphics interoperability + * objects which are costly and which are tied to the specific underlying buffer size. + * The downside of this approach is that when graphics interoperability is not used we are + * sending too much data to GPU when resolution divider is not 1. */ + const int buffer_width = params.full_size.x; + const int buffer_height = params.full_size.y; + if (texture_.buffer_width != buffer_width || texture_.buffer_height != buffer_height) { + const size_t size_in_bytes = sizeof(half4) * buffer_width * buffer_height; + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id); + glBufferData(GL_PIXEL_UNPACK_BUFFER, size_in_bytes, 0, GL_DYNAMIC_DRAW); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + texture_.buffer_width = buffer_width; + texture_.buffer_height = buffer_height; + } + + /* New content will be provided to the texture in one way or another, so mark this in a + * centralized place. */ + texture_.need_update = true; + + return true; +} + +void OpenGLDisplayDriver::update_end() +{ + gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + + gl_context_disable_(); +} + +/* -------------------------------------------------------------------- + * Texture buffer mapping. + */ + +half4 *OpenGLDisplayDriver::map_texture_buffer() +{ + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id); + + half4 *mapped_rgba_pixels = reinterpret_cast<half4 *>( + glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY)); + if (!mapped_rgba_pixels) { + LOG(ERROR) << "Error mapping OpenGLDisplayDriver pixel buffer object."; + } + + if (texture_.need_clear) { + const int64_t texture_width = texture_.width; + const int64_t texture_height = texture_.height; + memset(reinterpret_cast<void *>(mapped_rgba_pixels), + 0, + texture_width * texture_height * sizeof(half4)); + texture_.need_clear = false; + } + + return mapped_rgba_pixels; +} + +void OpenGLDisplayDriver::unmap_texture_buffer() +{ + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); +} + +/* -------------------------------------------------------------------- + * Graphics interoperability. + */ + +OpenGLDisplayDriver::GraphicsInterop OpenGLDisplayDriver::graphics_interop_get() +{ + GraphicsInterop interop_dst; + + interop_dst.buffer_width = texture_.buffer_width; + interop_dst.buffer_height = texture_.buffer_height; + interop_dst.opengl_pbo_id = texture_.gl_pbo_id; + + interop_dst.need_clear = texture_.need_clear; + texture_.need_clear = false; + + return interop_dst; +} + +void OpenGLDisplayDriver::graphics_interop_activate() +{ + gl_context_enable_(); +} + +void OpenGLDisplayDriver::graphics_interop_deactivate() +{ + gl_context_disable_(); +} + +/* -------------------------------------------------------------------- + * Drawing. + */ + +void OpenGLDisplayDriver::clear() +{ + texture_.need_clear = true; +} + +void OpenGLDisplayDriver::draw(const Params ¶ms) +{ + /* See do_update_begin() for why no locking is required here. */ + if (texture_.need_clear) { + /* Texture is requested to be cleared and was not yet cleared. + * Do early return which should be equivalent of drawing all-zero texture. */ + return; + } + + if (!gl_draw_resources_ensure()) { + return; + } + + if (gl_upload_sync_) { + glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED); + } + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + display_shader_.bind(params.full_size.x, params.full_size.y); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_.gl_id); + + if (texture_.width != params.size.x || texture_.height != params.size.y) { + /* Resolution divider is different from 1, force nearest interpolation. */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); + + texture_update_if_needed(); + vertex_buffer_update(params); + + GLuint vertex_array_object; + glGenVertexArrays(1, &vertex_array_object); + glBindVertexArray(vertex_array_object); + + const int texcoord_attribute = display_shader_.get_tex_coord_attrib_location(); + const int position_attribute = display_shader_.get_position_attrib_location(); + + glEnableVertexAttribArray(texcoord_attribute); + glEnableVertexAttribArray(position_attribute); + + glVertexAttribPointer( + texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0); + glVertexAttribPointer(position_attribute, + 2, + GL_FLOAT, + GL_FALSE, + 4 * sizeof(float), + (const GLvoid *)(sizeof(float) * 2)); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); + + glDeleteVertexArrays(1, &vertex_array_object); + + display_shader_.unbind(); + + glDisable(GL_BLEND); + + gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); +} + +bool OpenGLDisplayDriver::gl_draw_resources_ensure() +{ + if (!texture_.gl_id) { + /* If there is no texture allocated, there is nothing to draw. Inform the draw call that it can + * can not continue. Note that this is not an unrecoverable error, so once the texture is known + * we will come back here and create all the GPU resources needed for draw. */ + return false; + } + + if (gl_draw_resource_creation_attempted_) { + return gl_draw_resources_created_; + } + gl_draw_resource_creation_attempted_ = true; + + if (!vertex_buffer_) { + glGenBuffers(1, &vertex_buffer_); + if (!vertex_buffer_) { + LOG(ERROR) << "Error creating vertex buffer."; + return false; + } + } + + gl_draw_resources_created_ = true; + + return true; +} + +void OpenGLDisplayDriver::gl_resources_destroy() +{ + gl_context_enable_(); + + if (vertex_buffer_ != 0) { + glDeleteBuffers(1, &vertex_buffer_); + } + + if (texture_.gl_pbo_id) { + glDeleteBuffers(1, &texture_.gl_pbo_id); + texture_.gl_pbo_id = 0; + } + + if (texture_.gl_id) { + glDeleteTextures(1, &texture_.gl_id); + texture_.gl_id = 0; + } + + gl_context_disable_(); +} + +bool OpenGLDisplayDriver::gl_texture_resources_ensure() +{ + if (texture_.creation_attempted) { + return texture_.is_created; + } + texture_.creation_attempted = true; + + DCHECK(!texture_.gl_id); + DCHECK(!texture_.gl_pbo_id); + + /* Create texture. */ + glGenTextures(1, &texture_.gl_id); + if (!texture_.gl_id) { + LOG(ERROR) << "Error creating texture."; + return false; + } + + /* Configure the texture. */ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_.gl_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glBindTexture(GL_TEXTURE_2D, 0); + + /* Create PBO for the texture. */ + glGenBuffers(1, &texture_.gl_pbo_id); + if (!texture_.gl_pbo_id) { + LOG(ERROR) << "Error creating texture pixel buffer object."; + return false; + } + + /* Creation finished with a success. */ + texture_.is_created = true; + + return true; +} + +void OpenGLDisplayDriver::texture_update_if_needed() +{ + if (!texture_.need_update) { + return; + } + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id); + glTexSubImage2D( + GL_TEXTURE_2D, 0, 0, 0, texture_.width, texture_.height, GL_RGBA, GL_HALF_FLOAT, 0); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + texture_.need_update = false; +} + +void OpenGLDisplayDriver::vertex_buffer_update(const Params ¶ms) +{ + /* Invalidate old contents - avoids stalling if the buffer is still waiting in queue to be + * rendered. */ + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW); + + float *vpointer = reinterpret_cast<float *>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)); + if (!vpointer) { + return; + } + + vpointer[0] = 0.0f; + vpointer[1] = 0.0f; + vpointer[2] = params.full_offset.x; + vpointer[3] = params.full_offset.y; + + vpointer[4] = 1.0f; + vpointer[5] = 0.0f; + vpointer[6] = (float)params.size.x + params.full_offset.x; + vpointer[7] = params.full_offset.y; + + vpointer[8] = 1.0f; + vpointer[9] = 1.0f; + vpointer[10] = (float)params.size.x + params.full_offset.x; + vpointer[11] = (float)params.size.y + params.full_offset.y; + + vpointer[12] = 0.0f; + vpointer[13] = 1.0f; + vpointer[14] = params.full_offset.x; + vpointer[15] = (float)params.size.y + params.full_offset.y; + + glUnmapBuffer(GL_ARRAY_BUFFER); +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/app/opengl/display_driver.h b/intern/cycles/app/opengl/display_driver.h new file mode 100644 index 00000000000..92578412d68 --- /dev/null +++ b/intern/cycles/app/opengl/display_driver.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#pragma once + +#include <atomic> + +#include "app/opengl/shader.h" + +#include "session/display_driver.h" + +#include "util/function.h" +#include "util/unique_ptr.h" + +CCL_NAMESPACE_BEGIN + +class OpenGLDisplayDriver : public DisplayDriver { + public: + /* Callbacks for enabling and disabling the OpenGL context. Must be provided to support enabling + * the context on the Cycles render thread independent of the main thread. */ + OpenGLDisplayDriver(const function<bool()> &gl_context_enable, + const function<void()> &gl_context_disable); + ~OpenGLDisplayDriver(); + + virtual void graphics_interop_activate() override; + virtual void graphics_interop_deactivate() override; + + virtual void clear() override; + + void set_zoom(float zoom_x, float zoom_y); + + protected: + virtual void next_tile_begin() override; + + virtual bool update_begin(const Params ¶ms, int texture_width, int texture_height) override; + virtual void update_end() override; + + virtual half4 *map_texture_buffer() override; + virtual void unmap_texture_buffer() override; + + virtual GraphicsInterop graphics_interop_get() override; + + virtual void draw(const Params ¶ms) override; + + /* Make sure texture is allocated and its initial configuration is performed. */ + bool gl_texture_resources_ensure(); + + /* Ensure all runtime GPU resources needed for drawing are allocated. + * Returns true if all resources needed for drawing are available. */ + bool gl_draw_resources_ensure(); + + /* Destroy all GPU resources which are being used by this object. */ + void gl_resources_destroy(); + + /* Update GPU texture dimensions and content if needed (new pixel data was provided). + * + * NOTE: The texture needs to be bound. */ + void texture_update_if_needed(); + + /* Update vertex buffer with new coordinates of vertex positions and texture coordinates. + * This buffer is used to render texture in the viewport. + * + * NOTE: The buffer needs to be bound. */ + void vertex_buffer_update(const Params ¶ms); + + /* Texture which contains pixels of the render result. */ + struct { + /* Indicates whether texture creation was attempted and succeeded. + * Used to avoid multiple attempts of texture creation on GPU issues or GPU context + * misconfiguration. */ + bool creation_attempted = false; + bool is_created = false; + + /* OpenGL resource IDs of the texture itself and Pixel Buffer Object (PBO) used to write + * pixels to it. + * + * NOTE: Allocated on the engine's context. */ + uint gl_id = 0; + uint gl_pbo_id = 0; + + /* Is true when new data was written to the PBO, meaning, the texture might need to be resized + * and new data is to be uploaded to the GPU. */ + bool need_update = false; + + /* Content of the texture is to be filled with zeroes. */ + std::atomic<bool> need_clear = true; + + /* Dimensions of the texture in pixels. */ + int width = 0; + int height = 0; + + /* Dimensions of the underlying PBO. */ + int buffer_width = 0; + int buffer_height = 0; + } texture_; + + OpenGLShader display_shader_; + + /* Special track of whether GPU resources were attempted to be created, to avoid attempts of + * their re-creation on failure on every redraw. */ + bool gl_draw_resource_creation_attempted_ = false; + bool gl_draw_resources_created_ = false; + + /* Vertex buffer which hold vertices of a triangle fan which is textures with the texture + * holding the render result. */ + uint vertex_buffer_ = 0; + + void *gl_render_sync_ = nullptr; + void *gl_upload_sync_ = nullptr; + + float2 zoom_ = make_float2(1.0f, 1.0f); + + function<bool()> gl_context_enable_ = nullptr; + function<void()> gl_context_disable_ = nullptr; +}; + +CCL_NAMESPACE_END diff --git a/intern/cycles/app/opengl/shader.cpp b/intern/cycles/app/opengl/shader.cpp new file mode 100644 index 00000000000..9db9ea7fce9 --- /dev/null +++ b/intern/cycles/app/opengl/shader.cpp @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#include "app/opengl/shader.h" + +#include "util/log.h" +#include "util/string.h" + +#include <GL/glew.h> + +CCL_NAMESPACE_BEGIN + +/* -------------------------------------------------------------------- + * OpenGLShader. + */ + +static const char *VERTEX_SHADER = + "#version 330\n" + "uniform vec2 fullscreen;\n" + "in vec2 texCoord;\n" + "in vec2 pos;\n" + "out vec2 texCoord_interp;\n" + "\n" + "vec2 normalize_coordinates()\n" + "{\n" + " return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n" + "}\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n" + " texCoord_interp = texCoord;\n" + "}\n\0"; + +static const char *FRAGMENT_SHADER = + "#version 330\n" + "uniform sampler2D image_texture;\n" + "in vec2 texCoord_interp;\n" + "out vec4 fragColor;\n" + "\n" + "void main()\n" + "{\n" + " vec4 rgba = texture(image_texture, texCoord_interp);\n" + /* Harcoded Rec.709 gamma, should use OpenColorIO eventually. */ + " fragColor = pow(rgba, vec4(0.45, 0.45, 0.45, 1.0));\n" + "}\n\0"; + +static void shader_print_errors(const char *task, const char *log, const char *code) +{ + LOG(ERROR) << "Shader: " << task << " error:"; + LOG(ERROR) << "===== shader string ===="; + + stringstream stream(code); + string partial; + + int line = 1; + while (getline(stream, partial, '\n')) { + if (line < 10) { + LOG(ERROR) << " " << line << " " << partial; + } + else { + LOG(ERROR) << line << " " << partial; + } + line++; + } + LOG(ERROR) << log; +} + +static int compile_shader_program(void) +{ + const struct Shader { + const char *source; + const GLenum type; + } shaders[2] = {{VERTEX_SHADER, GL_VERTEX_SHADER}, {FRAGMENT_SHADER, GL_FRAGMENT_SHADER}}; + + const GLuint program = glCreateProgram(); + + for (int i = 0; i < 2; i++) { + const GLuint shader = glCreateShader(shaders[i].type); + + string source_str = shaders[i].source; + const char *c_str = source_str.c_str(); + + glShaderSource(shader, 1, &c_str, NULL); + glCompileShader(shader); + + GLint compile_status; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); + + if (!compile_status) { + GLchar log[5000]; + GLsizei length = 0; + glGetShaderInfoLog(shader, sizeof(log), &length, log); + shader_print_errors("compile", log, c_str); + return 0; + } + + glAttachShader(program, shader); + } + + /* Link output. */ + glBindFragDataLocation(program, 0, "fragColor"); + + /* Link and error check. */ + glLinkProgram(program); + + GLint link_status; + glGetProgramiv(program, GL_LINK_STATUS, &link_status); + if (!link_status) { + GLchar log[5000]; + GLsizei length = 0; + glGetShaderInfoLog(program, sizeof(log), &length, log); + shader_print_errors("linking", log, VERTEX_SHADER); + shader_print_errors("linking", log, FRAGMENT_SHADER); + return 0; + } + + return program; +} + +int OpenGLShader::get_position_attrib_location() +{ + if (position_attribute_location_ == -1) { + const uint shader_program = get_shader_program(); + position_attribute_location_ = glGetAttribLocation(shader_program, position_attribute_name); + } + return position_attribute_location_; +} + +int OpenGLShader::get_tex_coord_attrib_location() +{ + if (tex_coord_attribute_location_ == -1) { + const uint shader_program = get_shader_program(); + tex_coord_attribute_location_ = glGetAttribLocation(shader_program, tex_coord_attribute_name); + } + return tex_coord_attribute_location_; +} + +void OpenGLShader::bind(int width, int height) +{ + create_shader_if_needed(); + + if (!shader_program_) { + return; + } + + glUseProgram(shader_program_); + glUniform1i(image_texture_location_, 0); + glUniform2f(fullscreen_location_, width, height); +} + +void OpenGLShader::unbind() +{ +} + +uint OpenGLShader::get_shader_program() +{ + return shader_program_; +} + +void OpenGLShader::create_shader_if_needed() +{ + if (shader_program_ || shader_compile_attempted_) { + return; + } + + shader_compile_attempted_ = true; + + shader_program_ = compile_shader_program(); + if (!shader_program_) { + return; + } + + glUseProgram(shader_program_); + + image_texture_location_ = glGetUniformLocation(shader_program_, "image_texture"); + if (image_texture_location_ < 0) { + LOG(ERROR) << "Shader doesn't contain the 'image_texture' uniform."; + destroy_shader(); + return; + } + + fullscreen_location_ = glGetUniformLocation(shader_program_, "fullscreen"); + if (fullscreen_location_ < 0) { + LOG(ERROR) << "Shader doesn't contain the 'fullscreen' uniform."; + destroy_shader(); + return; + } +} + +void OpenGLShader::destroy_shader() +{ + glDeleteProgram(shader_program_); + shader_program_ = 0; +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/app/opengl/shader.h b/intern/cycles/app/opengl/shader.h new file mode 100644 index 00000000000..6ca121ca6ff --- /dev/null +++ b/intern/cycles/app/opengl/shader.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 OpenGL Foundation */ + +#pragma once + +#include "util/types.h" + +CCL_NAMESPACE_BEGIN + +class OpenGLShader { + public: + static constexpr const char *position_attribute_name = "pos"; + static constexpr const char *tex_coord_attribute_name = "texCoord"; + + OpenGLShader() = default; + virtual ~OpenGLShader() = default; + + /* Get attribute location for position and texture coordinate respectively. + * NOTE: The shader needs to be bound to have access to those. */ + int get_position_attrib_location(); + int get_tex_coord_attrib_location(); + + void bind(int width, int height); + void unbind(); + + protected: + uint get_shader_program(); + + void create_shader_if_needed(); + void destroy_shader(); + + /* Cached values of various OpenGL resources. */ + int position_attribute_location_ = -1; + int tex_coord_attribute_location_ = -1; + + uint shader_program_ = 0; + int image_texture_location_ = -1; + int fullscreen_location_ = -1; + + /* Shader compilation attempted. Which means, that if the shader program is 0 then compilation or + * linking has failed. Do not attempt to re-compile the shader. */ + bool shader_compile_attempted_ = false; +}; + +CCL_NAMESPACE_END diff --git a/intern/cycles/app/opengl/window.cpp b/intern/cycles/app/opengl/window.cpp new file mode 100644 index 00000000000..7351ae3eecd --- /dev/null +++ b/intern/cycles/app/opengl/window.cpp @@ -0,0 +1,352 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#include <stdio.h> +#include <stdlib.h> + +#include "app/opengl/window.h" + +#include "util/string.h" +#include "util/thread.h" +#include "util/time.h" +#include "util/version.h" + +#include <GL/glew.h> +#include <SDL.h> + +CCL_NAMESPACE_BEGIN + +/* structs */ + +struct Window { + WindowInitFunc initf = nullptr; + WindowExitFunc exitf = nullptr; + WindowResizeFunc resize = nullptr; + WindowDisplayFunc display = nullptr; + WindowKeyboardFunc keyboard = nullptr; + WindowMotionFunc motion = nullptr; + + bool first_display = true; + bool redraw = false; + + int mouseX = 0, mouseY = 0; + int mouseBut0 = 0, mouseBut2 = 0; + + int width = 0, height = 0; + + SDL_Window *window = nullptr; + SDL_GLContext gl_context = nullptr; + thread_mutex gl_context_mutex; +} V; + +/* public */ + +static void window_display_text(int x, int y, const char *text) +{ +/* Not currently supported, need to add text rendering support. */ +#if 0 + const char *c; + + glRasterPos3f(x, y, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + printf("display %s\n", text); + + for (c = text; *c != '\0'; c++) { + const uint8_t *bitmap = helvetica10_character_map[*c]; + glBitmap(bitmap[0], + helvetica10_height, + helvetica10_x_offset, + helvetica10_y_offset, + bitmap[0], + 0.0f, + bitmap + 1); + } +#else + static string last_text = ""; + + if (text != last_text) { + printf("%s\n", text); + last_text = text; + } +#endif +} + +void window_display_info(const char *info) +{ + const int height = 20; + +#if 0 + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.1f, 0.1f, 0.1f, 0.8f); + glRectf(0.0f, V.height - height, V.width, V.height); + glDisable(GL_BLEND); + + glColor3f(0.5f, 0.5f, 0.5f); +#endif + + window_display_text(10, 7 + V.height - height, info); + +#if 0 + glColor3f(1.0f, 1.0f, 1.0f); +#endif +} + +void window_display_help() +{ + const int w = (int)((float)V.width / 1.15f); + const int h = (int)((float)V.height / 1.15f); + + const int x1 = (V.width - w) / 2; +#if 0 + const int x2 = x1 + w; +#endif + + const int y1 = (V.height - h) / 2; + const int y2 = y1 + h; + +#if 0 + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.5f, 0.5f, 0.5f, 0.8f); + glRectf(x1, y1, x2, y2); + glDisable(GL_BLEND); + + glColor3f(0.8f, 0.8f, 0.8f); +#endif + + string info = string("Cycles Renderer ") + CYCLES_VERSION_STRING; + + window_display_text(x1 + 20, y2 - 20, info.c_str()); + window_display_text(x1 + 20, y2 - 40, "(C) 2011-2016 Blender Foundation"); + window_display_text(x1 + 20, y2 - 80, "Controls:"); + window_display_text(x1 + 20, y2 - 100, "h: Info/Help"); + window_display_text(x1 + 20, y2 - 120, "r: Reset"); + window_display_text(x1 + 20, y2 - 140, "p: Pause"); + window_display_text(x1 + 20, y2 - 160, "esc: Cancel"); + window_display_text(x1 + 20, y2 - 180, "q: Quit program"); + + window_display_text(x1 + 20, y2 - 210, "i: Interactive mode"); + window_display_text(x1 + 20, y2 - 230, "Left mouse: Move camera"); + window_display_text(x1 + 20, y2 - 250, "Right mouse: Rotate camera"); + window_display_text(x1 + 20, y2 - 270, "W/A/S/D: Move camera"); + window_display_text(x1 + 20, y2 - 290, "0/1/2/3: Set max bounces"); + +#if 0 + glColor3f(1.0f, 1.0f, 1.0f); +#endif +} + +static void window_display() +{ + if (V.first_display) { + if (V.initf) { + V.initf(); + } + if (V.exitf) { + atexit(V.exitf); + } + + V.first_display = false; + } + + window_opengl_context_enable(); + + glViewport(0, 0, V.width, V.height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glClearColor(0.05f, 0.05f, 0.05f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, V.width, 0, V.height, -1, 1); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glRasterPos3f(0, 0, 0); + + if (V.display) + V.display(); + + SDL_GL_SwapWindow(V.window); + window_opengl_context_disable(); +} + +static void window_reshape(int width, int height) +{ + if (V.width != width || V.height != height) { + if (V.resize) { + V.resize(width, height); + } + } + + V.width = width; + V.height = height; +} + +static bool window_keyboard(unsigned char key) +{ + if (V.keyboard) + V.keyboard(key); + + if (key == 'q') { + if (V.exitf) + V.exitf(); + return true; + } + + return false; +} + +static void window_mouse(int button, int state, int x, int y) +{ + if (button == SDL_BUTTON_LEFT) { + if (state == SDL_MOUSEBUTTONDOWN) { + V.mouseX = x; + V.mouseY = y; + V.mouseBut0 = 1; + } + else if (state == SDL_MOUSEBUTTONUP) { + V.mouseBut0 = 0; + } + } + else if (button == SDL_BUTTON_RIGHT) { + if (state == SDL_MOUSEBUTTONDOWN) { + V.mouseX = x; + V.mouseY = y; + V.mouseBut2 = 1; + } + else if (state == SDL_MOUSEBUTTONUP) { + V.mouseBut2 = 0; + } + } +} + +static void window_motion(int x, int y) +{ + const int but = V.mouseBut0 ? 0 : 2; + const int distX = x - V.mouseX; + const int distY = y - V.mouseY; + + if (V.motion) + V.motion(distX, distY, but); + + V.mouseX = x; + V.mouseY = y; +} + +bool window_opengl_context_enable() +{ + V.gl_context_mutex.lock(); + SDL_GL_MakeCurrent(V.window, V.gl_context); + return true; +} + +void window_opengl_context_disable() +{ + SDL_GL_MakeCurrent(V.window, nullptr); + V.gl_context_mutex.unlock(); +} + +void window_main_loop(const char *title, + int width, + int height, + WindowInitFunc initf, + WindowExitFunc exitf, + WindowResizeFunc resize, + WindowDisplayFunc display, + WindowKeyboardFunc keyboard, + WindowMotionFunc motion) +{ + V.width = width; + V.height = height; + V.first_display = true; + V.redraw = false; + V.initf = initf; + V.exitf = exitf; + V.resize = resize; + V.display = display; + V.keyboard = keyboard; + V.motion = motion; + + SDL_Init(SDL_INIT_VIDEO); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); + V.window = SDL_CreateWindow(title, + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + width, + height, + SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); + if (V.window == nullptr) { + fprintf(stderr, "Failed to create window: %s\n", SDL_GetError()); + return; + } + + SDL_RaiseWindow(V.window); + + V.gl_context = SDL_GL_CreateContext(V.window); + glewInit(); + SDL_GL_MakeCurrent(V.window, nullptr); + + window_reshape(width, height); + window_display(); + + while (true) { + bool quit = false; + SDL_Event event; + while (!quit && SDL_PollEvent(&event)) { + if (event.type == SDL_TEXTINPUT) { + quit = window_keyboard(event.text.text[0]); + } + else if (event.type == SDL_MOUSEMOTION) { + window_motion(event.motion.x, event.motion.y); + } + else if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) { + window_mouse(event.button.button, event.button.state, event.button.x, event.button.y); + } + else if (event.type == SDL_WINDOWEVENT) { + if (event.window.event == SDL_WINDOWEVENT_RESIZED || + event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { + window_reshape(event.window.data1, event.window.data2); + } + } + else if (event.type == SDL_QUIT) { + if (V.exitf) { + V.exitf(); + } + quit = true; + } + } + + if (quit) { + break; + } + + if (V.redraw) { + V.redraw = false; + window_display(); + } + + SDL_WaitEventTimeout(NULL, 100); + } + + SDL_GL_DeleteContext(V.gl_context); + SDL_DestroyWindow(V.window); + SDL_Quit(); +} + +void window_redraw() +{ + V.redraw = true; +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/app/opengl/window.h b/intern/cycles/app/opengl/window.h new file mode 100644 index 00000000000..531b5cab3fc --- /dev/null +++ b/intern/cycles/app/opengl/window.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#pragma once + +/* Functions to display a simple OpenGL window using SDL, simplified to the + * bare minimum we need to reduce boilerplate code in tests apps. */ + +CCL_NAMESPACE_BEGIN + +typedef void (*WindowInitFunc)(); +typedef void (*WindowExitFunc)(); +typedef void (*WindowResizeFunc)(int width, int height); +typedef void (*WindowDisplayFunc)(); +typedef void (*WindowKeyboardFunc)(unsigned char key); +typedef void (*WindowMotionFunc)(int x, int y, int button); + +void window_main_loop(const char *title, + int width, + int height, + WindowInitFunc initf, + WindowExitFunc exitf, + WindowResizeFunc resize, + WindowDisplayFunc display, + WindowKeyboardFunc keyboard, + WindowMotionFunc motion); + +void window_display_info(const char *info); +void window_display_help(); +void window_redraw(); + +bool window_opengl_context_enable(); +void window_opengl_context_disable(); + +CCL_NAMESPACE_END diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake index c964fbe0d72..6ad64d684c0 100644 --- a/intern/cycles/cmake/external_libs.cmake +++ b/intern/cycles/cmake/external_libs.cmake @@ -479,26 +479,22 @@ else() endif() ########################################################################### -# GLUT +# SDL ########################################################################### if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI) - if(MSVC AND EXISTS ${_cycles_lib_dir}) - add_definitions(-DFREEGLUT_STATIC -DFREEGLUT_LIB_PRAGMAS=0) - set(GLUT_LIBRARIES "${_cycles_lib_dir}/opengl/lib/freeglut_static.lib") - set(GLUT_INCLUDE_DIR "${_cycles_lib_dir}/opengl/include") - else() - find_package(GLUT) + # We can't use the version from the Blender precompiled libraries because + # it does not include the video subsystem. + find_package(SDL2) - if(NOT GLUT_FOUND) - set(WITH_CYCLES_STANDALONE_GUI OFF) - message(STATUS "GLUT not found, disabling Cycles standalone GUI") - endif() + if(NOT SDL2_FOUND) + set(WITH_CYCLES_STANDALONE_GUI OFF) + message(STATUS "SDL not found, disabling Cycles standalone GUI") endif() include_directories( SYSTEM - ${GLUT_INCLUDE_DIR} + ${SDL2_INCLUDE_DIRS} ) endif() diff --git a/intern/cycles/device/hip/device_impl.h b/intern/cycles/device/hip/device_impl.h index 00269ac287c..9afef3789af 100644 --- a/intern/cycles/device/hip/device_impl.h +++ b/intern/cycles/device/hip/device_impl.h @@ -12,8 +12,6 @@ # ifdef WITH_HIP_DYNLOAD # include "hipew.h" -# else -# include "util/opengl.h" # endif CCL_NAMESPACE_BEGIN diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt index 0e348b1ac0f..fddac1dbbcf 100644 --- a/intern/cycles/util/CMakeLists.txt +++ b/intern/cycles/util/CMakeLists.txt @@ -7,7 +7,6 @@ set(INC ) set(INC_SYS - ${GLEW_INCLUDE_DIR} ) set(SRC @@ -34,14 +33,6 @@ set(LIB ${TBB_LIBRARIES} ) -if(WITH_CYCLES_STANDALONE) - if(WITH_CYCLES_STANDALONE_GUI) - list(APPEND SRC - view.cpp - ) - endif() -endif() - set(SRC_HEADERS algorithm.h aligned_malloc.h @@ -142,7 +133,6 @@ set(SRC_HEADERS unique_ptr.h vector.h version.h - view.h windows.h xml.h ) diff --git a/intern/cycles/util/view.cpp b/intern/cycles/util/view.cpp deleted file mode 100644 index 475f8dbcee8..00000000000 --- a/intern/cycles/util/view.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -#include <stdio.h> -#include <stdlib.h> - -#include "util/opengl.h" -#include "util/string.h" -#include "util/time.h" -#include "util/version.h" -#include "util/view.h" - -#ifdef __APPLE__ -# include <GLUT/glut.h> -#else -# include <GL/glut.h> -#endif - -CCL_NAMESPACE_BEGIN - -/* structs */ - -struct View { - ViewInitFunc initf; - ViewExitFunc exitf; - ViewResizeFunc resize; - ViewDisplayFunc display; - ViewKeyboardFunc keyboard; - ViewMotionFunc motion; - - bool first_display; - bool redraw; - - int mouseX, mouseY; - int mouseBut0, mouseBut2; - - int width, height; -} V; - -/* public */ - -static void view_display_text(int x, int y, const char *text) -{ - const char *c; - - glRasterPos3f(x, y, 0); - - for (c = text; *c != '\0'; c++) - glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *c); -} - -void view_display_info(const char *info) -{ - const int height = 20; - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0.1f, 0.1f, 0.1f, 0.8f); - glRectf(0.0f, V.height - height, V.width, V.height); - glDisable(GL_BLEND); - - glColor3f(0.5f, 0.5f, 0.5f); - - view_display_text(10, 7 + V.height - height, info); - - glColor3f(1.0f, 1.0f, 1.0f); -} - -void view_display_help() -{ - const int w = (int)((float)V.width / 1.15f); - const int h = (int)((float)V.height / 1.15f); - - const int x1 = (V.width - w) / 2; - const int x2 = x1 + w; - - const int y1 = (V.height - h) / 2; - const int y2 = y1 + h; - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0.5f, 0.5f, 0.5f, 0.8f); - glRectf(x1, y1, x2, y2); - glDisable(GL_BLEND); - - glColor3f(0.8f, 0.8f, 0.8f); - - string info = string("Cycles Renderer ") + CYCLES_VERSION_STRING; - - view_display_text(x1 + 20, y2 - 20, info.c_str()); - view_display_text(x1 + 20, y2 - 40, "(C) 2011-2022 Blender Foundation"); - view_display_text(x1 + 20, y2 - 80, "Controls:"); - view_display_text(x1 + 20, y2 - 100, "h: Info/Help"); - view_display_text(x1 + 20, y2 - 120, "r: Reset"); - view_display_text(x1 + 20, y2 - 140, "p: Pause"); - view_display_text(x1 + 20, y2 - 160, "esc: Cancel"); - view_display_text(x1 + 20, y2 - 180, "q: Quit program"); - - view_display_text(x1 + 20, y2 - 210, "i: Interactive mode"); - view_display_text(x1 + 20, y2 - 230, "Left mouse: Move camera"); - view_display_text(x1 + 20, y2 - 250, "Right mouse: Rotate camera"); - view_display_text(x1 + 20, y2 - 270, "W/A/S/D: Move camera"); - view_display_text(x1 + 20, y2 - 290, "0/1/2/3: Set max bounces"); - - glColor3f(1.0f, 1.0f, 1.0f); -} - -static void view_display() -{ - if (V.first_display) { - if (V.initf) - V.initf(); - if (V.exitf) - atexit(V.exitf); - - V.first_display = false; - } - - glClearColor(0.05f, 0.05f, 0.05f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, V.width, 0, V.height, -1, 1); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glRasterPos3f(0, 0, 0); - - if (V.display) - V.display(); - - glutSwapBuffers(); -} - -static void view_reshape(int width, int height) -{ - if (width <= 0 || height <= 0) - return; - - V.width = width; - V.height = height; - - glViewport(0, 0, width, height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - if (V.resize) - V.resize(width, height); -} - -static void view_keyboard(unsigned char key, int x, int y) -{ - if (V.keyboard) - V.keyboard(key); - - if (key == 'm') - printf("mouse %d %d\n", x, y); - if (key == 'q') { - if (V.exitf) - V.exitf(); - exit(0); - } -} - -static void view_mouse(int button, int state, int x, int y) -{ - if (button == 0) { - if (state == GLUT_DOWN) { - V.mouseX = x; - V.mouseY = y; - V.mouseBut0 = 1; - } - else if (state == GLUT_UP) { - V.mouseBut0 = 0; - } - } - else if (button == 2) { - if (state == GLUT_DOWN) { - V.mouseX = x; - V.mouseY = y; - V.mouseBut2 = 1; - } - else if (state == GLUT_UP) { - V.mouseBut2 = 0; - } - } -} - -static void view_motion(int x, int y) -{ - const int but = V.mouseBut0 ? 0 : 2; - const int distX = x - V.mouseX; - const int distY = y - V.mouseY; - - if (V.motion) - V.motion(distX, distY, but); - - V.mouseX = x; - V.mouseY = y; -} - -static void view_idle() -{ - if (V.redraw) { - V.redraw = false; - glutPostRedisplay(); - } - - time_sleep(0.1); -} - -void view_main_loop(const char *title, - int width, - int height, - ViewInitFunc initf, - ViewExitFunc exitf, - ViewResizeFunc resize, - ViewDisplayFunc display, - ViewKeyboardFunc keyboard, - ViewMotionFunc motion) -{ - const char *name = "app"; - char *argv = (char *)name; - int argc = 1; - - memset(&V, 0, sizeof(V)); - V.width = width; - V.height = height; - V.first_display = true; - V.redraw = false; - V.initf = initf; - V.exitf = exitf; - V.resize = resize; - V.display = display; - V.keyboard = keyboard; - V.motion = motion; - - glutInit(&argc, &argv); - glutInitWindowSize(width, height); - glutInitWindowPosition(0, 0); - glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); - glutCreateWindow(title); - - glewInit(); - - view_reshape(width, height); - - glutDisplayFunc(view_display); - glutIdleFunc(view_idle); - glutReshapeFunc(view_reshape); - glutKeyboardFunc(view_keyboard); - glutMouseFunc(view_mouse); - glutMotionFunc(view_motion); - - glutMainLoop(); -} - -void view_redraw() -{ - V.redraw = true; -} - -CCL_NAMESPACE_END diff --git a/intern/cycles/util/view.h b/intern/cycles/util/view.h deleted file mode 100644 index 51c242c21f7..00000000000 --- a/intern/cycles/util/view.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -#ifndef __UTIL_VIEW_H__ -#define __UTIL_VIEW_H__ - -/* Functions to display a simple OpenGL window using GLUT, simplified to the - * bare minimum we need to reduce boilerplate code in tests apps. */ - -CCL_NAMESPACE_BEGIN - -typedef void (*ViewInitFunc)(); -typedef void (*ViewExitFunc)(); -typedef void (*ViewResizeFunc)(int width, int height); -typedef void (*ViewDisplayFunc)(); -typedef void (*ViewKeyboardFunc)(unsigned char key); -typedef void (*ViewMotionFunc)(int x, int y, int button); - -void view_main_loop(const char *title, - int width, - int height, - ViewInitFunc initf, - ViewExitFunc exitf, - ViewResizeFunc resize, - ViewDisplayFunc display, - ViewKeyboardFunc keyboard, - ViewMotionFunc motion); - -void view_display_info(const char *info); -void view_display_help(); -void view_redraw(); - -CCL_NAMESPACE_END - -#endif /*__UTIL_VIEW_H__*/ diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 16e3f32e88a..5b840fae341 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -780,7 +780,7 @@ class IMAGE_HT_header(Header): layout.template_edit_mode_selection() else: layout.prop(tool_settings, "uv_select_mode", text="", expand=True) - layout.prop(uvedit, "sticky_select_mode", icon_only=True) + layout.prop(tool_settings, "uv_sticky_select_mode", icon_only=True) IMAGE_MT_editor_menus.draw_collapsible(context, layout) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index e93d9179f82..61ba6189be4 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -823,7 +823,7 @@ class VIEW3D_MT_editor_menus(Menu): layout.menu("VIEW3D_MT_select_paint_mask") elif mesh.use_paint_mask_vertex and mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX'}: layout.menu("VIEW3D_MT_select_paint_mask_vertex") - elif mode_string not in ('SCULPT', 'SCULPT_CURVES'): + elif mode_string not in {'SCULPT', 'SCULPT_CURVES'}: layout.menu("VIEW3D_MT_select_%s" % mode_string.lower()) if gp_edit: @@ -866,7 +866,7 @@ class VIEW3D_MT_editor_menus(Menu): layout.menu("VIEW3D_MT_edit_curve_segments") elif obj: - if mode_string not in ('PAINT_TEXTURE', 'SCULPT_CURVES'): + if mode_string not in {'PAINT_TEXTURE', 'SCULPT_CURVES'}: layout.menu("VIEW3D_MT_%s" % mode_string.lower()) if mode_string == 'SCULPT': layout.menu("VIEW3D_MT_mask") diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index b448214ce28..ded64b68f79 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -88,7 +88,8 @@ struct KS_Path *BKE_keyingset_find_path(struct KeyingSet *ks, void BKE_keyingsets_copy(struct ListBase *newlist, const struct ListBase *list); /** Process the ID pointers inside a scene's keyingsets, in see `BKE_lib_query.h` for details. */ -void BKE_keyingsets_foreach_id(struct LibraryForeachIDData *data, const struct ListBase *keyingsets); +void BKE_keyingsets_foreach_id(struct LibraryForeachIDData *data, + const struct ListBase *keyingsets); /* Free the given Keying Set path */ void BKE_keyingset_free_path(struct KeyingSet *ks, struct KS_Path *ksp); diff --git a/source/blender/blenkernel/BKE_curves.h b/source/blender/blenkernel/BKE_curves.h index 7ad915b50d7..2cce15fbfd6 100644 --- a/source/blender/blenkernel/BKE_curves.h +++ b/source/blender/blenkernel/BKE_curves.h @@ -12,9 +12,9 @@ extern "C" { #endif struct BoundBox; +struct Curves; struct CustomDataLayer; struct Depsgraph; -struct Curves; struct Main; struct Object; struct Scene; diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h index a40a354eef7..e586bc4247d 100644 --- a/source/blender/blenkernel/BKE_gpencil.h +++ b/source/blender/blenkernel/BKE_gpencil.h @@ -16,6 +16,7 @@ struct Brush; struct CurveMapping; struct Depsgraph; struct GHash; +struct GPencilUpdateCache; struct ListBase; struct MDeformVert; struct Main; @@ -32,7 +33,6 @@ struct bGPDlayer; struct bGPDlayer_Mask; struct bGPDstroke; struct bGPdata; -struct GPencilUpdateCache; #define GPENCIL_SIMPLIFY(scene) (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ENABLE) #define GPENCIL_SIMPLIFY_ONPLAY(playing) \ diff --git a/source/blender/blenkernel/BKE_gpencil_update_cache.h b/source/blender/blenkernel/BKE_gpencil_update_cache.h index a4fd70eb883..52b8716bab5 100644 --- a/source/blender/blenkernel/BKE_gpencil_update_cache.h +++ b/source/blender/blenkernel/BKE_gpencil_update_cache.h @@ -14,11 +14,11 @@ extern "C" { #include "BLI_sys_types.h" /* for bool */ struct DLRBT_Tree; -struct bGPdata; -struct bGPDlayer; +struct GPencilUpdateCache; struct bGPDframe; +struct bGPDlayer; struct bGPDstroke; -struct GPencilUpdateCache; +struct bGPdata; /* GPencilUpdateCache.flag */ typedef enum eGPUpdateCacheNodeFlag { diff --git a/source/blender/blenkernel/BKE_image_partial_update.hh b/source/blender/blenkernel/BKE_image_partial_update.hh index 3804936d00f..45b08e17920 100644 --- a/source/blender/blenkernel/BKE_image_partial_update.hh +++ b/source/blender/blenkernel/BKE_image_partial_update.hh @@ -21,8 +21,8 @@ #include "DNA_image_types.h" extern "C" { -struct PartialUpdateUser; struct PartialUpdateRegister; +struct PartialUpdateUser; } namespace blender::bke::image { diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 9a212cb1275..acdca23b21c 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -409,14 +409,18 @@ void BKE_modifier_session_uuid_generate(struct ModifierData *md); bool BKE_modifier_unique_name(struct ListBase *modifiers, struct ModifierData *md); +struct ModifierData *BKE_modifier_copy_ex(const struct ModifierData *md, int flag); + /** * Callback's can use this to avoid copying every member. */ void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, int flag); -void BKE_modifier_copydata(struct ModifierData *md, struct ModifierData *target); -void BKE_modifier_copydata_ex(struct ModifierData *md, struct ModifierData *target, int flag); +void BKE_modifier_copydata(const struct ModifierData *md, struct ModifierData *target); +void BKE_modifier_copydata_ex(const struct ModifierData *md, + struct ModifierData *target, + int flag); bool BKE_modifier_depends_ontime(struct Scene *scene, struct ModifierData *md, int dag_eval_mode); bool BKE_modifier_supports_mapping(struct ModifierData *md); bool BKE_modifier_supports_cage(struct Scene *scene, struct ModifierData *md); diff --git a/source/blender/blenkernel/BKE_node_tree_update.h b/source/blender/blenkernel/BKE_node_tree_update.h index 7998a5ec017..5e377728bb7 100644 --- a/source/blender/blenkernel/BKE_node_tree_update.h +++ b/source/blender/blenkernel/BKE_node_tree_update.h @@ -7,12 +7,12 @@ */ struct ID; +struct ImageUser; struct Main; struct bNode; struct bNodeLink; struct bNodeSocket; struct bNodeTree; -struct ImageUser; #ifdef __cplusplus extern "C" { diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index fe3b1d0c306..16d43d40c50 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -2823,7 +2823,7 @@ void BKE_gpencil_frame_selected_hash(bGPdata *gpd, struct GHash *r_list) bool BKE_gpencil_can_avoid_full_copy_on_write(const Depsgraph *depsgraph, bGPdata *gpd) { - /* For now, we only use the update cache in the active depsgraph. Othwerwise we might access the + /* For now, we only use the update cache in the active depsgraph. Otherwise we might access the * cache while another depsgraph frees it. */ if (!DEG_is_active(depsgraph)) { return false; diff --git a/source/blender/blenkernel/intern/gpencil_update_cache.c b/source/blender/blenkernel/intern/gpencil_update_cache.c index 2258f8c353f..bbe576eb847 100644 --- a/source/blender/blenkernel/intern/gpencil_update_cache.c +++ b/source/blender/blenkernel/intern/gpencil_update_cache.c @@ -99,7 +99,7 @@ static void update_cache_node_create_ex(GPencilUpdateCache *root_cache, bool full_copy) { if (root_cache->flag == GP_UPDATE_NODE_FULL_COPY) { - /* Entire data-block has to be recaculated, e.g. nothing else needs to be added to the cache. + /* Entire data-block has to be recalculated, e.g. nothing else needs to be added to the cache. */ return; } @@ -110,14 +110,14 @@ static void update_cache_node_create_ex(GPencilUpdateCache *root_cache, root_cache->data = (bGPdata *)data; root_cache->flag = node_flag; if (full_copy) { - /* Entire data-block has to be recaculated, remove all caches of "lower" elements. */ + /* Entire data-block has to be recalculated, remove all caches of "lower" elements. */ BLI_dlrbTree_free(root_cache->children, cache_node_free); } return; } const bool is_layer_update_node = (gpf_index == -1); - /* If the data pointer in GPencilUpdateCache is NULL, this element is not actually cached + /* If the data pointer in #GPencilUpdateCache is NULL, this element is not actually cached * and does not need to be updated, but we do need the index to find elements that are in * levels below. E.g. if a stroke needs to be updated, the frame it is in would not hold a * pointer to it's data. */ @@ -174,7 +174,7 @@ static void update_cache_node_create( } if (root_cache->flag == GP_UPDATE_NODE_FULL_COPY) { - /* Entire data-block has to be recaculated, e.g. nothing else needs to be added to the cache. + /* Entire data-block has to be recalculated, e.g. nothing else needs to be added to the cache. */ return; } diff --git a/source/blender/blenkernel/intern/image_gpu.cc b/source/blender/blenkernel/intern/image_gpu.cc index 5675641deb4..444cbbe4bf9 100644 --- a/source/blender/blenkernel/intern/image_gpu.cc +++ b/source/blender/blenkernel/intern/image_gpu.cc @@ -431,7 +431,8 @@ static GPUTexture *image_get_gpu_texture(Image *ima, if (ibuf_intern == nullptr) { ibuf_intern = BKE_image_acquire_ibuf(ima, iuser, nullptr); if (ibuf_intern == nullptr) { - return image_gpu_texture_error_create(textarget); + *tex = image_gpu_texture_error_create(textarget); + return *tex; } } diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc index e1e4a12533a..9d5635f49ab 100644 --- a/source/blender/blenkernel/intern/image_partial_update.cc +++ b/source/blender/blenkernel/intern/image_partial_update.cc @@ -90,8 +90,8 @@ static int chunk_number_for_pixel(int pixel_offset) return chunk_offset; } -struct PartialUpdateUserImpl; struct PartialUpdateRegisterImpl; +struct PartialUpdateUserImpl; /** * Wrap PartialUpdateUserImpl to its C-struct (PartialUpdateUser). diff --git a/source/blender/blenkernel/intern/mesh_calc_edges.cc b/source/blender/blenkernel/intern/mesh_calc_edges.cc index 0524412e302..5895eb7fd71 100644 --- a/source/blender/blenkernel/intern/mesh_calc_edges.cc +++ b/source/blender/blenkernel/intern/mesh_calc_edges.cc @@ -7,6 +7,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" + #include "BLI_map.hh" #include "BLI_task.hh" #include "BLI_threads.h" diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index c3d819bf46e..121bfbff394 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -1041,7 +1041,7 @@ static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh) BKE_mesh_wrapper_ensure_mdata(mesh); } else { - BKE_mesh_wrapper_ensure_subdivision(object, mesh); + mesh = BKE_mesh_wrapper_ensure_subdivision(object, mesh); } Mesh *mesh_result = (Mesh *)BKE_id_copy_ex( @@ -1079,8 +1079,7 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, mask.pmask |= CD_MASK_ORIGINDEX; } Mesh *result = mesh_create_eval_final(depsgraph, scene, &object_for_eval, &mask); - BKE_mesh_wrapper_ensure_subdivision(object, result); - return result; + return BKE_mesh_wrapper_ensure_subdivision(object, result); } static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph, @@ -1223,6 +1222,9 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain, BKE_mesh_nomain_to_mesh(mesh, mesh_in_bmain, nullptr, &CD_MASK_MESH, true); + /* Anonymous attributes shouldn't exist on original data. */ + BKE_mesh_anonymous_attributes_remove(mesh_in_bmain); + /* User-count is required because so far mesh was in a limbo, where library management does * not perform any user management (i.e. copy of a mesh will not increase users of materials). */ BKE_library_foreach_ID_link( diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 46fea5ae115..837c1fe179f 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -131,7 +131,7 @@ void BKE_modifier_panel_expand(ModifierData *md) /***/ -ModifierData *BKE_modifier_new(int type) +static ModifierData *modifier_allocate_and_init(int type) { const ModifierTypeInfo *mti = BKE_modifier_get_info(type); ModifierData *md = MEM_callocN(mti->structSize, mti->structName); @@ -152,6 +152,13 @@ ModifierData *BKE_modifier_new(int type) mti->initData(md); } + return md; +} + +ModifierData *BKE_modifier_new(int type) +{ + ModifierData *md = modifier_allocate_and_init(type); + BKE_modifier_session_uuid_generate(md); return md; @@ -315,6 +322,16 @@ void BKE_modifiers_foreach_tex_link(Object *ob, TexWalkFunc walk, void *userData } } +ModifierData *BKE_modifier_copy_ex(const ModifierData *md, int flag) +{ + ModifierData *md_dst = modifier_allocate_and_init(md->type); + + BLI_strncpy(md_dst->name, md->name, sizeof(md_dst->name)); + BKE_modifier_copydata_ex(md, md_dst, flag); + + return md_dst; +} + void BKE_modifier_copydata_generic(const ModifierData *md_src, ModifierData *md_dst, const int UNUSED(flag)) @@ -348,7 +365,7 @@ static void modifier_copy_data_id_us_cb(void *UNUSED(userData), } } -void BKE_modifier_copydata_ex(ModifierData *md, ModifierData *target, const int flag) +void BKE_modifier_copydata_ex(const ModifierData *md, ModifierData *target, const int flag) { const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); @@ -378,7 +395,7 @@ void BKE_modifier_copydata_ex(ModifierData *md, ModifierData *target, const int } } -void BKE_modifier_copydata(ModifierData *md, ModifierData *target) +void BKE_modifier_copydata(const ModifierData *md, ModifierData *target) { BKE_modifier_copydata_ex(md, target, 0); } diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 579e61750f0..3a8d7d6bc8a 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -1599,9 +1599,7 @@ bool BKE_object_modifier_stack_copy(Object *ob_dst, continue; } - ModifierData *md_dst = BKE_modifier_new(md_src->type); - BLI_strncpy(md_dst->name, md_src->name, sizeof(md_dst->name)); - BKE_modifier_copydata_ex(md_src, md_dst, flag_subdata); + ModifierData *md_dst = BKE_modifier_copy_ex(md_src, flag_subdata); BLI_addtail(&ob_dst->modifiers, md_dst); } diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh index eac43506874..b6b3d15aefe 100644 --- a/source/blender/blenlib/BLI_math_vec_types.hh +++ b/source/blender/blenlib/BLI_math_vec_types.hh @@ -353,7 +353,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> friend vec_base operator/(const vec_base &a, const vec_base &b) { - BLI_assert(!math::is_any_zero()); + BLI_assert(!math::is_any_zero(b)); BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] / b[i]); } @@ -365,7 +365,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> friend vec_base operator/(T a, const vec_base &b) { - BLI_assert(!math::is_any_zero()); + BLI_assert(!math::is_any_zero(b)); BLI_VEC_OP_IMPL(ret, i, ret[i] = a / b[i]); } @@ -377,7 +377,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> vec_base &operator/=(const vec_base &b) { - BLI_assert(!b != T(0)); + BLI_assert(b != T(0)); BLI_VEC_OP_IMPL_SELF(i, (*this)[i] /= b[i]); } @@ -509,7 +509,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> BLI_INT_OP(T) friend vec_base operator%(const vec_base &a, const vec_base &b) { - BLI_assert(!math::is_any_zero()); + BLI_assert(!math::is_any_zero(b)); BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] % b[i]); } diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c index 485836eca72..e90a0ee02db 100644 --- a/source/blender/blenlib/intern/winstuff.c +++ b/source/blender/blenlib/intern/winstuff.c @@ -3,7 +3,7 @@ /** \file * \ingroup bli - * Windows-posix compatibility layer, windows-specific functions. + * WIN32-POSIX compatibility layer, MS-Windows-specific functions. */ #ifdef WIN32 diff --git a/source/blender/blenloader/BLO_undofile.h b/source/blender/blenloader/BLO_undofile.h index 49f7f62cb9b..48334444c4c 100644 --- a/source/blender/blenloader/BLO_undofile.h +++ b/source/blender/blenloader/BLO_undofile.h @@ -5,7 +5,7 @@ /** \file * \ingroup blenloader - * External writefile function prototypes. + * External write-file function prototypes. */ #include "BLI_filereader.h" diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl index e9525ce9de0..d8f8a1cc03f 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl @@ -254,31 +254,8 @@ void main() * Morgan McGuire and Kyle Whitson * http://graphics.cs.williams.edu * - * - * Copyright (c) Morgan McGuire and Williams College, 2006 - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-2-Clause + * Copyright 2006 Morgan McGuire and Williams College, All rights reserved. */ #ifdef BLUR2 diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 7efd0de7a44..ac2e5bbca2e 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -1340,8 +1340,9 @@ void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache, drw_subdiv_compute_dispatch(cache, shader, 0, dst_offset, cache->num_subdiv_quads); - /* This generates a vertex buffer, so we need to put a barrier on the vertex attribute array. */ - GPU_memory_barrier(GPU_BARRIER_VERTEX_ATTRIB_ARRAY); + /* This generates a vertex buffer, so we need to put a barrier on the vertex attribute array. Put + * a barrier on the shader storage as we may use the result in another compute shader. */ + GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE | GPU_BARRIER_VERTEX_ATTRIB_ARRAY); /* Cleanup. */ GPU_shader_unbind(); @@ -1422,6 +1423,28 @@ void draw_subdiv_finalize_normals(const DRWSubdivCache *cache, GPU_shader_unbind(); } +void draw_subdiv_finalize_custom_normals(const DRWSubdivCache *cache, + GPUVertBuf *src_custom_normals, + GPUVertBuf *pos_nor) +{ + GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_NORMALS_FINALIZE, "#define CUSTOM_NORMALS"); + GPU_shader_bind(shader); + + GPU_vertbuf_bind_as_ssbo(src_custom_normals, 0); + /* outputPosNor is bound at index 2 in the base shader. */ + GPU_vertbuf_bind_as_ssbo(pos_nor, 2); + + drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads); + + /* This generates a vertex buffer, so we need to put a barrier on the vertex attribute array. + * We also need it for subsequent compute shaders, so a barrier on the shader storage is also + * needed. */ + GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE | GPU_BARRIER_VERTEX_ATTRIB_ARRAY); + + /* Cleanup. */ + GPU_shader_unbind(); +} + void draw_subdiv_build_tris_buffer(const DRWSubdivCache *cache, GPUIndexBuf *subdiv_tris, const int material_count) @@ -1813,6 +1836,11 @@ static bool draw_subdiv_create_requested_buffers(const Scene *scene, /* We can only evaluate limit normals if the patches are adaptive. */ draw_cache->do_limit_normals = settings.is_adaptive; + draw_cache->use_custom_loop_normals = (smd->flags & eSubsurfModifierFlag_UseCustomNormals) && + (mesh_eval->flag & ME_AUTOSMOOTH) && + CustomData_has_layer(&mesh_eval->ldata, + CD_CUSTOMLOOPNORMAL); + if (DRW_ibo_requested(mbc->buff.ibo.tris)) { draw_subdiv_cache_ensure_mat_offsets(draw_cache, mesh_eval, batch_cache->mat_len); } diff --git a/source/blender/draw/intern/draw_subdivision.h b/source/blender/draw/intern/draw_subdivision.h index 394482c0862..6714ba571e5 100644 --- a/source/blender/draw/intern/draw_subdivision.h +++ b/source/blender/draw/intern/draw_subdivision.h @@ -52,6 +52,7 @@ typedef struct DRWSubdivCache { struct Subdiv *subdiv; bool optimal_display; bool do_limit_normals; + bool use_custom_loop_normals; /* Coordinates used to evaluate patches for UVs, positions, and normals. */ struct GPUVertBuf *patch_coords; @@ -171,6 +172,10 @@ void draw_subdiv_finalize_normals(const DRWSubdivCache *cache, struct GPUVertBuf *subdiv_loop_subdiv_vert_index, struct GPUVertBuf *pos_nor); +void draw_subdiv_finalize_custom_normals(const DRWSubdivCache *cache, + GPUVertBuf *src_custom_normals, + GPUVertBuf *pos_nor); + void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache, struct GPUVertBuf *pos_nor, bool do_limit_normals); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc index 6e2cb8ad3e3..bd7f1ba0128 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc @@ -200,6 +200,16 @@ static GPUVertFormat *get_normals_format() return &format; } +static GPUVertFormat *get_custom_normals_format() +{ + static GPUVertFormat format = {0}; + if (format.attr_len == 0) { + GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + GPU_vertformat_alias_add(&format, "lnor"); + } + return &format; +} + static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, struct MeshBatchCache *UNUSED(cache), @@ -207,7 +217,8 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache, void *UNUSED(data)) { GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer); - const bool do_limit_normals = subdiv_cache->do_limit_normals; + const bool do_limit_normals = subdiv_cache->do_limit_normals && + !subdiv_cache->use_custom_loop_normals; /* Initialize the vertex buffer, it was already allocated. */ GPU_vertbuf_init_build_on_device( @@ -215,7 +226,31 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache, draw_subdiv_extract_pos_nor(subdiv_cache, vbo, do_limit_normals); - if (!do_limit_normals) { + if (subdiv_cache->use_custom_loop_normals) { + Mesh *coarse_mesh = subdiv_cache->mesh; + float(*lnors)[3] = static_cast<float(*)[3]>( + CustomData_get_layer(&coarse_mesh->ldata, CD_NORMAL)); + BLI_assert(lnors != NULL); + + GPUVertBuf *src_custom_normals = GPU_vertbuf_calloc(); + GPU_vertbuf_init_with_format(src_custom_normals, get_custom_normals_format()); + GPU_vertbuf_data_alloc(src_custom_normals, coarse_mesh->totloop); + + memcpy( + GPU_vertbuf_get_data(src_custom_normals), lnors, sizeof(float[3]) * coarse_mesh->totloop); + + GPUVertBuf *dst_custom_normals = GPU_vertbuf_calloc(); + GPU_vertbuf_init_build_on_device( + dst_custom_normals, get_custom_normals_format(), subdiv_cache->num_subdiv_loops); + + draw_subdiv_interp_custom_data(subdiv_cache, src_custom_normals, dst_custom_normals, 3, 0); + + draw_subdiv_finalize_custom_normals(subdiv_cache, dst_custom_normals, vbo); + + GPU_vertbuf_discard(src_custom_normals); + GPU_vertbuf_discard(dst_custom_normals); + } + else if (!do_limit_normals) { /* We cannot evaluate vertex normals using the limit surface, so compute them manually. */ GPUVertBuf *subdiv_loop_subdiv_vert_index = draw_subdiv_build_origindex_buffer( subdiv_cache->subdiv_loop_subdiv_vert_index, subdiv_cache->num_subdiv_loops); diff --git a/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl index 36c3970d9a0..df0016761e2 100644 --- a/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl +++ b/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl @@ -185,7 +185,7 @@ void main() } else { /* Interpolate the src data for the center. */ - uint loop_end = loop_start + number_of_vertices - 1; + uint loop_end = loop_start + number_of_vertices; Vertex center_value; clear(center_value); @@ -202,7 +202,7 @@ void main() uint prev_coarse_corner = (current_coarse_corner + number_of_vertices - 1) % number_of_vertices; - v0 = read_vertex(loop_start); + v0 = read_vertex(loop_start + current_coarse_corner); v1 = average(v0, read_vertex(loop_start + next_coarse_corner)); v3 = average(v0, read_vertex(loop_start + prev_coarse_corner)); diff --git a/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl index 84cd65d4161..c2e0e752783 100644 --- a/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl +++ b/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl @@ -1,6 +1,18 @@ /* To be compile with common_subdiv_lib.glsl */ +#ifdef CUSTOM_NORMALS +struct CustomNormal { + float x; + float y; + float z; +}; + +layout(std430, binding = 0) readonly buffer inputNormals +{ + CustomNormal custom_normals[]; +}; +#else layout(std430, binding = 0) readonly buffer inputNormals { vec3 vertex_normals[]; @@ -10,6 +22,7 @@ layout(std430, binding = 1) readonly buffer inputSubdivVertLoopMap { uint vert_loop_map[]; }; +#endif layout(std430, binding = 2) buffer outputPosNor { @@ -26,9 +39,17 @@ void main() uint start_loop_index = quad_index * 4; +#ifdef CUSTOM_NORMALS + for (int i = 0; i < 4; i++) { + CustomNormal custom_normal = custom_normals[start_loop_index + i]; + vec3 nor = vec3(custom_normal.x, custom_normal.y, custom_normal.z); + set_vertex_nor(pos_nor[start_loop_index + i], normalize(nor)); + } +#else for (int i = 0; i < 4; i++) { uint subdiv_vert_index = vert_loop_map[start_loop_index + i]; vec3 nor = vertex_normals[subdiv_vert_index]; set_vertex_nor(pos_nor[start_loop_index + i], nor); } +#endif } diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c index 976c5988aa6..e8f097d0018 100644 --- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c +++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c @@ -1811,7 +1811,7 @@ static void gpencil_sculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA * gso->mval[1] = mouse[1] = (int)(mousef[1]); /* If the mouse/pen has not moved, no reason to continue. This also avoid a small - * drift due precision acumulation errors. */ + * drift due precision accumulation errors. */ if ((gso->mval[0] == gso->mval_prev[0]) && (gso->mval[1] == gso->mval_prev[1])) { return; } diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 87d5adda213..bd3a6bce8e8 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -15,9 +15,9 @@ extern "C" { #endif struct GPUBatch; +struct IDRemapper; struct Main; struct bContext; -struct IDRemapper; /* ed_util.c */ diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 0c9ddc97508..26af378b1b7 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -97,8 +97,7 @@ bool uvedit_face_select_test(const struct Scene *scene, struct BMFace *efa, int bool uvedit_edge_select_test(const struct Scene *scene, struct BMLoop *l, int cd_loop_uv_offset); bool uvedit_uv_select_test(const struct Scene *scene, struct BMLoop *l, int cd_loop_uv_offset); /* uv face */ -void uvedit_face_select_set_with_sticky(const struct SpaceImage *sima, - const struct Scene *scene, +void uvedit_face_select_set_with_sticky(const struct Scene *scene, struct BMEditMesh *em, struct BMFace *efa, bool select, @@ -120,8 +119,7 @@ void uvedit_face_select_disable(const struct Scene *scene, struct BMFace *efa, int cd_loop_uv_offset); /* uv edge */ -void uvedit_edge_select_set_with_sticky(const struct SpaceImage *sima, - const struct Scene *scene, +void uvedit_edge_select_set_with_sticky(const struct Scene *scene, struct BMEditMesh *em, struct BMLoop *l, bool select, @@ -143,8 +141,7 @@ void uvedit_edge_select_disable(const struct Scene *scene, struct BMLoop *l, int cd_loop_uv_offset); /* uv vert */ -void uvedit_uv_select_set_with_sticky(const struct SpaceImage *sima, - const struct Scene *scene, +void uvedit_uv_select_set_with_sticky(const struct Scene *scene, struct BMEditMesh *em, struct BMLoop *l, bool select, diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index db66aad4a7c..12215083eb6 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -6059,7 +6059,8 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) view_data = IDP_GetPropertyTypeFromGroup(idgroup, PROJ_VIEW_DATA_ID, IDP_ARRAY); /* type check to make sure its ok */ - if (view_data->len != PROJ_VIEW_DATA_SIZE || view_data->subtype != IDP_FLOAT) { + if (view_data != NULL && + (view_data->len != PROJ_VIEW_DATA_SIZE || view_data->subtype != IDP_FLOAT)) { BKE_report(op->reports, RPT_ERROR, "Image project data invalid"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_view3d/view3d_navigate.h b/source/blender/editors/space_view3d/view3d_navigate.h index 5fbfb3e9bd8..127d08580dc 100644 --- a/source/blender/editors/space_view3d/view3d_navigate.h +++ b/source/blender/editors/space_view3d/view3d_navigate.h @@ -14,15 +14,15 @@ #define V3D_OP_TRACKBALLSIZE (1.1f) struct ARegion; -struct bContext; struct Depsgraph; struct Dial; struct Main; -struct rcti; struct RegionView3D; struct Scene; struct ScrArea; struct View3D; +struct bContext; +struct rcti; struct wmEvent; struct wmOperator; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 3d5b9207ad1..ccaabe18620 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -1572,7 +1572,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *op) const ToolSettings *ts = scene->toolsettings; const bool use_face_center = (ts->uv_selectmode == UV_SELECT_FACE); - const bool stickymode = sima ? (sima->sticky != SI_STICKY_DISABLE) : 1; + const bool stickymode = sima ? (ts->uv_sticky != SI_STICKY_DISABLE) : 1; const bool select = RNA_boolean_get(op->ptr, "select"); uint objects_len = 0; diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c index 225b595852f..33621c1f0b6 100644 --- a/source/blender/editors/uvedit/uvedit_path.c +++ b/source/blender/editors/uvedit/uvedit_path.c @@ -138,7 +138,6 @@ struct PathSelectParams { }; struct UserData_UV { - const SpaceImage *sima; Scene *scene; BMEditMesh *em; uint cd_loop_uv_offset; @@ -226,8 +225,7 @@ static void looptag_set_cb(BMLoop *l, bool val, void *user_data_v) } } -static int mouse_mesh_uv_shortest_path_vert(const SpaceImage *sima, - Scene *scene, +static int mouse_mesh_uv_shortest_path_vert(Scene *scene, Object *obedit, const struct PathSelectParams *op_params, BMLoop *l_src, @@ -269,7 +267,6 @@ static int mouse_mesh_uv_shortest_path_vert(const SpaceImage *sima, } struct UserData_UV user_data = { - .sima = sima, .scene = scene, .em = em, .cd_loop_uv_offset = cd_loop_uv_offset, @@ -389,15 +386,13 @@ static bool facetag_test_cb(BMFace *f, void *user_data_v) static void facetag_set_cb(BMFace *f, bool val, void *user_data_v) { struct UserData_UV *user_data = user_data_v; - const SpaceImage *sima = user_data->sima; const Scene *scene = user_data->scene; BMEditMesh *em = user_data->em; const uint cd_loop_uv_offset = user_data->cd_loop_uv_offset; - uvedit_face_select_set_with_sticky(sima, scene, em, f, val, false, cd_loop_uv_offset); + uvedit_face_select_set_with_sticky(scene, em, f, val, false, cd_loop_uv_offset); } -static int mouse_mesh_uv_shortest_path_face(const SpaceImage *sima, - Scene *scene, +static int mouse_mesh_uv_shortest_path_face(Scene *scene, Object *obedit, const struct PathSelectParams *op_params, BMFace *f_src, @@ -410,7 +405,6 @@ static int mouse_mesh_uv_shortest_path_face(const SpaceImage *sima, int flush = 0; struct UserData_UV user_data = { - .sima = sima, .scene = scene, .em = em, .cd_loop_uv_offset = cd_loop_uv_offset, @@ -489,8 +483,7 @@ static int mouse_mesh_uv_shortest_path_face(const SpaceImage *sima, static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op); -static bool uv_shortest_path_pick_ex(const SpaceImage *sima, - Scene *scene, +static bool uv_shortest_path_pick_ex(Scene *scene, Depsgraph *depsgraph, Object *obedit, const struct PathSelectParams *op_params, @@ -508,8 +501,7 @@ static bool uv_shortest_path_pick_ex(const SpaceImage *sima, /* pass */ } else if (ele_src->head.htype == BM_FACE) { - flush = mouse_mesh_uv_shortest_path_face(sima, - scene, + flush = mouse_mesh_uv_shortest_path_face(scene, obedit, op_params, (BMFace *)ele_src, @@ -519,8 +511,7 @@ static bool uv_shortest_path_pick_ex(const SpaceImage *sima, ok = true; } else if (ele_src->head.htype == BM_LOOP) { - flush = mouse_mesh_uv_shortest_path_vert(sima, - scene, + flush = mouse_mesh_uv_shortest_path_vert(scene, obedit, op_params, (BMLoop *)ele_src, @@ -560,7 +551,6 @@ static bool uv_shortest_path_pick_ex(const SpaceImage *sima, static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - SpaceImage *sima = CTX_wm_space_image(C); Scene *scene = CTX_data_scene(C); const ToolSettings *ts = scene->toolsettings; const char uv_selectmode = ED_uvedit_select_mode_get(scene); @@ -667,7 +657,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve } uv_shortest_path_pick_ex( - sima, scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset); + scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset); /* To support redo. */ int index; @@ -691,7 +681,6 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - const SpaceImage *sima = CTX_wm_space_image(C); Scene *scene = CTX_data_scene(C); const char uv_selectmode = ED_uvedit_select_mode_get(scene); Object *obedit = CTX_data_edit_object(C); @@ -742,15 +731,8 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op) path_select_params_from_op(op, &op_params); op_params.track_active = true; - if (!uv_shortest_path_pick_ex(sima, - scene, - depsgraph, - obedit, - &op_params, - ele_src, - ele_dst, - aspect_y, - cd_loop_uv_offset)) { + if (!uv_shortest_path_pick_ex( + scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset)) { return OPERATOR_CANCELLED; } @@ -791,7 +773,6 @@ void UV_OT_shortest_path_pick(wmOperatorType *ot) static int uv_shortest_path_select_exec(bContext *C, wmOperator *op) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - const SpaceImage *sima = CTX_wm_space_image(C); Scene *scene = CTX_data_scene(C); const char uv_selectmode = ED_uvedit_select_mode_get(scene); bool found_valid_elements = false; @@ -840,15 +821,8 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op) struct PathSelectParams op_params; path_select_params_from_op(op, &op_params); - uv_shortest_path_pick_ex(sima, - scene, - depsgraph, - obedit, - &op_params, - ele_src, - ele_dst, - aspect_y, - cd_loop_uv_offset); + uv_shortest_path_pick_ex( + scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset); found_valid_elements = true; } diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index 75bcf7c546e..4454a8414b5 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -63,14 +63,8 @@ static void uv_select_all_perform_multi(Scene *scene, const uint objects_len, int action); -static void uv_select_flush_from_tag_face(SpaceImage *sima, - Scene *scene, - Object *obedit, - const bool select); -static void uv_select_flush_from_tag_loop(SpaceImage *sima, - Scene *scene, - Object *obedit, - const bool select); +static void uv_select_flush_from_tag_face(Scene *scene, Object *obedit, const bool select); +static void uv_select_flush_from_tag_loop(Scene *scene, Object *obedit, const bool select); static void uv_select_tag_update_for_object(Depsgraph *depsgraph, const ToolSettings *ts, Object *obedit); @@ -234,8 +228,7 @@ bool uvedit_face_select_test(const Scene *scene, BMFace *efa, const int cd_loop_ return uvedit_face_select_test_ex(scene->toolsettings, efa, cd_loop_uv_offset); } -void uvedit_face_select_set_with_sticky(const SpaceImage *sima, - const Scene *scene, +void uvedit_face_select_set_with_sticky(const Scene *scene, BMEditMesh *em, BMFace *efa, const bool select, @@ -251,8 +244,7 @@ void uvedit_face_select_set_with_sticky(const SpaceImage *sima, BMLoop *l_iter, *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(efa); do { - uvedit_uv_select_set_with_sticky( - sima, scene, em, l_iter, select, do_history, cd_loop_uv_offset); + uvedit_uv_select_set_with_sticky(scene, em, l_iter, select, do_history, cd_loop_uv_offset); } while ((l_iter = l_iter->next) != l_first); } @@ -344,8 +336,7 @@ bool uvedit_edge_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv return uvedit_edge_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset); } -void uvedit_edge_select_set_with_sticky(const struct SpaceImage *sima, - const Scene *scene, +void uvedit_edge_select_set_with_sticky(const Scene *scene, BMEditMesh *em, BMLoop *l, const bool select, @@ -358,9 +349,8 @@ void uvedit_edge_select_set_with_sticky(const struct SpaceImage *sima, return; } - uvedit_uv_select_set_with_sticky(sima, scene, em, l, select, do_history, cd_loop_uv_offset); - uvedit_uv_select_set_with_sticky( - sima, scene, em, l->next, select, do_history, cd_loop_uv_offset); + uvedit_uv_select_set_with_sticky(scene, em, l, select, do_history, cd_loop_uv_offset); + uvedit_uv_select_set_with_sticky(scene, em, l->next, select, do_history, cd_loop_uv_offset); } void uvedit_edge_select_set(const Scene *scene, @@ -463,8 +453,7 @@ bool uvedit_uv_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv_o return uvedit_uv_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset); } -void uvedit_uv_select_set_with_sticky(const struct SpaceImage *sima, - const Scene *scene, +void uvedit_uv_select_set_with_sticky(const Scene *scene, BMEditMesh *em, BMLoop *l, const bool select, @@ -477,7 +466,7 @@ void uvedit_uv_select_set_with_sticky(const struct SpaceImage *sima, return; } - const int sticky = sima->sticky; + const int sticky = ts->uv_sticky; switch (sticky) { case SI_STICKY_DISABLE: { uvedit_uv_select_set(scene, em, l, select, do_history, cd_loop_uv_offset); @@ -1133,8 +1122,7 @@ static void uv_select_edgeloop_single_side_tag(const Scene *scene, } } -static int uv_select_edgeloop( - SpaceImage *sima, Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend) +static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend) { BMEditMesh *em = BKE_editmesh_from_object(obedit); bool select; @@ -1197,8 +1185,7 @@ static int uv_select_edgeloop( BMLoop *l_iter; BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l_iter, BM_ELEM_TAG)) { - uvedit_edge_select_set_with_sticky( - sima, scene, em, l_iter, select, false, cd_loop_uv_offset); + uvedit_edge_select_set_with_sticky(scene, em, l_iter, select, false, cd_loop_uv_offset); } } } @@ -1213,8 +1200,7 @@ static int uv_select_edgeloop( /** \name Edge Ring Select * \{ */ -static int uv_select_edgering( - const SpaceImage *sima, Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend) +static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend) { const ToolSettings *ts = scene->toolsettings; BMEditMesh *em = BKE_editmesh_from_object(obedit); @@ -1253,12 +1239,10 @@ static int uv_select_edgering( } if (use_face_select) { - uvedit_face_select_set_with_sticky( - sima, scene, em, l_step->f, select, false, cd_loop_uv_offset); + uvedit_face_select_set_with_sticky(scene, em, l_step->f, select, false, cd_loop_uv_offset); } else { - uvedit_edge_select_set_with_sticky( - sima, scene, em, l_step, select, false, cd_loop_uv_offset); + uvedit_edge_select_set_with_sticky(scene, em, l_step, select, false, cd_loop_uv_offset); } BM_elem_flag_enable(l_step->e, BM_ELEM_TAG); @@ -1544,7 +1528,6 @@ static int uv_select_more_less(bContext *C, const bool select) { Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - SpaceImage *sima = CTX_wm_space_image(C); BMFace *efa; BMLoop *l; @@ -1643,11 +1626,11 @@ static int uv_select_more_less(bContext *C, const bool select) if (changed) { if (is_uv_face_selectmode) { /* Select tagged faces. */ - uv_select_flush_from_tag_face(sima, scene, obedit, select); + uv_select_flush_from_tag_face(scene, obedit, select); } else { /* Select tagged loops. */ - uv_select_flush_from_tag_loop(sima, scene, obedit, select); + uv_select_flush_from_tag_loop(scene, obedit, select); } DEG_id_tag_update(obedit->data, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); @@ -1877,7 +1860,6 @@ static int uv_mouse_select_multi(bContext *C, const bool deselect_all) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - SpaceImage *sima = CTX_wm_space_image(C); const ARegion *region = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); const ToolSettings *ts = scene->toolsettings; @@ -1907,7 +1889,7 @@ static int uv_mouse_select_multi(bContext *C, } else { selectmode = ts->uv_selectmode; - sticky = (sima) ? sima->sticky : SI_STICKY_DISABLE; + sticky = ts->uv_sticky; } /* find nearest element */ @@ -1991,20 +1973,19 @@ static int uv_mouse_select_multi(bContext *C, if (selectmode == UV_SELECT_VERTEX) { /* (de)select uv vertex */ select = !uvedit_uv_select_test(scene, hit.l, cd_loop_uv_offset); - uvedit_uv_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset); + uvedit_uv_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset); flush = 1; } else if (selectmode == UV_SELECT_EDGE) { /* (de)select edge */ select = !(uvedit_edge_select_test(scene, hit.l, cd_loop_uv_offset)); - uvedit_edge_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset); + uvedit_edge_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset); flush = 1; } else if (selectmode == UV_SELECT_FACE) { /* (de)select face */ select = !(uvedit_face_select_test(scene, hit.efa, cd_loop_uv_offset)); - uvedit_face_select_set_with_sticky( - sima, scene, em, hit.efa, select, true, cd_loop_uv_offset); + uvedit_face_select_set_with_sticky(scene, em, hit.efa, select, true, cd_loop_uv_offset); flush = -1; } @@ -2027,18 +2008,17 @@ static int uv_mouse_select_multi(bContext *C, if (selectmode == UV_SELECT_VERTEX) { /* select vertex */ - uvedit_uv_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset); + uvedit_uv_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset); flush = 1; } else if (selectmode == UV_SELECT_EDGE) { /* select edge */ - uvedit_edge_select_set_with_sticky(sima, scene, em, hit.l, select, true, cd_loop_uv_offset); + uvedit_edge_select_set_with_sticky(scene, em, hit.l, select, true, cd_loop_uv_offset); flush = 1; } else if (selectmode == UV_SELECT_FACE) { /* select face */ - uvedit_face_select_set_with_sticky( - sima, scene, em, hit.efa, select, true, cd_loop_uv_offset); + uvedit_face_select_set_with_sticky(scene, em, hit.efa, select, true, cd_loop_uv_offset); flush = 1; } } @@ -2154,7 +2134,6 @@ static int uv_mouse_select_loop_generic_multi(bContext *C, const bool extend, enum eUVLoopGenericType loop_type) { - SpaceImage *sima = CTX_wm_space_image(C); const ARegion *region = CTX_wm_region(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = CTX_data_scene(C); @@ -2179,10 +2158,10 @@ static int uv_mouse_select_loop_generic_multi(bContext *C, } if (loop_type == UV_LOOP_SELECT) { - flush = uv_select_edgeloop(sima, scene, obedit, &hit, extend); + flush = uv_select_edgeloop(scene, obedit, &hit, extend); } else if (loop_type == UV_RING_SELECT) { - flush = uv_select_edgering(sima, scene, obedit, &hit, extend); + flush = uv_select_edgering(scene, obedit, &hit, extend); } else { BLI_assert_unreachable(); @@ -2686,10 +2665,7 @@ static void uv_select_flush_from_tag_sticky_loc_internal(Scene *scene, * \note This function is very similar to #uv_select_flush_from_tag_loop, * be sure to update both upon changing. */ -static void uv_select_flush_from_tag_face(SpaceImage *sima, - Scene *scene, - Object *obedit, - const bool select) +static void uv_select_flush_from_tag_face(Scene *scene, Object *obedit, const bool select) { /* Selecting UV Faces with some modes requires us to change * the selection in other faces (depending on the sticky mode). @@ -2704,7 +2680,7 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima, BMIter iter, liter; const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_VERTEX) { + if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_VERTEX) { /* Tag all verts as untouched, then touch the ones that have a face center * in the loop and select all MLoopUV's that use a touched vert. */ BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false); @@ -2728,7 +2704,7 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima, } } } - else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_LOC) { + else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_LOC) { struct UvVertMap *vmap; uint efa_index; @@ -2769,10 +2745,7 @@ static void uv_select_flush_from_tag_face(SpaceImage *sima, * \note This function is very similar to #uv_select_flush_from_tag_loop, * be sure to update both upon changing. */ -static void uv_select_flush_from_tag_loop(SpaceImage *sima, - Scene *scene, - Object *obedit, - const bool select) +static void uv_select_flush_from_tag_loop(Scene *scene, Object *obedit, const bool select) { /* Selecting UV Loops with some modes requires us to change * the selection in other faces (depending on the sticky mode). @@ -2788,7 +2761,7 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima, const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_VERTEX) { + if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_VERTEX) { /* Tag all verts as untouched, then touch the ones that have a face center * in the loop and select all MLoopUV's that use a touched vert. */ BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false); @@ -2812,7 +2785,7 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima, } } } - else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && sima->sticky == SI_STICKY_LOC) { + else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_LOC) { struct UvVertMap *vmap; uint efa_index; @@ -2854,7 +2827,6 @@ static void uv_select_flush_from_tag_loop(SpaceImage *sima, static int uv_box_select_exec(bContext *C, wmOperator *op) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - SpaceImage *sima = CTX_wm_space_image(C); Scene *scene = CTX_data_scene(C); const ToolSettings *ts = scene->toolsettings; ViewLayer *view_layer = CTX_data_view_layer(C); @@ -2923,7 +2895,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) /* (de)selects all tagged faces and deals with sticky modes */ if (changed) { - uv_select_flush_from_tag_face(sima, scene, obedit, select); + uv_select_flush_from_tag_face(scene, obedit, select); } } else if (use_edge && !pinned) { @@ -2939,7 +2911,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); if (BLI_rctf_isect_pt_v(&rectf, luv->uv) && BLI_rctf_isect_pt_v(&rectf, luv_prev->uv)) { uvedit_edge_select_set_with_sticky( - sima, scene, em, l_prev, select, false, cd_loop_uv_offset); + scene, em, l_prev, select, false, cd_loop_uv_offset); changed = true; } l_prev = l; @@ -2985,7 +2957,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) } } - if (sima->sticky == SI_STICKY_VERTEX) { + if (ts->uv_sticky == SI_STICKY_VERTEX) { uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset); } } @@ -3142,7 +3114,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) /* (de)selects all tagged faces and deals with sticky modes */ if (changed) { - uv_select_flush_from_tag_face(sima, scene, obedit, select); + uv_select_flush_from_tag_face(scene, obedit, select); } } else if (use_edge) { @@ -3158,7 +3130,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); if (uv_circle_select_is_edge_inside(luv->uv, luv_prev->uv, offset, ellipse)) { uvedit_edge_select_set_with_sticky( - sima, scene, em, l_prev, select, false, cd_loop_uv_offset); + scene, em, l_prev, select, false, cd_loop_uv_offset); changed = true; } l_prev = l; @@ -3194,7 +3166,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) } } - if (sima->sticky == SI_STICKY_VERTEX) { + if (ts->uv_sticky == SI_STICKY_VERTEX) { uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset); } } @@ -3262,7 +3234,6 @@ static bool do_lasso_select_mesh_uv(bContext *C, const eSelectOp sel_op) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - SpaceImage *sima = CTX_wm_space_image(C); const ARegion *region = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); const ToolSettings *ts = scene->toolsettings; @@ -3321,7 +3292,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, /* (de)selects all tagged faces and deals with sticky modes */ if (changed) { - uv_select_flush_from_tag_face(sima, scene, obedit, select); + uv_select_flush_from_tag_face(scene, obedit, select); } } else if (use_edge) { @@ -3340,7 +3311,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, do_lasso_select_mesh_uv_is_point_inside( region, &rect, mcoords, mcoords_len, luv_prev->uv)) { uvedit_edge_select_set_with_sticky( - sima, scene, em, l_prev, select, false, cd_loop_uv_offset); + scene, em, l_prev, select, false, cd_loop_uv_offset); changed = true; } l_prev = l; @@ -3377,7 +3348,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, } } - if (sima->sticky == SI_STICKY_VERTEX) { + if (ts->uv_sticky == SI_STICKY_VERTEX) { uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset); } } diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 9472aed79a5..d689fbe14b5 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -287,6 +287,12 @@ void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter); void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat, bool use_clamp); void GPU_texture_swizzle_set(GPUTexture *tex, const char swizzle[4]); +/** + * Return the number of dimensions of the texture ignoring dimension of layers (1, 2 or 3). + * Cube textures are considered 2D. + */ +int GPU_texture_dimensions(const GPUTexture *tex); + int GPU_texture_width(const GPUTexture *tex); int GPU_texture_height(const GPUTexture *tex); int GPU_texture_orig_width(const GPUTexture *tex); diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc index 19c7c5d78ff..da5f08f003e 100644 --- a/source/blender/gpu/intern/gpu_texture.cc +++ b/source/blender/gpu/intern/gpu_texture.cc @@ -507,6 +507,25 @@ void GPU_texture_ref(GPUTexture *tex) reinterpret_cast<Texture *>(tex)->refcount++; } +int GPU_texture_dimensions(const GPUTexture *tex_) +{ + eGPUTextureType type = reinterpret_cast<const Texture *>(tex_)->type_get(); + if (type & GPU_TEXTURE_1D) { + return 1; + } + else if (type & GPU_TEXTURE_2D) { + return 2; + } + else if (type & GPU_TEXTURE_3D) { + return 3; + } + else if (type & GPU_TEXTURE_CUBE) { + return 2; + } + /* GPU_TEXTURE_BUFFER */ + return 1; +} + int GPU_texture_width(const GPUTexture *tex) { return reinterpret_cast<const Texture *>(tex)->width_get(); diff --git a/source/blender/io/usd/intern/usd_writer_material.h b/source/blender/io/usd/intern/usd_writer_material.h index 80b5626e3bd..3e9b84477d5 100644 --- a/source/blender/io/usd/intern/usd_writer_material.h +++ b/source/blender/io/usd/intern/usd_writer_material.h @@ -8,10 +8,10 @@ #include <string> -struct bNode; -struct bNodeTree; struct Material; struct USDExportParams; +struct bNode; +struct bNodeTree; namespace blender::io::usd { diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index c0a9cc1ec41..fe3613548a6 100644 --- a/source/blender/makesdna/DNA_gpencil_types.h +++ b/source/blender/makesdna/DNA_gpencil_types.h @@ -18,8 +18,8 @@ extern "C" { struct AnimData; struct Curve; struct Curve; -struct MDeformVert; struct GPencilUpdateCache; +struct MDeformVert; #define GP_DEFAULT_PIX_FACTOR 1.0f #define GP_DEFAULT_GRID_LINES 4 diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index a3e4551a865..0d42abdb363 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1391,13 +1391,14 @@ typedef struct ToolSettings { char object_flag; /* Selection Mode for Mesh */ - short selectmode; + char selectmode; /* UV Calculation */ char unwrapper; char uvcalc_flag; char uv_flag; char uv_selectmode; + char uv_sticky; float uvcalc_margin; @@ -2300,6 +2301,13 @@ enum { #define UV_SELECT_FACE 4 #define UV_SELECT_ISLAND 8 +/** #ToolSettings.uv_sticky */ +enum { + SI_STICKY_LOC = 0, + SI_STICKY_DISABLE = 1, + SI_STICKY_VERTEX = 2, +}; + /** #ToolSettings.gpencil_flags */ typedef enum eGPencil_Flags { /* When creating new frames, the last frame gets used as the basis for the new one */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index ad7f8cc1e40..b1212965992 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1214,11 +1214,10 @@ typedef struct SpaceImage { /** UV draw type. */ char dt_uv; /** Sticky selection type. */ - char sticky; char dt_uvstretch; char around; - char _pad1[3]; + char _pad1[4]; int flag; @@ -1265,15 +1264,6 @@ typedef enum eSpaceImage_Mode { SI_MODE_UV = 3, } eSpaceImage_Mode; -/* SpaceImage.sticky - * Note DISABLE should be 0, however would also need to re-arrange icon order, - * also, sticky loc is the default mode so this means we don't need to 'do_versions' */ -typedef enum eSpaceImage_Sticky { - SI_STICKY_LOC = 0, - SI_STICKY_DISABLE = 1, - SI_STICKY_VERTEX = 2, -} eSpaceImage_Sticky; - /** #SpaceImage.flag */ typedef enum eSpaceImage_Flag { SI_FLAG_UNUSED_0 = (1 << 0), /* cleared */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index c8f65e5e153..178029ef340 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2883,6 +2883,25 @@ static void rna_def_tool_settings(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem uv_sticky_mode_items[] = { + {SI_STICKY_DISABLE, + "DISABLED", + ICON_STICKY_UVS_DISABLE, + "Disabled", + "Sticky vertex selection disabled"}, + {SI_STICKY_LOC, + "SHARED_LOCATION", + ICON_STICKY_UVS_LOC, + "Shared Location", + "Select UVs that are at the same location and share a mesh vertex"}, + {SI_STICKY_VERTEX, + "SHARED_VERTEX", + ICON_STICKY_UVS_VERT, + "Shared Vertex", + "Select UVs that share a mesh vertex, whether or not they are at the same location"}, + {0, NULL, 0, NULL, NULL}, + }; + srna = RNA_def_struct(brna, "ToolSettings", NULL); RNA_def_struct_path_func(srna, "rna_ToolSettings_path"); RNA_def_struct_ui_text(srna, "Tool Settings", ""); @@ -3454,6 +3473,13 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "UV Selection Mode", "UV selection and display mode"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); + prop = RNA_def_property(srna, "uv_sticky_select_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "uv_sticky"); + RNA_def_property_enum_items(prop, uv_sticky_mode_items); + RNA_def_property_ui_text( + prop, "Sticky Selection Mode", "Method for extending UV vertex selection"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); + prop = RNA_def_property(srna, "use_uv_select_sync", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uv_flag", UV_SYNC_SELECTION); RNA_def_property_ui_text( diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 20fa8b87cd2..c51f0c00498 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -3428,25 +3428,6 @@ static void rna_def_space_image_uv(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static const EnumPropertyItem sticky_mode_items[] = { - {SI_STICKY_DISABLE, - "DISABLED", - ICON_STICKY_UVS_DISABLE, - "Disabled", - "Sticky vertex selection disabled"}, - {SI_STICKY_LOC, - "SHARED_LOCATION", - ICON_STICKY_UVS_LOC, - "Shared Location", - "Select UVs that are at the same location and share a mesh vertex"}, - {SI_STICKY_VERTEX, - "SHARED_VERTEX", - ICON_STICKY_UVS_VERT, - "Shared Vertex", - "Select UVs that share a mesh vertex, whether or not they are at the same location"}, - {0, NULL, 0, NULL, NULL}, - }; - static const EnumPropertyItem dt_uvstretch_items[] = { {SI_UVDT_STRETCH_ANGLE, "ANGLE", 0, "Angle", "Angular distortion between UV and 3D angles"}, {SI_UVDT_STRETCH_AREA, "AREA", 0, "Area", "Area distortion between UV and 3D faces"}, @@ -3466,14 +3447,6 @@ static void rna_def_space_image_uv(BlenderRNA *brna) RNA_def_struct_path_func(srna, "rna_SpaceUVEditor_path"); RNA_def_struct_ui_text(srna, "Space UV Editor", "UV editor data for the image editor space"); - /* selection */ - prop = RNA_def_property(srna, "sticky_select_mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "sticky"); - RNA_def_property_enum_items(prop, sticky_mode_items); - RNA_def_property_ui_text( - prop, "Sticky Selection Mode", "Method for extending UV vertex selection"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); - /* drawing */ prop = RNA_def_property(srna, "edge_display_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "dt_uv"); diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c index 1c0b5fc782c..0853c5dd3ea 100644 --- a/source/blender/python/mathutils/mathutils_noise.c +++ b/source/blender/python/mathutils/mathutils_noise.c @@ -27,48 +27,20 @@ /*-----------------------------------------*/ /* 'mersenne twister' random number generator */ -/* - * A C-program for MT19937, with initialization improved 2002/2/10. +/* A C-program for MT19937, with initialization improved 2002/2/10. * Coded by Takuji Nishimura and Makoto Matsumoto. * This is a faster version by taking Shawn Cokus's optimization, * Matthe Bellew's simplification, Isaku Wada's real version. * - * Before using, initialize the state by using init_genrand(seed) - * or init_by_array(init_key, key_length). + * Before using, initialize the state by using + * `init_genrand(seed)` or `init_by_array(init_key, key_length)`. * - * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, - * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * Copyright 1997-2002 Makoto Matsumoto and Takuji Nishimura, All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. The names of its contributors may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * Any feedback is very welcome. * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) - */ + * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space). */ /* Period parameters */ #define N 624 diff --git a/source/blender/render/RE_pipeline.h b/source/blender/render/RE_pipeline.h index 6250f61b11c..2d43aa7b27f 100644 --- a/source/blender/render/RE_pipeline.h +++ b/source/blender/render/RE_pipeline.h @@ -11,11 +11,11 @@ #include "DNA_listBase.h" #include "DNA_vec_types.h" +struct ImBuf; struct Image; struct ImageFormatData; struct Main; struct Object; -struct ImBuf; struct RenderData; struct RenderResult; struct ReportList; |