Compare commits
5 Commits
refactor-m
...
tiles-sche
Author | SHA1 | Date | |
---|---|---|---|
5fcc889baa | |||
3b691b54b1 | |||
948703b36d | |||
815c999382 | |||
0563280bff |
@@ -74,6 +74,12 @@ set(SRC
|
||||
intern/COM_MemoryProxy.h
|
||||
intern/COM_MemoryBuffer.cpp
|
||||
intern/COM_MemoryBuffer.h
|
||||
intern/COM_MemoryBufferColor.cpp
|
||||
intern/COM_MemoryBufferColor.h
|
||||
intern/COM_MemoryBufferVector.cpp
|
||||
intern/COM_MemoryBufferVector.h
|
||||
intern/COM_MemoryBufferValue.cpp
|
||||
intern/COM_MemoryBufferValue.h
|
||||
intern/COM_WorkScheduler.cpp
|
||||
intern/COM_WorkScheduler.h
|
||||
intern/COM_WorkPackage.cpp
|
||||
@@ -90,8 +96,6 @@ set(SRC
|
||||
intern/COM_OpenCLDevice.h
|
||||
intern/COM_CompositorContext.cpp
|
||||
intern/COM_CompositorContext.h
|
||||
intern/COM_ChannelInfo.cpp
|
||||
intern/COM_ChannelInfo.h
|
||||
intern/COM_SingleThreadedOperation.cpp
|
||||
intern/COM_SingleThreadedOperation.h
|
||||
intern/COM_Debug.cpp
|
||||
|
@@ -105,7 +105,9 @@ typedef enum OrderOfChunks {
|
||||
|
||||
#define COM_RULE_OF_THIRDS_DIVIDER 100.0f
|
||||
|
||||
#define COM_NUMBER_OF_CHANNELS 4
|
||||
#define COM_NO_CHANNELS_VALUE 1
|
||||
#define COM_NO_CHANNELS_VECTOR 3
|
||||
#define COM_NO_CHANNELS_COLOR 4
|
||||
|
||||
#define COM_BLUR_BOKEH_PIXELS 512
|
||||
|
||||
|
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011, Blender Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor:
|
||||
* Jeroen Bakker
|
||||
* Monique Dewanchand
|
||||
*/
|
||||
|
||||
#include "COM_ChannelInfo.h"
|
||||
#include "COM_defines.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* @brief create new ChannelInfo instance and sets the defaults.
|
||||
*/
|
||||
ChannelInfo::ChannelInfo()
|
||||
{
|
||||
this->m_number = 0;
|
||||
this->m_premultiplied = true;
|
||||
this->m_type = COM_CT_UNUSED;
|
||||
}
|
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011, Blender Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor:
|
||||
* Jeroen Bakker
|
||||
* Monique Dewanchand
|
||||
*/
|
||||
|
||||
#ifndef _COM_ChannelInfo_h
|
||||
#define _COM_ChannelInfo_h
|
||||
|
||||
#include <vector>
|
||||
#include "BKE_text.h"
|
||||
#include <string>
|
||||
#include "DNA_node_types.h"
|
||||
#include "BLI_rect.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* @brief List of possible channel types
|
||||
* @ingroup Model
|
||||
*/
|
||||
typedef enum ChannelType {
|
||||
COM_CT_ColorComponent /** @brief this channel is contains color information. Specific used is determined by channelnumber, and in the future color space */,
|
||||
COM_CT_Alpha /** @brief this channel is contains transparency value */,
|
||||
COM_CT_Value /** @brief this channel is contains a value */,
|
||||
COM_CT_X /** @brief this channel is contains a X value */,
|
||||
COM_CT_Y /** @brief this channel is contains a Y value */,
|
||||
COM_CT_Z /** @brief this channel is contains a Z value */,
|
||||
COM_CT_W /** @brief this channel is contains a W value */,
|
||||
COM_CT_UNUSED /** @brief this channel is unused */
|
||||
} ChannelType;
|
||||
|
||||
/**
|
||||
* @brief ChannelInfo holds information about a channel.
|
||||
*
|
||||
* Channels are transported from node to node via a NodeLink.
|
||||
* ChannelInfo holds specific setting of these channels in order that the to-node of the link
|
||||
* Can handle specific logic per channel setting.
|
||||
*
|
||||
* @note currently this is not used, but a future place to implement color spacing and other things.
|
||||
* @ingroup Model
|
||||
*/
|
||||
class ChannelInfo {
|
||||
private:
|
||||
/**
|
||||
* @brief the channel number, in the link. [0-3]
|
||||
*/
|
||||
int m_number;
|
||||
|
||||
/**
|
||||
* @brief type of channel
|
||||
*/
|
||||
ChannelType m_type;
|
||||
|
||||
/**
|
||||
* @brieg Is this value in this channel premultiplied with its alpha
|
||||
* @note only valid if type = ColorComponent;
|
||||
*/
|
||||
bool m_premultiplied;
|
||||
|
||||
// /**
|
||||
// * Color space of this value.
|
||||
// * only valid when type = ColorComponent;
|
||||
// */
|
||||
// string colorspacename;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief creates a new ChannelInfo and set default values
|
||||
*/
|
||||
ChannelInfo();
|
||||
|
||||
/**
|
||||
* @brief set the index of this channel in the NodeLink
|
||||
*/
|
||||
void setNumber(const int number) { this->m_number = number; }
|
||||
|
||||
/**
|
||||
* @brief get the index of this channel in the NodeLink
|
||||
*/
|
||||
const int getNumber() const { return this->m_number; }
|
||||
|
||||
/**
|
||||
* @brief set the type of channel
|
||||
*/
|
||||
void setType(const ChannelType type) { this->m_type = type; }
|
||||
|
||||
/**
|
||||
* @brief get the type of channel
|
||||
*/
|
||||
const ChannelType getType() const { return this->m_type; }
|
||||
|
||||
/**
|
||||
* @brief set the premultiplicatioin of this channel
|
||||
*/
|
||||
void setPremultiplied(const bool premultiplied) { this->m_premultiplied = premultiplied; }
|
||||
|
||||
/**
|
||||
* @brief is this channel premultiplied
|
||||
*/
|
||||
const bool isPremultiplied() const { return this->m_premultiplied; }
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@@ -372,7 +372,7 @@ MemoryBuffer **ExecutionGroup::getInputBuffersOpenCL(int chunkNumber)
|
||||
MemoryBuffer *ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *rect)
|
||||
{
|
||||
MemoryBuffer *imageBuffer = memoryProxy->getBuffer();
|
||||
MemoryBuffer *result = new MemoryBuffer(memoryProxy, rect);
|
||||
MemoryBuffer *result = MemoryBuffer::create(memoryProxy, rect);
|
||||
result->copyContentFrom(imageBuffer);
|
||||
return result;
|
||||
}
|
||||
@@ -465,7 +465,7 @@ MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int chunkNumber, rcti *rect)
|
||||
NodeOperation *operation = this->getOutputOperation();
|
||||
if (operation->isWriteBufferOperation()) {
|
||||
WriteBufferOperation *writeOperation = (WriteBufferOperation *)operation;
|
||||
MemoryBuffer *buffer = new MemoryBuffer(writeOperation->getMemoryProxy(), rect);
|
||||
MemoryBuffer *buffer = MemoryBuffer::create(writeOperation->getMemoryProxy(), rect);
|
||||
return buffer;
|
||||
}
|
||||
return NULL;
|
||||
|
@@ -98,7 +98,7 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editin
|
||||
}
|
||||
}
|
||||
|
||||
// DebugInfo::graphviz(this);
|
||||
DebugInfo::graphviz(this);
|
||||
}
|
||||
|
||||
ExecutionSystem::~ExecutionSystem()
|
||||
|
@@ -27,7 +27,11 @@
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
||||
unsigned int MemoryBuffer::determineBufferSize()
|
||||
#include "COM_MemoryBufferColor.h"
|
||||
#include "COM_MemoryBufferVector.h"
|
||||
#include "COM_MemoryBufferValue.h"
|
||||
|
||||
unsigned int MemoryBuffer::determineBufferSize() const
|
||||
{
|
||||
return getWidth() * getHeight();
|
||||
}
|
||||
@@ -41,38 +45,109 @@ int MemoryBuffer::getHeight() const
|
||||
return this->m_rect.ymax - this->m_rect.ymin;
|
||||
}
|
||||
|
||||
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect)
|
||||
MemoryBuffer* MemoryBuffer::create(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect) {
|
||||
DataType type;
|
||||
type = memoryProxy->getDataType();
|
||||
|
||||
if (type == COM_DT_VALUE) {
|
||||
return new MemoryBufferValue(memoryProxy, chunkNumber, rect);
|
||||
}
|
||||
else if (type == COM_DT_VECTOR) {
|
||||
return new MemoryBufferVector(memoryProxy, chunkNumber, rect);
|
||||
}
|
||||
else {
|
||||
return new MemoryBufferColor(memoryProxy, chunkNumber, rect);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryBuffer* MemoryBuffer::create(MemoryProxy *memoryProxy, rcti *rect) {
|
||||
DataType type;
|
||||
type = memoryProxy->getDataType();
|
||||
|
||||
if (type==COM_DT_VALUE){
|
||||
return new MemoryBufferValue(memoryProxy, rect);
|
||||
}
|
||||
else if (type == COM_DT_VECTOR) {
|
||||
return new MemoryBufferVector(memoryProxy, rect);
|
||||
}
|
||||
else {
|
||||
return new MemoryBufferColor(memoryProxy, rect);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryBuffer* MemoryBuffer::create(DataType datatype, rcti *rect) {
|
||||
if (datatype==COM_DT_VALUE){
|
||||
return new MemoryBufferValue(datatype, rect);
|
||||
}
|
||||
else if (datatype == COM_DT_VECTOR) {
|
||||
return new MemoryBufferVector(datatype, rect);
|
||||
}
|
||||
else {
|
||||
return new MemoryBufferColor(datatype, rect);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect, unsigned int no_channels)
|
||||
{
|
||||
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
|
||||
this->m_memoryProxy = memoryProxy;
|
||||
this->m_chunkNumber = chunkNumber;
|
||||
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, "COM_MemoryBuffer");
|
||||
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * no_channels, "COM_MemoryBuffer");
|
||||
this->m_state = COM_MB_ALLOCATED;
|
||||
this->m_datatype = COM_DT_COLOR;
|
||||
this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
|
||||
this->m_no_channels = no_channels;
|
||||
}
|
||||
|
||||
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect)
|
||||
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect, unsigned int no_channels)
|
||||
{
|
||||
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
|
||||
this->m_memoryProxy = memoryProxy;
|
||||
this->m_chunkNumber = -1;
|
||||
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, "COM_MemoryBuffer");
|
||||
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * no_channels, "COM_MemoryBuffer");
|
||||
this->m_state = COM_MB_TEMPORARILY;
|
||||
this->m_datatype = COM_DT_COLOR;
|
||||
this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
|
||||
}
|
||||
MemoryBuffer *MemoryBuffer::duplicate()
|
||||
{
|
||||
MemoryBuffer *result = new MemoryBuffer(this->m_memoryProxy, &this->m_rect);
|
||||
memcpy(result->m_buffer, this->m_buffer, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float));
|
||||
return result;
|
||||
}
|
||||
void MemoryBuffer::clear()
|
||||
{
|
||||
memset(this->m_buffer, 0, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float));
|
||||
this->m_no_channels = no_channels;
|
||||
}
|
||||
|
||||
MemoryBuffer::MemoryBuffer(DataType datatype, rcti *rect, unsigned int no_channels) {
|
||||
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
|
||||
this->m_memoryProxy = NULL;
|
||||
this->m_chunkNumber = -1;
|
||||
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * no_channels, "COM_MemoryBuffer");
|
||||
this->m_state = COM_MB_TEMPORARILY;
|
||||
this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
|
||||
this->m_no_channels = no_channels;
|
||||
}
|
||||
|
||||
void MemoryBuffer::clear()
|
||||
{
|
||||
memset(this->m_buffer, 0, this->determineBufferSize() * this->m_no_channels * sizeof(float));
|
||||
}
|
||||
|
||||
void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer)
|
||||
{
|
||||
if (!otherBuffer) {
|
||||
BLI_assert(0);
|
||||
return;
|
||||
}
|
||||
unsigned int otherY;
|
||||
unsigned int minX = max(this->m_rect.xmin, otherBuffer->m_rect.xmin);
|
||||
unsigned int maxX = min(this->m_rect.xmax, otherBuffer->m_rect.xmax);
|
||||
unsigned int minY = max(this->m_rect.ymin, otherBuffer->m_rect.ymin);
|
||||
unsigned int maxY = min(this->m_rect.ymax, otherBuffer->m_rect.ymax);
|
||||
int offset;
|
||||
int otherOffset;
|
||||
|
||||
|
||||
for (otherY = minY; otherY < maxY; otherY++) {
|
||||
otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_chunkWidth + minX - otherBuffer->m_rect.xmin) * this->m_no_channels;
|
||||
offset = ((otherY - this->m_rect.ymin) * this->m_chunkWidth + minX - this->m_rect.xmin) * this->m_no_channels;
|
||||
memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * this->m_no_channels * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: this method needs to be checked! At Mind 2014
|
||||
float *MemoryBuffer::convertToValueBuffer()
|
||||
{
|
||||
const unsigned int size = this->determineBufferSize();
|
||||
@@ -83,29 +158,16 @@ float *MemoryBuffer::convertToValueBuffer()
|
||||
const float *fp_src = this->m_buffer;
|
||||
float *fp_dst = result;
|
||||
|
||||
for (i = 0; i < size; i++, fp_dst++, fp_src += COM_NUMBER_OF_CHANNELS) {
|
||||
for (i = 0; i < size; i++, fp_dst++, fp_src += COM_NO_CHANNELS_COLOR) {
|
||||
*fp_dst = *fp_src;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float MemoryBuffer::getMaximumValue()
|
||||
float MemoryBuffer::getMaximumValue() const
|
||||
{
|
||||
float result = this->m_buffer[0];
|
||||
const unsigned int size = this->determineBufferSize();
|
||||
unsigned int i;
|
||||
|
||||
const float *fp_src = this->m_buffer;
|
||||
|
||||
for (i = 0; i < size; i++, fp_src += COM_NUMBER_OF_CHANNELS) {
|
||||
float value = *fp_src;
|
||||
if (value > result) {
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float MemoryBuffer::getMaximumValue(rcti *rect)
|
||||
@@ -116,7 +178,7 @@ float MemoryBuffer::getMaximumValue(rcti *rect)
|
||||
BLI_rcti_isect(rect, &this->m_rect, &rect_clamp);
|
||||
|
||||
if (!BLI_rcti_is_empty(&rect_clamp)) {
|
||||
MemoryBuffer *temp = new MemoryBuffer(NULL, &rect_clamp);
|
||||
MemoryBuffer *temp = MemoryBuffer::create(COM_DT_VALUE, &rect_clamp);
|
||||
temp->copyContentFrom(this);
|
||||
float result = temp->getMaximumValue();
|
||||
delete temp;
|
||||
@@ -136,204 +198,6 @@ MemoryBuffer::~MemoryBuffer()
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer)
|
||||
{
|
||||
if (!otherBuffer) {
|
||||
BLI_assert(0);
|
||||
return;
|
||||
}
|
||||
unsigned int otherY;
|
||||
unsigned int minX = max(this->m_rect.xmin, otherBuffer->m_rect.xmin);
|
||||
unsigned int maxX = min(this->m_rect.xmax, otherBuffer->m_rect.xmax);
|
||||
unsigned int minY = max(this->m_rect.ymin, otherBuffer->m_rect.ymin);
|
||||
unsigned int maxY = min(this->m_rect.ymax, otherBuffer->m_rect.ymax);
|
||||
int offset;
|
||||
int otherOffset;
|
||||
|
||||
|
||||
for (otherY = minY; otherY < maxY; otherY++) {
|
||||
otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_chunkWidth + minX - otherBuffer->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
|
||||
offset = ((otherY - this->m_rect.ymin) * this->m_chunkWidth + minX - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
|
||||
memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * COM_NUMBER_OF_CHANNELS * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBuffer::writePixel(int x, int y, const float color[4])
|
||||
{
|
||||
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
|
||||
y >= this->m_rect.ymin && y < this->m_rect.ymax)
|
||||
{
|
||||
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
|
||||
copy_v4_v4(&this->m_buffer[offset], color);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBuffer::addPixel(int x, int y, const float color[4])
|
||||
{
|
||||
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
|
||||
y >= this->m_rect.ymin && y < this->m_rect.ymax)
|
||||
{
|
||||
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
|
||||
add_v4_v4(&this->m_buffer[offset], color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2
|
||||
// used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible
|
||||
#define EWA_MAXIDX 255
|
||||
static const float EWA_WTS[EWA_MAXIDX + 1] = {
|
||||
1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
|
||||
0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
|
||||
0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
|
||||
0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f,
|
||||
0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f,
|
||||
0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f,
|
||||
0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f,
|
||||
0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f,
|
||||
0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f,
|
||||
0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f,
|
||||
0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f,
|
||||
0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f,
|
||||
0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f,
|
||||
0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f,
|
||||
0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f,
|
||||
0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f,
|
||||
0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f,
|
||||
0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f,
|
||||
0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f,
|
||||
0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f,
|
||||
0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f,
|
||||
0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f,
|
||||
0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f,
|
||||
0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f,
|
||||
0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f,
|
||||
0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f,
|
||||
0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f,
|
||||
0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f,
|
||||
0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f,
|
||||
0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f,
|
||||
0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f,
|
||||
0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f
|
||||
};
|
||||
|
||||
static void ellipse_bounds(float A, float B, float C, float F, float &xmax, float &ymax)
|
||||
{
|
||||
float denom = 4.0f * A * C - B * B;
|
||||
if (denom > 0.0f && A != 0.0f && C != 0.0f) {
|
||||
xmax = sqrtf(F) / (2.0f * A) * (sqrtf(F * (4.0f * A - B * B / C)) + B * B * sqrtf(F / (C * denom)));
|
||||
ymax = sqrtf(F) / (2.0f * C) * (sqrtf(F * (4.0f * C - B * B / A)) + B * B * sqrtf(F / (A * denom)));
|
||||
}
|
||||
else {
|
||||
xmax = 0.0f;
|
||||
ymax = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void ellipse_params(float Ux, float Uy, float Vx, float Vy,
|
||||
float &A, float &B, float &C, float &F, float &umax, float &vmax)
|
||||
{
|
||||
A = Vx * Vx + Vy * Vy;
|
||||
B = -2.0f * (Ux * Vx + Uy * Vy);
|
||||
C = Ux * Ux + Uy * Uy;
|
||||
F = A * C - B * B * 0.25f;
|
||||
|
||||
float factor = (F != 0.0f ? (float)(EWA_MAXIDX + 1) / F : 0.0f);
|
||||
A *= factor;
|
||||
B *= factor;
|
||||
C *= factor;
|
||||
F = (float)(EWA_MAXIDX + 1);
|
||||
|
||||
ellipse_bounds(A, B, C, sqrtf(F), umax, vmax);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filtering method based on
|
||||
* "Creating raster omnimax images from multiple perspective views using the elliptical weighted average filter"
|
||||
* by Ned Greene and Paul S. Heckbert (1986)
|
||||
*/
|
||||
void MemoryBuffer::readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler)
|
||||
{
|
||||
zero_v4(result);
|
||||
int width = this->getWidth(), height = this->getHeight();
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
float u = uv[0], v = uv[1];
|
||||
float Ux = derivatives[0][0], Vx = derivatives[1][0], Uy = derivatives[0][1], Vy = derivatives[1][1];
|
||||
float A, B, C, F, ue, ve;
|
||||
ellipse_params(Ux, Uy, Vx, Vy, A, B, C, F, ue, ve);
|
||||
|
||||
/* Note: highly eccentric ellipses can lead to large texture space areas to filter!
|
||||
* This is limited somewhat by the EWA_WTS size in the loop, but a nicer approach
|
||||
* could be the one found in
|
||||
* "High Quality Elliptical Texture Filtering on GPU"
|
||||
* by Pavlos Mavridis and Georgios Papaioannou
|
||||
* in which the eccentricity of the ellipse is clamped.
|
||||
*/
|
||||
|
||||
int U0 = (int)u;
|
||||
int V0 = (int)v;
|
||||
/* pixel offset for interpolation */
|
||||
float ufac = u - floorf(u), vfac = v - floorf(v);
|
||||
/* filter size */
|
||||
int u1 = (int)(u - ue);
|
||||
int u2 = (int)(u + ue);
|
||||
int v1 = (int)(v - ve);
|
||||
int v2 = (int)(v + ve);
|
||||
|
||||
/* sane clamping to avoid unnecessarily huge loops */
|
||||
/* note: if eccentricity gets clamped (see above),
|
||||
* the ue/ve limits can also be lowered accordingly
|
||||
*/
|
||||
if (U0 - u1 > EWA_MAXIDX) u1 = U0 - EWA_MAXIDX;
|
||||
if (u2 - U0 > EWA_MAXIDX) u2 = U0 + EWA_MAXIDX;
|
||||
if (V0 - v1 > EWA_MAXIDX) v1 = V0 - EWA_MAXIDX;
|
||||
if (v2 - V0 > EWA_MAXIDX) v2 = V0 + EWA_MAXIDX;
|
||||
|
||||
/* Early output check for cases the whole region is outside of the buffer. */
|
||||
if ((u2 < m_rect.xmin || u1 >= m_rect.xmax) ||
|
||||
(v2 < m_rect.ymin || v1 >= m_rect.ymax))
|
||||
{
|
||||
zero_v4(result);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clamp sampling rectagle to the buffer dimensions. */
|
||||
u1 = max_ii(u1, m_rect.xmin);
|
||||
u2 = min_ii(u2, m_rect.xmax);
|
||||
v1 = max_ii(v1, m_rect.ymin);
|
||||
v2 = min_ii(v2, m_rect.ymax);
|
||||
|
||||
float DDQ = 2.0f * A;
|
||||
float U = u1 - U0;
|
||||
float ac1 = A * (2.0f * U + 1.0f);
|
||||
float ac2 = A * U * U;
|
||||
float BU = B * U;
|
||||
|
||||
float sum = 0.0f;
|
||||
for (int v = v1; v <= v2; ++v) {
|
||||
float V = v - V0;
|
||||
|
||||
float DQ = ac1 + B * V;
|
||||
float Q = (C * V + BU) * V + ac2;
|
||||
for (int u = u1; u <= u2; ++u) {
|
||||
if (Q < F) {
|
||||
float tc[4];
|
||||
const float wt = EWA_WTS[CLAMPIS((int)Q, 0, EWA_MAXIDX)];
|
||||
switch (sampler) {
|
||||
case COM_PS_NEAREST: read(tc, u, v); break;
|
||||
case COM_PS_BILINEAR: readBilinear(tc, (float)u + ufac, (float)v + vfac); break;
|
||||
case COM_PS_BICUBIC: readBilinear(tc, (float)u + ufac, (float)v + vfac); break; /* XXX no readBicubic method yet */
|
||||
default: zero_v4(tc); break;
|
||||
}
|
||||
madd_v4_v4fl(result, tc, wt);
|
||||
sum += wt;
|
||||
}
|
||||
Q += DQ;
|
||||
DQ += DDQ;
|
||||
}
|
||||
}
|
||||
|
||||
mul_v4_fl(result, (sum != 0.0f ? 1.0f / sum : 0.0f));
|
||||
const int MemoryBuffer::get_no_channels() const {
|
||||
return this->m_no_channels;
|
||||
}
|
||||
|
@@ -61,57 +61,84 @@ class MemoryProxy;
|
||||
class MemoryBuffer {
|
||||
private:
|
||||
/**
|
||||
* @brief proxy of the memory (same for all chunks in the same buffer)
|
||||
* brief refers to the chunknumber within the executiongroup where related to the MemoryProxy
|
||||
* @see memoryProxy
|
||||
*/
|
||||
MemoryProxy *m_memoryProxy;
|
||||
unsigned int m_chunkNumber;
|
||||
|
||||
|
||||
/**
|
||||
* @brief the type of buffer COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR
|
||||
* @brief state of the buffer
|
||||
*/
|
||||
DataType m_datatype;
|
||||
|
||||
MemoryBufferState m_state;
|
||||
|
||||
/**
|
||||
* @brief the number of channels that form a single pixel in this buffer
|
||||
*/
|
||||
unsigned int m_no_channels;
|
||||
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief width of the chunk
|
||||
*/
|
||||
unsigned int m_chunkWidth;
|
||||
|
||||
/**
|
||||
* @brief region of this buffer inside relative to the MemoryProxy
|
||||
*/
|
||||
rcti m_rect;
|
||||
|
||||
/**
|
||||
* brief refers to the chunknumber within the executiongroup where related to the MemoryProxy
|
||||
* @see memoryProxy
|
||||
* @brief proxy of the memory (same for all chunks in the same buffer)
|
||||
*/
|
||||
unsigned int m_chunkNumber;
|
||||
|
||||
/**
|
||||
* @brief width of the chunk
|
||||
*/
|
||||
unsigned int m_chunkWidth;
|
||||
|
||||
/**
|
||||
* @brief state of the buffer
|
||||
*/
|
||||
MemoryBufferState m_state;
|
||||
|
||||
MemoryProxy *m_memoryProxy;
|
||||
|
||||
/**
|
||||
* @brief the actual float buffer/data
|
||||
*/
|
||||
float *m_buffer;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief construct new MemoryBuffer for a chunk
|
||||
*
|
||||
* @param no_channels Number of channels that must be allocated for every pixel
|
||||
*/
|
||||
MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
|
||||
MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect, unsigned int no_channels);
|
||||
|
||||
/**
|
||||
* @brief construct new temporarily MemoryBuffer for an area
|
||||
*
|
||||
* @param no_channels Number of channels that must be allocated for every pixel
|
||||
*/
|
||||
MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect);
|
||||
|
||||
MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect, unsigned int no_channels);
|
||||
|
||||
/**
|
||||
* @brief construct new temporarily MemoryBuffer for an area
|
||||
*
|
||||
* @param no_channels Number of channels that must be allocated for every pixel
|
||||
*/
|
||||
MemoryBuffer(DataType datatype, rcti *rect, unsigned int no_channels);
|
||||
public:
|
||||
/**
|
||||
* @brief factory method for the constructor, selecting the right subclass
|
||||
*/
|
||||
static MemoryBuffer* create(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
|
||||
|
||||
/**
|
||||
* @brief factory method for the constructor, selecting the right subclass, creating a temporarily buffer
|
||||
*/
|
||||
static MemoryBuffer* create(MemoryProxy *memoryProxy, rcti *rect);
|
||||
|
||||
/**
|
||||
* @brief factory method for the constructor, selecting the right subclass, creating a temporarily buffer
|
||||
*/
|
||||
static MemoryBuffer* create(DataType datatype, rcti *rect);
|
||||
|
||||
/**
|
||||
* @brief destructor
|
||||
*/
|
||||
~MemoryBuffer();
|
||||
virtual ~MemoryBuffer();
|
||||
|
||||
/**
|
||||
* @brief read the ChunkNumber of this MemoryBuffer
|
||||
@@ -164,89 +191,24 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
inline void read(float result[4], int x, int y,
|
||||
virtual void read(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP)
|
||||
{
|
||||
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
|
||||
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
|
||||
if (clip_x || clip_y) {
|
||||
/* clip result outside rect is zero */
|
||||
zero_v4(result);
|
||||
}
|
||||
else {
|
||||
wrap_pixel(x, y, extend_x, extend_y);
|
||||
const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS;
|
||||
copy_v4_v4(result, &this->m_buffer[offset]);
|
||||
}
|
||||
}
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP) = 0;
|
||||
|
||||
inline void readNoCheck(float result[4], int x, int y,
|
||||
|
||||
virtual void readNoCheck(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP)
|
||||
{
|
||||
wrap_pixel(x, y, extend_x, extend_y);
|
||||
const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS;
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP) = 0;
|
||||
|
||||
BLI_assert(offset >= 0);
|
||||
BLI_assert(offset < this->determineBufferSize() * COM_NUMBER_OF_CHANNELS);
|
||||
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
|
||||
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
|
||||
|
||||
#if 0
|
||||
/* always true */
|
||||
BLI_assert((int)(MEM_allocN_len(this->m_buffer) / sizeof(*this->m_buffer)) ==
|
||||
(int)(this->determineBufferSize() * COM_NUMBER_OF_CHANNELS));
|
||||
#endif
|
||||
|
||||
copy_v4_v4(result, &this->m_buffer[offset]);
|
||||
}
|
||||
|
||||
void writePixel(int x, int y, const float color[4]);
|
||||
void addPixel(int x, int y, const float color[4]);
|
||||
inline void readBilinear(float result[4], float x, float y,
|
||||
|
||||
virtual void writePixel(int x, int y, const float *color) = 0;
|
||||
virtual void addPixel(int x, int y, const float *color) = 0;
|
||||
virtual void readBilinear(float *result, float x, float y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP)
|
||||
{
|
||||
int x1 = floor(x);
|
||||
int y1 = floor(y);
|
||||
int x2 = x1 + 1;
|
||||
int y2 = y1 + 1;
|
||||
wrap_pixel(x1, y1, extend_x, extend_y);
|
||||
wrap_pixel(x2, y2, extend_x, extend_y);
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP) = 0;
|
||||
|
||||
float valuex = x - x1;
|
||||
float valuey = y - y1;
|
||||
float mvaluex = 1.0f - valuex;
|
||||
float mvaluey = 1.0f - valuey;
|
||||
|
||||
float color1[4];
|
||||
float color2[4];
|
||||
float color3[4];
|
||||
float color4[4];
|
||||
|
||||
read(color1, x1, y1);
|
||||
read(color2, x1, y2);
|
||||
read(color3, x2, y1);
|
||||
read(color4, x2, y2);
|
||||
|
||||
color1[0] = color1[0] * mvaluey + color2[0] * valuey;
|
||||
color1[1] = color1[1] * mvaluey + color2[1] * valuey;
|
||||
color1[2] = color1[2] * mvaluey + color2[2] * valuey;
|
||||
color1[3] = color1[3] * mvaluey + color2[3] * valuey;
|
||||
|
||||
color3[0] = color3[0] * mvaluey + color4[0] * valuey;
|
||||
color3[1] = color3[1] * mvaluey + color4[1] * valuey;
|
||||
color3[2] = color3[2] * mvaluey + color4[2] * valuey;
|
||||
color3[3] = color3[3] * mvaluey + color4[3] * valuey;
|
||||
|
||||
result[0] = color1[0] * mvaluex + color3[0] * valuex;
|
||||
result[1] = color1[1] * mvaluex + color3[1] * valuex;
|
||||
result[2] = color1[2] * mvaluex + color3[2] * valuex;
|
||||
result[3] = color1[3] * mvaluex + color3[3] * valuex;
|
||||
}
|
||||
|
||||
void readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler);
|
||||
virtual void readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler) {}
|
||||
|
||||
/**
|
||||
* @brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk)
|
||||
@@ -282,13 +244,23 @@ public:
|
||||
*/
|
||||
void clear();
|
||||
|
||||
MemoryBuffer *duplicate();
|
||||
virtual MemoryBuffer *duplicate() = 0;
|
||||
|
||||
float *convertToValueBuffer();
|
||||
float getMaximumValue();
|
||||
virtual float getMaximumValue() const;
|
||||
float getMaximumValue(rcti *rect);
|
||||
private:
|
||||
unsigned int determineBufferSize();
|
||||
|
||||
/**
|
||||
* @brief return the number of channels that form a single pixel.
|
||||
*
|
||||
* Value = 1
|
||||
* Vector= 3
|
||||
* Color = 4
|
||||
*/
|
||||
const int get_no_channels() const;
|
||||
|
||||
protected:
|
||||
unsigned int determineBufferSize() const;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBuffer")
|
||||
|
291
source/blender/compositor/intern/COM_MemoryBufferColor.cpp
Normal file
291
source/blender/compositor/intern/COM_MemoryBufferColor.cpp
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright 2014, Blender Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor:
|
||||
* Jeroen Bakker
|
||||
* Monique Dewanchand
|
||||
*/
|
||||
|
||||
#include "COM_MemoryBufferColor.h"
|
||||
|
||||
#define NUMBER_OF_CHANNELS COM_NO_CHANNELS_COLOR
|
||||
|
||||
MemoryBufferColor::MemoryBufferColor(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect):
|
||||
MemoryBuffer(memoryProxy, chunkNumber, rect, NUMBER_OF_CHANNELS)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBufferColor::MemoryBufferColor(MemoryProxy *memoryProxy, rcti *rect) :
|
||||
MemoryBuffer(memoryProxy, rect, NUMBER_OF_CHANNELS)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBufferColor::MemoryBufferColor(DataType datatype, rcti *rect) :
|
||||
MemoryBuffer(datatype, rect, NUMBER_OF_CHANNELS) {
|
||||
}
|
||||
|
||||
|
||||
MemoryBuffer *MemoryBufferColor::duplicate()
|
||||
{
|
||||
MemoryBufferColor *result = new MemoryBufferColor(this->m_memoryProxy, &this->m_rect);
|
||||
memcpy(result->getBuffer(), this->getBuffer(), this->determineBufferSize() * NUMBER_OF_CHANNELS * sizeof(float));
|
||||
return result;
|
||||
}
|
||||
|
||||
// --- write pixels ---
|
||||
void MemoryBufferColor::writePixel(int x, int y, const float *color)
|
||||
{
|
||||
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
|
||||
y >= this->m_rect.ymin && y < this->m_rect.ymax)
|
||||
{
|
||||
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
|
||||
copy_v4_v4(&this->m_buffer[offset], color);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBufferColor::addPixel(int x, int y, const float *color)
|
||||
{
|
||||
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
|
||||
y >= this->m_rect.ymin && y < this->m_rect.ymax)
|
||||
{
|
||||
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
|
||||
add_v4_v4(&this->m_buffer[offset], color);
|
||||
}
|
||||
}
|
||||
|
||||
// --- SAMPLERS ---
|
||||
inline void MemoryBufferColor::read(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x,
|
||||
MemoryBufferExtend extend_y)
|
||||
{
|
||||
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
|
||||
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
|
||||
if (clip_x || clip_y) {
|
||||
/* clip result outside rect is zero */
|
||||
zero_v4(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
wrap_pixel(x, y, extend_x, extend_y);
|
||||
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
|
||||
copy_v4_v4(result, &this->m_buffer[offset]);
|
||||
}
|
||||
}
|
||||
|
||||
inline void MemoryBufferColor::readNoCheck(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x,
|
||||
MemoryBufferExtend extend_y)
|
||||
{
|
||||
|
||||
wrap_pixel(x, y, extend_x, extend_y);
|
||||
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
|
||||
|
||||
BLI_assert(offset >= 0);
|
||||
BLI_assert(offset < this->determineBufferSize() * NUMBER_OF_CHANNELS);
|
||||
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
|
||||
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
|
||||
|
||||
copy_v4_v4(result, &this->m_buffer[offset]);
|
||||
}
|
||||
|
||||
inline void MemoryBufferColor::readBilinear(float *result, float x, float y,
|
||||
MemoryBufferExtend extend_x,
|
||||
MemoryBufferExtend extend_y)
|
||||
{
|
||||
int x1 = floor(x);
|
||||
int y1 = floor(y);
|
||||
int x2 = x1 + 1;
|
||||
int y2 = y1 + 1;
|
||||
wrap_pixel(x1, y1, extend_x, extend_y);
|
||||
wrap_pixel(x2, y2, extend_x, extend_y);
|
||||
|
||||
float valuex = x - x1;
|
||||
float valuey = y - y1;
|
||||
float mvaluex = 1.0f - valuex;
|
||||
float mvaluey = 1.0f - valuey;
|
||||
|
||||
float color1[4];
|
||||
float color2[4];
|
||||
float color3[4];
|
||||
float color4[4];
|
||||
|
||||
read(color1, x1, y1);
|
||||
read(color2, x1, y2);
|
||||
read(color3, x2, y1);
|
||||
read(color4, x2, y2);
|
||||
|
||||
color1[0] = color1[0] * mvaluey + color2[0] * valuey;
|
||||
color1[1] = color1[1] * mvaluey + color2[1] * valuey;
|
||||
color1[2] = color1[2] * mvaluey + color2[2] * valuey;
|
||||
color1[3] = color1[3] * mvaluey + color2[3] * valuey;
|
||||
|
||||
color3[0] = color3[0] * mvaluey + color4[0] * valuey;
|
||||
color3[1] = color3[1] * mvaluey + color4[1] * valuey;
|
||||
color3[2] = color3[2] * mvaluey + color4[2] * valuey;
|
||||
color3[3] = color3[3] * mvaluey + color4[3] * valuey;
|
||||
|
||||
result[0] = color1[0] * mvaluex + color3[0] * valuex;
|
||||
result[1] = color1[1] * mvaluex + color3[1] * valuex;
|
||||
result[2] = color1[2] * mvaluex + color3[2] * valuex;
|
||||
result[3] = color1[3] * mvaluex + color3[3] * valuex;
|
||||
}
|
||||
|
||||
// --- EWA Filtering ---
|
||||
// table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2
|
||||
// used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible
|
||||
#define EWA_MAXIDX 255
|
||||
static const float EWA_WTS[EWA_MAXIDX + 1] = {
|
||||
1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
|
||||
0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
|
||||
0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
|
||||
0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f,
|
||||
0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f,
|
||||
0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f,
|
||||
0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f,
|
||||
0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f,
|
||||
0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f,
|
||||
0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f,
|
||||
0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f,
|
||||
0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f,
|
||||
0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f,
|
||||
0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f,
|
||||
0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f,
|
||||
0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f,
|
||||
0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f,
|
||||
0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f,
|
||||
0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f,
|
||||
0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f,
|
||||
0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f,
|
||||
0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f,
|
||||
0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f,
|
||||
0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f,
|
||||
0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f,
|
||||
0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f,
|
||||
0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f,
|
||||
0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f,
|
||||
0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f,
|
||||
0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f,
|
||||
0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f,
|
||||
0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f
|
||||
};
|
||||
|
||||
static void ellipse_bounds(float A, float B, float C, float F, float &xmax, float &ymax)
|
||||
{
|
||||
float denom = 4.0f * A * C - B * B;
|
||||
if (denom > 0.0f && A != 0.0f && C != 0.0f) {
|
||||
xmax = sqrtf(F) / (2.0f * A) * (sqrtf(F * (4.0f * A - B * B / C)) + B * B * sqrtf(F / (C * denom)));
|
||||
ymax = sqrtf(F) / (2.0f * C) * (sqrtf(F * (4.0f * C - B * B / A)) + B * B * sqrtf(F / (A * denom)));
|
||||
}
|
||||
else {
|
||||
xmax = 0.0f;
|
||||
ymax = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void ellipse_params(float Ux, float Uy, float Vx, float Vy,
|
||||
float &A, float &B, float &C, float &F, float &umax, float &vmax)
|
||||
{
|
||||
A = Vx * Vx + Vy * Vy;
|
||||
B = -2.0f * (Ux * Vx + Uy * Vy);
|
||||
C = Ux * Ux + Uy * Uy;
|
||||
F = A * C - B * B * 0.25f;
|
||||
|
||||
float factor = (F != 0.0f ? (float)(EWA_MAXIDX + 1) / F : 0.0f);
|
||||
A *= factor;
|
||||
B *= factor;
|
||||
C *= factor;
|
||||
F = (float)(EWA_MAXIDX + 1);
|
||||
|
||||
ellipse_bounds(A, B, C, sqrtf(F), umax, vmax);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filtering method based on
|
||||
* "Creating raster omnimax images from multiple perspective views using the elliptical weighted average filter"
|
||||
* by Ned Greene and Paul S. Heckbert (1986)
|
||||
*/
|
||||
void MemoryBufferColor::readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler)
|
||||
{
|
||||
zero_v4(result);
|
||||
int width = this->getWidth(), height = this->getHeight();
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
float u = uv[0], v = uv[1];
|
||||
float Ux = derivatives[0][0], Vx = derivatives[1][0], Uy = derivatives[0][1], Vy = derivatives[1][1];
|
||||
float A, B, C, F, ue, ve;
|
||||
ellipse_params(Ux, Uy, Vx, Vy, A, B, C, F, ue, ve);
|
||||
|
||||
/* Note: highly eccentric ellipses can lead to large texture space areas to filter!
|
||||
* This is limited somewhat by the EWA_WTS size in the loop, but a nicer approach
|
||||
* could be the one found in
|
||||
* "High Quality Elliptical Texture Filtering on GPU"
|
||||
* by Pavlos Mavridis and Georgios Papaioannou
|
||||
* in which the eccentricity of the ellipse is clamped.
|
||||
*/
|
||||
|
||||
int U0 = (int)u;
|
||||
int V0 = (int)v;
|
||||
/* pixel offset for interpolation */
|
||||
float ufac = u - floorf(u), vfac = v - floorf(v);
|
||||
/* filter size */
|
||||
int u1 = (int)(u - ue);
|
||||
int u2 = (int)(u + ue);
|
||||
int v1 = (int)(v - ve);
|
||||
int v2 = (int)(v + ve);
|
||||
|
||||
/* sane clamping to avoid unnecessarily huge loops */
|
||||
/* note: if eccentricity gets clamped (see above),
|
||||
* the ue/ve limits can also be lowered accordingly
|
||||
*/
|
||||
if (U0 - u1 > EWA_MAXIDX) u1 = U0 - EWA_MAXIDX;
|
||||
if (u2 - U0 > EWA_MAXIDX) u2 = U0 + EWA_MAXIDX;
|
||||
if (V0 - v1 > EWA_MAXIDX) v1 = V0 - EWA_MAXIDX;
|
||||
if (v2 - V0 > EWA_MAXIDX) v2 = V0 + EWA_MAXIDX;
|
||||
|
||||
float DDQ = 2.0f * A;
|
||||
float U = u1 - U0;
|
||||
float ac1 = A * (2.0f * U + 1.0f);
|
||||
float ac2 = A * U * U;
|
||||
float BU = B * U;
|
||||
|
||||
float sum = 0.0f;
|
||||
for (int v = v1; v <= v2; ++v) {
|
||||
float V = v - V0;
|
||||
|
||||
float DQ = ac1 + B * V;
|
||||
float Q = (C * V + BU) * V + ac2;
|
||||
for (int u = u1; u <= u2; ++u) {
|
||||
if (Q < F) {
|
||||
float tc[4];
|
||||
const float wt = EWA_WTS[CLAMPIS((int)Q, 0, EWA_MAXIDX)];
|
||||
switch (sampler) {
|
||||
case COM_PS_NEAREST: read(tc, u, v); break;
|
||||
case COM_PS_BILINEAR: readBilinear(tc, (float)u + ufac, (float)v + vfac); break;
|
||||
case COM_PS_BICUBIC: readBilinear(tc, (float)u + ufac, (float)v + vfac); break; /* XXX no readBicubic method yet */
|
||||
default: zero_v4(tc); break;
|
||||
}
|
||||
madd_v4_v4fl(result, tc, wt);
|
||||
sum += wt;
|
||||
}
|
||||
Q += DQ;
|
||||
DQ += DDQ;
|
||||
}
|
||||
}
|
||||
|
||||
mul_v4_fl(result, (sum != 0.0f ? 1.0f / sum : 0.0f));
|
||||
}
|
71
source/blender/compositor/intern/COM_MemoryBufferColor.h
Normal file
71
source/blender/compositor/intern/COM_MemoryBufferColor.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2014, Blender Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor:
|
||||
* Jeroen Bakker
|
||||
* Monique Dewanchand
|
||||
*/
|
||||
|
||||
class MemoryBufferColor;
|
||||
|
||||
#ifndef _COM_MemoryBufferColor_h_
|
||||
#define _COM_MemoryBufferColor_h_
|
||||
|
||||
#include "COM_MemoryBuffer.h"
|
||||
|
||||
class MemoryBufferColor: MemoryBuffer
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* @brief construct new MemoryBuffer for a chunk
|
||||
*/
|
||||
MemoryBufferColor(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
|
||||
|
||||
/**
|
||||
* @brief construct new temporarily MemoryBuffer for an area
|
||||
*/
|
||||
MemoryBufferColor(MemoryProxy *memoryProxy, rcti *rect);
|
||||
|
||||
MemoryBufferColor(DataType datatype, rcti *rect);
|
||||
public:
|
||||
void writePixel(int x, int y, const float *color);
|
||||
void addPixel(int x, int y, const float *color);
|
||||
void read(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP);
|
||||
|
||||
void readNoCheck(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP);
|
||||
|
||||
void readBilinear(float *result, float x, float y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP);
|
||||
|
||||
void readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler);
|
||||
|
||||
MemoryBuffer *duplicate();
|
||||
|
||||
|
||||
friend class MemoryBuffer;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBufferColor")
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
152
source/blender/compositor/intern/COM_MemoryBufferValue.cpp
Normal file
152
source/blender/compositor/intern/COM_MemoryBufferValue.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2014, Blender Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor:
|
||||
* Jeroen Bakker
|
||||
* Monique Dewanchand
|
||||
*/
|
||||
|
||||
#include "COM_MemoryBufferValue.h"
|
||||
|
||||
#define NUMBER_OF_CHANNELS COM_NO_CHANNELS_VALUE
|
||||
|
||||
MemoryBufferValue::MemoryBufferValue(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect):
|
||||
MemoryBuffer(memoryProxy, chunkNumber, rect, NUMBER_OF_CHANNELS)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBufferValue::MemoryBufferValue(MemoryProxy *memoryProxy, rcti *rect) :
|
||||
MemoryBuffer(memoryProxy, rect, NUMBER_OF_CHANNELS)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBufferValue::MemoryBufferValue(DataType datatype, rcti *rect) :
|
||||
MemoryBuffer(datatype, rect, NUMBER_OF_CHANNELS) {
|
||||
}
|
||||
|
||||
MemoryBuffer *MemoryBufferValue::duplicate()
|
||||
{
|
||||
MemoryBufferValue *result = new MemoryBufferValue(this->m_memoryProxy, &this->m_rect);
|
||||
memcpy(result->getBuffer(), this->getBuffer(), this->determineBufferSize() * NUMBER_OF_CHANNELS * sizeof(float));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// --- write pixels ---
|
||||
void MemoryBufferValue::writePixel(int x, int y, const float *color)
|
||||
{
|
||||
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
|
||||
y >= this->m_rect.ymin && y < this->m_rect.ymax)
|
||||
{
|
||||
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
|
||||
copy_v4_v4(&this->m_buffer[offset], color);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBufferValue::addPixel(int x, int y, const float *color)
|
||||
{
|
||||
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
|
||||
y >= this->m_rect.ymin && y < this->m_rect.ymax)
|
||||
{
|
||||
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
|
||||
this->m_buffer[offset] = color[0];
|
||||
}
|
||||
}
|
||||
|
||||
// --- SAMPLERS ---
|
||||
inline void MemoryBufferValue::read(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x,
|
||||
MemoryBufferExtend extend_y)
|
||||
{
|
||||
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
|
||||
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
|
||||
if (clip_x || clip_y) {
|
||||
/* clip result outside rect is zero */
|
||||
zero_v4(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
wrap_pixel(x, y, extend_x, extend_y);
|
||||
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
|
||||
result[0] = this->m_buffer[offset];
|
||||
}
|
||||
}
|
||||
|
||||
inline void MemoryBufferValue::readNoCheck(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x,
|
||||
MemoryBufferExtend extend_y)
|
||||
{
|
||||
|
||||
wrap_pixel(x, y, extend_x, extend_y);
|
||||
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
|
||||
|
||||
BLI_assert(offset >= 0);
|
||||
BLI_assert(offset < this->determineBufferSize() * NUMBER_OF_CHANNELS);
|
||||
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
|
||||
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
|
||||
|
||||
result[0] = this->m_buffer[offset];
|
||||
}
|
||||
|
||||
inline void MemoryBufferValue::readBilinear(float *result, float x, float y,
|
||||
MemoryBufferExtend extend_x,
|
||||
MemoryBufferExtend extend_y)
|
||||
{
|
||||
int x1 = floor(x);
|
||||
int y1 = floor(y);
|
||||
int x2 = x1 + 1;
|
||||
int y2 = y1 + 1;
|
||||
wrap_pixel(x1, y1, extend_x, extend_y);
|
||||
wrap_pixel(x2, y2, extend_x, extend_y);
|
||||
|
||||
float valuex = x - x1;
|
||||
float valuey = y - y1;
|
||||
float mvaluex = 1.0f - valuex;
|
||||
float mvaluey = 1.0f - valuey;
|
||||
|
||||
float value1;
|
||||
float value2;
|
||||
float value3;
|
||||
float value4;
|
||||
|
||||
read(&value1, x1, y1);
|
||||
read(&value2, x1, y2);
|
||||
read(&value3, x2, y1);
|
||||
read(&value4, x2, y2);
|
||||
|
||||
value1 = value1 * mvaluey + value2 * valuey;
|
||||
value3 = value3 * mvaluey + value4 * valuey;
|
||||
result[0] = value1 * mvaluex + value3 * valuex;
|
||||
}
|
||||
|
||||
float MemoryBufferValue::getMaximumValue() const
|
||||
{
|
||||
float result = this->m_buffer[0];
|
||||
const unsigned int size = this->determineBufferSize();
|
||||
unsigned int i;
|
||||
|
||||
const float *fp_src = this->m_buffer;
|
||||
|
||||
for (i = 0; i < size; i++, fp_src += NUMBER_OF_CHANNELS) {
|
||||
float value = *fp_src;
|
||||
if (value > result) {
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
68
source/blender/compositor/intern/COM_MemoryBufferValue.h
Normal file
68
source/blender/compositor/intern/COM_MemoryBufferValue.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2014, Blender Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor:
|
||||
* Jeroen Bakker
|
||||
* Monique Dewanchand
|
||||
*/
|
||||
|
||||
class MemoryBufferValue;
|
||||
|
||||
#ifndef _COM_MemoryBufferValue_h_
|
||||
#define _COM_MemoryBufferValue_h_
|
||||
|
||||
#include "COM_MemoryBuffer.h"
|
||||
|
||||
class MemoryBufferValue: public MemoryBuffer
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* @brief construct new MemoryBuffer for a chunk
|
||||
*/
|
||||
MemoryBufferValue(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
|
||||
|
||||
/**
|
||||
* @brief construct new temporarily MemoryBuffer for an area
|
||||
*/
|
||||
MemoryBufferValue(MemoryProxy *memoryProxy, rcti *rect);
|
||||
MemoryBufferValue(DataType datatype, rcti *rect);
|
||||
|
||||
public:
|
||||
void writePixel(int x, int y, const float *color);
|
||||
void addPixel(int x, int y, const float *color);
|
||||
void read(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP);
|
||||
|
||||
void readNoCheck(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP);
|
||||
|
||||
void readBilinear(float *result, float x, float y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP);
|
||||
|
||||
float getMaximumValue() const;
|
||||
MemoryBuffer *duplicate();
|
||||
|
||||
friend class MemoryBuffer;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBufferValue")
|
||||
#endif
|
||||
};
|
||||
#endif
|
144
source/blender/compositor/intern/COM_MemoryBufferVector.cpp
Normal file
144
source/blender/compositor/intern/COM_MemoryBufferVector.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright 2014, Blender Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor:
|
||||
* Jeroen Bakker
|
||||
* Monique Dewanchand
|
||||
*/
|
||||
|
||||
#include "COM_MemoryBufferVector.h"
|
||||
|
||||
#define NUMBER_OF_CHANNELS COM_NO_CHANNELS_VECTOR
|
||||
|
||||
MemoryBufferVector::MemoryBufferVector(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect):
|
||||
MemoryBuffer(memoryProxy, chunkNumber, rect, NUMBER_OF_CHANNELS)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBufferVector::MemoryBufferVector(MemoryProxy *memoryProxy, rcti *rect) :
|
||||
MemoryBuffer(memoryProxy, rect, NUMBER_OF_CHANNELS)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBufferVector::MemoryBufferVector(DataType datatype, rcti *rect) :
|
||||
MemoryBuffer(datatype, rect, NUMBER_OF_CHANNELS) {
|
||||
}
|
||||
|
||||
|
||||
MemoryBuffer *MemoryBufferVector::duplicate()
|
||||
{
|
||||
MemoryBufferVector *result = new MemoryBufferVector(this->m_memoryProxy, &this->m_rect);
|
||||
memcpy(result->getBuffer(), this->getBuffer(), this->determineBufferSize() * NUMBER_OF_CHANNELS * sizeof(float));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// --- write pixels ---
|
||||
void MemoryBufferVector::writePixel(int x, int y, const float *color)
|
||||
{
|
||||
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
|
||||
y >= this->m_rect.ymin && y < this->m_rect.ymax)
|
||||
{
|
||||
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
|
||||
copy_v4_v4(&this->m_buffer[offset], color);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryBufferVector::addPixel(int x, int y, const float *color)
|
||||
{
|
||||
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
|
||||
y >= this->m_rect.ymin && y < this->m_rect.ymax)
|
||||
{
|
||||
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * NUMBER_OF_CHANNELS;
|
||||
add_v4_v4(&this->m_buffer[offset], color);
|
||||
}
|
||||
}
|
||||
|
||||
// --- SAMPLERS ---
|
||||
inline void MemoryBufferVector::read(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x,
|
||||
MemoryBufferExtend extend_y)
|
||||
{
|
||||
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
|
||||
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
|
||||
if (clip_x || clip_y) {
|
||||
/* clip result outside rect is zero */
|
||||
zero_v4(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
wrap_pixel(x, y, extend_x, extend_y);
|
||||
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
|
||||
copy_v4_v4(result, &this->m_buffer[offset]);
|
||||
}
|
||||
}
|
||||
|
||||
inline void MemoryBufferVector::readNoCheck(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x,
|
||||
MemoryBufferExtend extend_y)
|
||||
{
|
||||
|
||||
wrap_pixel(x, y, extend_x, extend_y);
|
||||
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
|
||||
|
||||
BLI_assert(offset >= 0);
|
||||
BLI_assert(offset < this->determineBufferSize() * NUMBER_OF_CHANNELS);
|
||||
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
|
||||
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
|
||||
|
||||
copy_v4_v4(result, &this->m_buffer[offset]);
|
||||
}
|
||||
|
||||
inline void MemoryBufferVector::readBilinear(float *result, float x, float y,
|
||||
MemoryBufferExtend extend_x,
|
||||
MemoryBufferExtend extend_y)
|
||||
{
|
||||
int x1 = floor(x);
|
||||
int y1 = floor(y);
|
||||
int x2 = x1 + 1;
|
||||
int y2 = y1 + 1;
|
||||
wrap_pixel(x1, y1, extend_x, extend_y);
|
||||
wrap_pixel(x2, y2, extend_x, extend_y);
|
||||
|
||||
float valuex = x - x1;
|
||||
float valuey = y - y1;
|
||||
float mvaluex = 1.0f - valuex;
|
||||
float mvaluey = 1.0f - valuey;
|
||||
|
||||
float vector1[NUMBER_OF_CHANNELS];
|
||||
float vector2[NUMBER_OF_CHANNELS];
|
||||
float vector3[NUMBER_OF_CHANNELS];
|
||||
float vector4[NUMBER_OF_CHANNELS];
|
||||
|
||||
read(vector1, x1, y1);
|
||||
read(vector2, x1, y2);
|
||||
read(vector3, x2, y1);
|
||||
read(vector4, x2, y2);
|
||||
|
||||
vector1[0] = vector1[0] * mvaluey + vector2[0] * valuey;
|
||||
vector1[1] = vector1[1] * mvaluey + vector2[1] * valuey;
|
||||
vector1[2] = vector1[2] * mvaluey + vector2[2] * valuey;
|
||||
|
||||
vector3[0] = vector3[0] * mvaluey + vector4[0] * valuey;
|
||||
vector3[1] = vector3[1] * mvaluey + vector4[1] * valuey;
|
||||
vector3[2] = vector3[2] * mvaluey + vector4[2] * valuey;
|
||||
|
||||
result[0] = vector1[0] * mvaluex + vector3[0] * valuex;
|
||||
result[1] = vector1[1] * mvaluex + vector3[1] * valuex;
|
||||
result[2] = vector1[2] * mvaluex + vector3[2] * valuex;
|
||||
}
|
||||
|
67
source/blender/compositor/intern/COM_MemoryBufferVector.h
Normal file
67
source/blender/compositor/intern/COM_MemoryBufferVector.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2014, Blender Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor:
|
||||
* Jeroen Bakker
|
||||
* Monique Dewanchand
|
||||
*/
|
||||
|
||||
class MemoryBufferVector;
|
||||
|
||||
#ifndef _COM_MemoryBufferVector_h_
|
||||
#define _COM_MemoryBufferVector_h_
|
||||
|
||||
#include "COM_MemoryBuffer.h"
|
||||
|
||||
class MemoryBufferVector: public MemoryBuffer
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* @brief construct new MemoryBuffer for a chunk
|
||||
*/
|
||||
MemoryBufferVector(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
|
||||
|
||||
/**
|
||||
* @brief construct new temporarily MemoryBuffer for an area
|
||||
*/
|
||||
MemoryBufferVector(MemoryProxy *memoryProxy, rcti *rect);
|
||||
MemoryBufferVector(DataType datatype, rcti *rect);
|
||||
|
||||
public:
|
||||
void writePixel(int x, int y, const float *color);
|
||||
void addPixel(int x, int y, const float *color);
|
||||
void read(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP);
|
||||
|
||||
void readNoCheck(float *result, int x, int y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP);
|
||||
|
||||
void readBilinear(float *result, float x, float y,
|
||||
MemoryBufferExtend extend_x = COM_MB_CLIP,
|
||||
MemoryBufferExtend extend_y = COM_MB_CLIP);
|
||||
|
||||
MemoryBuffer *duplicate();
|
||||
|
||||
friend class MemoryBuffer;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBufferVector")
|
||||
#endif
|
||||
};
|
||||
#endif
|
@@ -23,10 +23,11 @@
|
||||
#include "COM_MemoryProxy.h"
|
||||
|
||||
|
||||
MemoryProxy::MemoryProxy()
|
||||
MemoryProxy::MemoryProxy(DataType type)
|
||||
{
|
||||
this->m_writeBufferOperation = NULL;
|
||||
this->m_executor = NULL;
|
||||
this->m_datatype = type;
|
||||
}
|
||||
|
||||
void MemoryProxy::allocate(unsigned int width, unsigned int height)
|
||||
@@ -37,7 +38,7 @@ void MemoryProxy::allocate(unsigned int width, unsigned int height)
|
||||
result.ymin = 0;
|
||||
result.ymax = height;
|
||||
|
||||
this->m_buffer = new MemoryBuffer(this, 1, &result);
|
||||
this->m_buffer = MemoryBuffer::create(this, 1, &result);
|
||||
}
|
||||
|
||||
void MemoryProxy::free()
|
||||
|
@@ -47,12 +47,7 @@ private:
|
||||
* @brief reference to the executor. the Execution group that can fill a chunk
|
||||
*/
|
||||
ExecutionGroup *m_executor;
|
||||
|
||||
/**
|
||||
* @brief datatype of this MemoryProxy
|
||||
*/
|
||||
/* DataType m_datatype; */ /* UNUSED */
|
||||
|
||||
|
||||
/**
|
||||
* @brief channel information of this buffer
|
||||
*/
|
||||
@@ -63,8 +58,13 @@ private:
|
||||
*/
|
||||
MemoryBuffer *m_buffer;
|
||||
|
||||
/**
|
||||
* @brief datatype of this MemoryProxy
|
||||
*/
|
||||
DataType m_datatype;
|
||||
|
||||
public:
|
||||
MemoryProxy();
|
||||
MemoryProxy(DataType type);
|
||||
|
||||
/**
|
||||
* @brief set the ExecutionGroup that can be scheduled to calculate a certain chunk.
|
||||
@@ -104,6 +104,8 @@ public:
|
||||
*/
|
||||
inline MemoryBuffer *getBuffer() { return this->m_buffer; }
|
||||
|
||||
inline DataType getDataType() { return this->m_datatype; }
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryProxy")
|
||||
#endif
|
||||
|
@@ -448,7 +448,7 @@ void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOpera
|
||||
/* check of other end already has write operation, otherwise add a new one */
|
||||
WriteBufferOperation *writeoperation = find_attached_write_buffer_operation(output);
|
||||
if (!writeoperation) {
|
||||
writeoperation = new WriteBufferOperation();
|
||||
writeoperation = new WriteBufferOperation(output->getDataType());
|
||||
writeoperation->setbNodeTree(m_context->getbNodeTree());
|
||||
addOperation(writeoperation);
|
||||
|
||||
@@ -458,7 +458,7 @@ void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOpera
|
||||
}
|
||||
|
||||
/* add readbuffer op for the input */
|
||||
ReadBufferOperation *readoperation = new ReadBufferOperation();
|
||||
ReadBufferOperation *readoperation = new ReadBufferOperation(output->getDataType());
|
||||
readoperation->setMemoryProxy(writeoperation->getMemoryProxy());
|
||||
this->addOperation(readoperation);
|
||||
|
||||
@@ -491,7 +491,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOper
|
||||
|
||||
/* if no write buffer operation exists yet, create a new one */
|
||||
if (!writeOperation) {
|
||||
writeOperation = new WriteBufferOperation();
|
||||
writeOperation = new WriteBufferOperation(operation->getOutputSocket()->getDataType());
|
||||
writeOperation->setbNodeTree(m_context->getbNodeTree());
|
||||
addOperation(writeOperation);
|
||||
|
||||
@@ -506,7 +506,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOper
|
||||
if (&target->getOperation() == writeOperation)
|
||||
continue; /* skip existing write op links */
|
||||
|
||||
ReadBufferOperation *readoperation = new ReadBufferOperation();
|
||||
ReadBufferOperation *readoperation = new ReadBufferOperation(operation->getOutputSocket()->getDataType());
|
||||
readoperation->setMemoryProxy(writeOperation->getMemoryProxy());
|
||||
addOperation(readoperation);
|
||||
|
||||
|
@@ -24,6 +24,18 @@
|
||||
#include "COM_WorkScheduler.h"
|
||||
|
||||
typedef enum COM_VendorID {NVIDIA = 0x10DE, AMD = 0x1002} COM_VendorID;
|
||||
const cl_image_format IMAGE_FORMAT_COLOR = {
|
||||
CL_RGBA,
|
||||
CL_FLOAT
|
||||
};
|
||||
const cl_image_format IMAGE_FORMAT_VECTOR = {
|
||||
CL_RGB,
|
||||
CL_FLOAT
|
||||
};
|
||||
const cl_image_format IMAGE_FORMAT_VALUE = {
|
||||
CL_R,
|
||||
CL_FLOAT
|
||||
};
|
||||
|
||||
OpenCLDevice::OpenCLDevice(cl_context context, cl_device_id device, cl_program program, cl_int vendorId)
|
||||
{
|
||||
@@ -72,6 +84,21 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel,
|
||||
return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation *)reader);
|
||||
}
|
||||
|
||||
const cl_image_format* OpenCLDevice::determineImageFormat(MemoryBuffer *memoryBuffer)
|
||||
{
|
||||
const cl_image_format *imageFormat;
|
||||
int no_channels = memoryBuffer->get_no_channels();
|
||||
if (no_channels == 1) {
|
||||
imageFormat = &IMAGE_FORMAT_VALUE;
|
||||
} else if (no_channels == 3) {
|
||||
imageFormat = &IMAGE_FORMAT_VECTOR;
|
||||
} else {
|
||||
imageFormat = &IMAGE_FORMAT_COLOR;
|
||||
}
|
||||
|
||||
return imageFormat;
|
||||
}
|
||||
|
||||
cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex,
|
||||
list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers,
|
||||
ReadBufferOperation *reader)
|
||||
@@ -80,12 +107,9 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel,
|
||||
|
||||
MemoryBuffer *result = reader->getInputMemoryBuffer(inputMemoryBuffers);
|
||||
|
||||
const cl_image_format imageFormat = {
|
||||
CL_RGBA,
|
||||
CL_FLOAT
|
||||
};
|
||||
const cl_image_format *imageFormat = determineImageFormat(result);
|
||||
|
||||
cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &imageFormat, result->getWidth(),
|
||||
cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, imageFormat, result->getWidth(),
|
||||
result->getHeight(), 0, result->getBuffer(), &error);
|
||||
|
||||
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
|
||||
@@ -192,5 +216,4 @@ cl_kernel OpenCLDevice::COM_clCreateKernel(const char *kernelname, list<cl_kerne
|
||||
if (clKernelsToCleanUp) clKernelsToCleanUp->push_back(kernel);
|
||||
}
|
||||
return kernel;
|
||||
|
||||
}
|
||||
|
@@ -94,6 +94,13 @@ public:
|
||||
*/
|
||||
void execute(WorkPackage *work);
|
||||
|
||||
/**
|
||||
* @brief determine an image format
|
||||
* @param memorybuffer
|
||||
*/
|
||||
|
||||
static const cl_image_format* determineImageFormat(MemoryBuffer *memoryBuffer);
|
||||
|
||||
cl_context getContext() { return this->m_context; }
|
||||
|
||||
cl_command_queue getQueue() { return this->m_queue; }
|
||||
|
83
source/blender/compositor/intern/COM_OutputSocket.h
Normal file
83
source/blender/compositor/intern/COM_OutputSocket.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2011, Blender Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor:
|
||||
* Jeroen Bakker
|
||||
* Monique Dewanchand
|
||||
*/
|
||||
|
||||
#ifndef _COM_OutputSocket_h
|
||||
#define _COM_OutputSocket_h
|
||||
|
||||
#include <vector>
|
||||
#include "COM_Socket.h"
|
||||
|
||||
using namespace std;
|
||||
class SocketConnection;
|
||||
class Node;
|
||||
class InputSocket;
|
||||
class WriteBufferOperation;
|
||||
|
||||
//#define COM_ST_INPUT 0
|
||||
//#define COM_ST_OUTPUT 1
|
||||
|
||||
/**
|
||||
* @brief OutputSocket are sockets that can send data/input
|
||||
* @ingroup Model
|
||||
*/
|
||||
class OutputSocket : public Socket {
|
||||
private:
|
||||
vector<SocketConnection *> m_connections;
|
||||
|
||||
void removeFirstConnection();
|
||||
public:
|
||||
OutputSocket(DataType datatype);
|
||||
OutputSocket(DataType datatype, int inputSocketDataTypeDeterminatorIndex);
|
||||
OutputSocket(OutputSocket *from);
|
||||
void addConnection(SocketConnection *connection);
|
||||
void removeConnection(SocketConnection *connection);
|
||||
SocketConnection *getConnection(unsigned int index) { return this->m_connections[index]; }
|
||||
const int isConnected() const;
|
||||
int isOutputSocket() const;
|
||||
|
||||
/**
|
||||
* @brief determine the resolution of this socket
|
||||
* @param resolution the result of this operation
|
||||
* @param preferredResolution the preferable resolution as no resolution could be determined
|
||||
*/
|
||||
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
|
||||
|
||||
/**
|
||||
* @brief determine the actual data type and channel info.
|
||||
*/
|
||||
void relinkConnections(OutputSocket *relinkToSocket) { this->relinkConnections(relinkToSocket, false); }
|
||||
void relinkConnections(OutputSocket *relinkToSocket, bool single);
|
||||
const int getNumberOfConnections() { return this->m_connections.size(); }
|
||||
|
||||
void clearConnections();
|
||||
|
||||
/**
|
||||
* @brief find a connected write buffer operation to this OutputSocket
|
||||
* @return WriteBufferOperation or NULL
|
||||
*/
|
||||
WriteBufferOperation *findAttachedWriteBufferOperation() const;
|
||||
ChannelInfo *getChannelInfo(const int channelnumber);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
#endif
|
126
source/blender/compositor/intern/COM_SocketConnection.h
Normal file
126
source/blender/compositor/intern/COM_SocketConnection.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2011, Blender Foundation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor:
|
||||
* Jeroen Bakker
|
||||
* Monique Dewanchand
|
||||
*/
|
||||
|
||||
#ifndef _COM_SocketConnection_h
|
||||
#define _COM_SocketConnection_h
|
||||
|
||||
#include "DNA_node_types.h"
|
||||
#include "COM_Node.h"
|
||||
#include "COM_Socket.h"
|
||||
|
||||
/**
|
||||
* @brief An SocketConnection is an connection between an InputSocket and an OutputSocket.
|
||||
*
|
||||
* <pre>
|
||||
* +----------+ To InputSocket +----------+
|
||||
* | From | SocketConnection \| To Node |
|
||||
* | Node *====================* |
|
||||
* | |\ | |
|
||||
* | | From OutputSocket +----------+
|
||||
* +----------+
|
||||
* </pre>
|
||||
* @ingroup Model
|
||||
* @see InputSocket
|
||||
* @see OutputSocket
|
||||
*/
|
||||
class SocketConnection {
|
||||
private:
|
||||
/**
|
||||
* @brief Startpoint of the connection
|
||||
*/
|
||||
OutputSocket *m_fromSocket;
|
||||
|
||||
/**
|
||||
* @brief Endpoint of the connection
|
||||
*/
|
||||
InputSocket *m_toSocket;
|
||||
|
||||
/**
|
||||
* @brief has the resize already been done for this connection
|
||||
*/
|
||||
bool m_ignoreResizeCheck;
|
||||
public:
|
||||
SocketConnection();
|
||||
|
||||
/**
|
||||
* @brief set the startpoint of the connection
|
||||
* @param fromsocket
|
||||
*/
|
||||
void setFromSocket(OutputSocket *fromsocket);
|
||||
|
||||
/**
|
||||
* @brief get the startpoint of the connection
|
||||
* @return from OutputSocket
|
||||
*/
|
||||
OutputSocket *getFromSocket() const;
|
||||
|
||||
/**
|
||||
* @brief set the endpoint of the connection
|
||||
* @param tosocket
|
||||
*/
|
||||
void setToSocket(InputSocket *tosocket);
|
||||
|
||||
/**
|
||||
* @brief get the endpoint of the connection
|
||||
* @return to InputSocket
|
||||
*/
|
||||
InputSocket *getToSocket() const;
|
||||
|
||||
/**
|
||||
* @brief check if this connection is valid
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
/**
|
||||
* @brief return the Node where this connection is connected from
|
||||
*/
|
||||
NodeBase *getFromNode() const;
|
||||
|
||||
/**
|
||||
* @brief return the Node where this connection is connected to
|
||||
*/
|
||||
NodeBase *getToNode() const;
|
||||
|
||||
/**
|
||||
* @brief set, whether the resize has already been done for this SocketConnection
|
||||
*/
|
||||
void setIgnoreResizeCheck(bool check) { this->m_ignoreResizeCheck = check; }
|
||||
|
||||
/**
|
||||
* @brief has the resize already been done for this SocketConnection
|
||||
*/
|
||||
bool isIgnoreResizeCheck() const { return this->m_ignoreResizeCheck; }
|
||||
|
||||
/**
|
||||
* @brief does this SocketConnection need resolution conversion
|
||||
* @note PreviewOperation's will be ignored
|
||||
* @note Already converted SocketConnection's will be ignored
|
||||
* @return needs conversion [true:false]
|
||||
*/
|
||||
bool needsResolutionConversion() const;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("COM:SocketConnection")
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
@@ -71,8 +71,9 @@ void SocketBufferNode::convertToOperations(NodeConverter &converter, const Compo
|
||||
NodeOutput *output = this->getOutputSocket(0);
|
||||
NodeInput *input = this->getInputSocket(0);
|
||||
|
||||
WriteBufferOperation *writeOperation = new WriteBufferOperation();
|
||||
ReadBufferOperation *readOperation = new ReadBufferOperation();
|
||||
DataType datatype = output->getDataType();
|
||||
WriteBufferOperation *writeOperation = new WriteBufferOperation(datatype);
|
||||
ReadBufferOperation *readOperation = new ReadBufferOperation(datatype);
|
||||
readOperation->setMemoryProxy(writeOperation->getMemoryProxy());
|
||||
converter.addOperation(writeOperation);
|
||||
converter.addOperation(readOperation);
|
||||
|
@@ -57,8 +57,8 @@ void TranslateNode::convertToOperations(NodeConverter &converter, const Composit
|
||||
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
|
||||
|
||||
if (data->wrap_axis) {
|
||||
WriteBufferOperation *writeOperation = new WriteBufferOperation();
|
||||
WrapOperation *wrapOperation = new WrapOperation();
|
||||
WriteBufferOperation *writeOperation = new WriteBufferOperation(COM_DT_COLOR);
|
||||
WrapOperation *wrapOperation = new WrapOperation(COM_DT_COLOR);
|
||||
wrapOperation->setMemoryProxy(writeOperation->getMemoryProxy());
|
||||
wrapOperation->setWrapping(data->wrap_axis);
|
||||
|
||||
|
@@ -95,7 +95,7 @@ void *AntiAliasOperation::initializeTileData(rcti *rect)
|
||||
float *input = tile->getBuffer();
|
||||
char *valuebuffer = (char *)MEM_mallocN(sizeof(char) * size, __func__);
|
||||
for (int i = 0; i < size; i++) {
|
||||
float in = input[i * COM_NUMBER_OF_CHANNELS];
|
||||
float in = input[i];
|
||||
valuebuffer[i] = FTOCHAR(in);
|
||||
}
|
||||
antialias_tagbuf(tile->getWidth(), tile->getHeight(), valuebuffer);
|
||||
|
@@ -138,7 +138,7 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber)
|
||||
int y2 = rect->ymax;
|
||||
int offset = (y1 * this->getWidth() + x1);
|
||||
int add = (this->getWidth() - (x2 - x1));
|
||||
int offset4 = offset * COM_NUMBER_OF_CHANNELS;
|
||||
int offset4 = offset * COM_NO_CHANNELS_COLOR;
|
||||
int x;
|
||||
int y;
|
||||
bool breaked = false;
|
||||
@@ -196,14 +196,14 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber)
|
||||
|
||||
this->m_depthInput->readSampled(color, input_x, input_y, COM_PS_NEAREST);
|
||||
zbuffer[offset] = color[0];
|
||||
offset4 += COM_NUMBER_OF_CHANNELS;
|
||||
offset4 += COM_NO_CHANNELS_COLOR;
|
||||
offset++;
|
||||
if (isBreaked()) {
|
||||
breaked = true;
|
||||
}
|
||||
}
|
||||
offset += add;
|
||||
offset4 += add * COM_NUMBER_OF_CHANNELS;
|
||||
offset4 += add * COM_NO_CHANNELS_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,6 @@
|
||||
|
||||
#include "COM_ConvertOperation.h"
|
||||
|
||||
|
||||
ConvertBaseOperation::ConvertBaseOperation()
|
||||
{
|
||||
this->m_inputOperation = NULL;
|
||||
@@ -49,9 +48,9 @@ ConvertValueToColorOperation::ConvertValueToColorOperation() : ConvertBaseOperat
|
||||
|
||||
void ConvertValueToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
|
||||
{
|
||||
float inputValue[4];
|
||||
this->m_inputOperation->readSampled(inputValue, x, y, sampler);
|
||||
output[0] = output[1] = output[2] = inputValue[0];
|
||||
float value;
|
||||
this->m_inputOperation->readSampled(&value, x, y, sampler);
|
||||
output[0] = output[1] = output[2] = value;
|
||||
output[3] = 1.0f;
|
||||
}
|
||||
|
||||
@@ -98,7 +97,9 @@ ConvertColorToVectorOperation::ConvertColorToVectorOperation() : ConvertBaseOper
|
||||
|
||||
void ConvertColorToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
|
||||
{
|
||||
this->m_inputOperation->readSampled(output, x, y, sampler);
|
||||
float color[4];
|
||||
this->m_inputOperation->readSampled(color, x, y, sampler);
|
||||
copy_v3_v3(output, color);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,12 +113,9 @@ ConvertValueToVectorOperation::ConvertValueToVectorOperation() : ConvertBaseOper
|
||||
|
||||
void ConvertValueToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
|
||||
{
|
||||
float input[4];
|
||||
this->m_inputOperation->readSampled(input, x, y, sampler);
|
||||
output[0] = input[0];
|
||||
output[1] = input[0];
|
||||
output[2] = input[0];
|
||||
output[3] = 0.0f;
|
||||
float value;
|
||||
this->m_inputOperation->readSampled(&value, x, y, sampler);
|
||||
output[0] = output[1] = output[2] = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +129,7 @@ ConvertVectorToColorOperation::ConvertVectorToColorOperation() : ConvertBaseOper
|
||||
|
||||
void ConvertVectorToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
|
||||
{
|
||||
this->m_inputOperation->readSampled(output, x, y, sampler);
|
||||
this->m_inputOperation->readSampled(output, x, y, sampler);
|
||||
output[3] = 1.0f;
|
||||
}
|
||||
|
||||
|
@@ -82,18 +82,18 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y,
|
||||
const int bufferWidth = BLI_rcti_size_x(rect);
|
||||
int offset;
|
||||
|
||||
this->m_inputProgram->read(inputValue, x, y, NULL);
|
||||
if (inputValue[0] > sw) {
|
||||
inputBuffer->read(inputValue, x, y);
|
||||
if (inputValue[0] > sw) {
|
||||
for (int yi = miny; yi < maxy; yi++) {
|
||||
const float dy = yi - y;
|
||||
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4;
|
||||
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
|
||||
for (int xi = minx; xi < maxx; xi++) {
|
||||
if (buffer[offset] < sw) {
|
||||
const float dx = xi - x;
|
||||
const float dis = dx * dx + dy * dy;
|
||||
mindist = min(mindist, dis);
|
||||
}
|
||||
offset += 4;
|
||||
offset ++;
|
||||
}
|
||||
}
|
||||
pixelvalue = -sqrtf(mindist);
|
||||
@@ -101,14 +101,14 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y,
|
||||
else {
|
||||
for (int yi = miny; yi < maxy; yi++) {
|
||||
const float dy = yi - y;
|
||||
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4;
|
||||
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
|
||||
for (int xi = minx; xi < maxx; xi++) {
|
||||
if (buffer[offset] > sw) {
|
||||
const float dx = xi - x;
|
||||
const float dis = dx * dx + dy * dy;
|
||||
mindist = min(mindist, dis);
|
||||
}
|
||||
offset += 4;
|
||||
offset ++;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -193,7 +193,7 @@ void DilateDistanceOperation::executePixel(float output[4], int x, int y, void *
|
||||
const float mindist = distance * distance;
|
||||
|
||||
MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
|
||||
float *buffer = inputBuffer->getBuffer();
|
||||
float *buffer = inputBuffer->getBuffer();
|
||||
rcti *rect = inputBuffer->getRect();
|
||||
const int minx = max(x - this->m_scope, rect->xmin);
|
||||
const int miny = max(y - this->m_scope, rect->ymin);
|
||||
@@ -206,17 +206,17 @@ void DilateDistanceOperation::executePixel(float output[4], int x, int y, void *
|
||||
|
||||
for (int yi = miny; yi < maxy; yi++) {
|
||||
const float dy = yi - y;
|
||||
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4;
|
||||
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
|
||||
for (int xi = minx; xi < maxx; xi++) {
|
||||
const float dx = xi - x;
|
||||
const float dis = dx * dx + dy * dy;
|
||||
if (dis <= mindist) {
|
||||
value = max(buffer[offset], value);
|
||||
}
|
||||
offset += 4;
|
||||
offset ++;
|
||||
}
|
||||
}
|
||||
output[0] = value;
|
||||
output[0] = value;
|
||||
}
|
||||
|
||||
void DilateDistanceOperation::deinitExecution()
|
||||
@@ -280,14 +280,14 @@ void ErodeDistanceOperation::executePixel(float output[4], int x, int y, void *d
|
||||
|
||||
for (int yi = miny; yi < maxy; yi++) {
|
||||
const float dy = yi - y;
|
||||
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4;
|
||||
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
|
||||
for (int xi = minx; xi < maxx; xi++) {
|
||||
const float dx = xi - x;
|
||||
const float dis = dx * dx + dy * dy;
|
||||
if (dis <= mindist) {
|
||||
value = min(buffer[offset], value);
|
||||
}
|
||||
offset += 4;
|
||||
offset ++;
|
||||
}
|
||||
}
|
||||
output[0] = value;
|
||||
@@ -383,7 +383,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect)
|
||||
buf[x] = -MAXFLOAT;
|
||||
}
|
||||
for (x = xmin; x < xmax; ++x) {
|
||||
buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)];
|
||||
buf[x - rect->xmin + window - 1] = buffer[(y * width + x)];
|
||||
}
|
||||
|
||||
for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
|
||||
@@ -510,7 +510,7 @@ void *ErodeStepOperation::initializeTileData(rcti *rect)
|
||||
buf[x] = MAXFLOAT;
|
||||
}
|
||||
for (x = xmin; x < xmax; ++x) {
|
||||
buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)];
|
||||
buf[x - rect->xmin + window - 1] = buffer[(y * width + x)];
|
||||
}
|
||||
|
||||
for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
|
||||
|
@@ -129,16 +129,16 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
|
||||
this->m_sy = this->m_data.sizey * this->m_size / 2.0f;
|
||||
|
||||
if ((this->m_sx == this->m_sy) && (this->m_sx > 0.f)) {
|
||||
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
|
||||
for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
|
||||
IIR_gauss(copy, this->m_sx, c, 3);
|
||||
}
|
||||
else {
|
||||
if (this->m_sx > 0.0f) {
|
||||
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
|
||||
for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
|
||||
IIR_gauss(copy, this->m_sx, c, 1);
|
||||
}
|
||||
if (this->m_sy > 0.0f) {
|
||||
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
|
||||
for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
|
||||
IIR_gauss(copy, this->m_sy, c, 2);
|
||||
}
|
||||
}
|
||||
@@ -170,7 +170,7 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
|
||||
dai.ymin = max(dai.ymin, buf_rect->ymin);
|
||||
dai.ymax = min(dai.ymax, buf_rect->ymax);
|
||||
|
||||
MemoryBuffer *tile = new MemoryBuffer(NULL, &dai);
|
||||
MemoryBuffer *tile = MemoryBuffer::create(COM_DT_COLOR, &dai);
|
||||
tile->copyContentFrom(buffer);
|
||||
|
||||
int c;
|
||||
@@ -178,16 +178,16 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
|
||||
float sy = this->m_data.sizey * this->m_size / 2.0f;
|
||||
|
||||
if ((sx == sy) && (sx > 0.f)) {
|
||||
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
|
||||
for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
|
||||
IIR_gauss(tile, sx, c, 3);
|
||||
}
|
||||
else {
|
||||
if (sx > 0.0f) {
|
||||
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
|
||||
for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
|
||||
IIR_gauss(tile, sx, c, 1);
|
||||
}
|
||||
if (sy > 0.0f) {
|
||||
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
|
||||
for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
|
||||
IIR_gauss(tile, sy, c, 2);
|
||||
}
|
||||
}
|
||||
@@ -217,6 +217,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign
|
||||
unsigned int x, y, sz;
|
||||
unsigned int i;
|
||||
float *buffer = src->getBuffer();
|
||||
const unsigned int no_channels = src->get_no_channels();
|
||||
|
||||
// <0.5 not valid, though can have a possibly useful sort of sharpening effect
|
||||
if (sigma < 0.5f) return;
|
||||
@@ -295,31 +296,31 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign
|
||||
int offset;
|
||||
for (y = 0; y < src_height; ++y) {
|
||||
const int yx = y * src_width;
|
||||
offset = yx * COM_NUMBER_OF_CHANNELS + chan;
|
||||
offset = yx * no_channels + chan;
|
||||
for (x = 0; x < src_width; ++x) {
|
||||
X[x] = buffer[offset];
|
||||
offset += COM_NUMBER_OF_CHANNELS;
|
||||
offset += no_channels;
|
||||
}
|
||||
YVV(src_width);
|
||||
offset = yx * COM_NUMBER_OF_CHANNELS + chan;
|
||||
offset = yx * no_channels + chan;
|
||||
for (x = 0; x < src_width; ++x) {
|
||||
buffer[offset] = Y[x];
|
||||
offset += COM_NUMBER_OF_CHANNELS;
|
||||
offset += no_channels;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xy & 2) { // V
|
||||
int offset;
|
||||
const int add = src_width * COM_NUMBER_OF_CHANNELS;
|
||||
const int add = src_width * no_channels;
|
||||
|
||||
for (x = 0; x < src_width; ++x) {
|
||||
offset = x * COM_NUMBER_OF_CHANNELS + chan;
|
||||
offset = x * no_channels + chan;
|
||||
for (y = 0; y < src_height; ++y) {
|
||||
X[y] = buffer[offset];
|
||||
offset += add;
|
||||
}
|
||||
YVV(src_height);
|
||||
offset = x * COM_NUMBER_OF_CHANNELS + chan;
|
||||
offset = x * no_channels + chan;
|
||||
for (y = 0; y < src_height; ++y) {
|
||||
buffer[offset] = Y[y];
|
||||
offset += add;
|
||||
@@ -395,7 +396,7 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
|
||||
if (this->m_overlay == FAST_GAUSS_OVERLAY_MIN) {
|
||||
float *src = newBuf->getBuffer();
|
||||
float *dst = copy->getBuffer();
|
||||
for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUMBER_OF_CHANNELS, dst += COM_NUMBER_OF_CHANNELS) {
|
||||
for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NO_CHANNELS_VALUE, dst += COM_NO_CHANNELS_VALUE) {
|
||||
if (*src < *dst) {
|
||||
*dst = *src;
|
||||
}
|
||||
@@ -404,15 +405,13 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
|
||||
else if (this->m_overlay == FAST_GAUSS_OVERLAY_MAX) {
|
||||
float *src = newBuf->getBuffer();
|
||||
float *dst = copy->getBuffer();
|
||||
for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUMBER_OF_CHANNELS, dst += COM_NUMBER_OF_CHANNELS) {
|
||||
for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NO_CHANNELS_VALUE, dst += COM_NO_CHANNELS_VALUE) {
|
||||
if (*src > *dst) {
|
||||
*dst = *src;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// newBuf->
|
||||
|
||||
this->m_iirgaus = copy;
|
||||
}
|
||||
unlockMutex();
|
||||
|
@@ -102,15 +102,14 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo
|
||||
|
||||
/* *** this is the main part which is different to 'GaussianXBlurOperation' *** */
|
||||
int step = getStep();
|
||||
int offsetadd = getOffsetAdd();
|
||||
int bufferindex = ((xmin - bufferstartx) * 4) + ((ymin - bufferstarty) * 4 * bufferwidth);
|
||||
int bufferindex = ((xmin - bufferstartx)) + ((ymin - bufferstarty) * bufferwidth);
|
||||
|
||||
/* gauss */
|
||||
float alpha_accum = 0.0f;
|
||||
float multiplier_accum = 0.0f;
|
||||
|
||||
/* dilate */
|
||||
float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
|
||||
float value_max = finv_test(buffer[(x) + (y * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
|
||||
float distfacinv_max = 1.0f; /* 0 to 1 */
|
||||
|
||||
for (int nx = xmin; nx < xmax; nx += step) {
|
||||
@@ -134,7 +133,7 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo
|
||||
distfacinv_max = multiplier;
|
||||
}
|
||||
}
|
||||
bufferindex += offsetadd;
|
||||
bufferindex += step;
|
||||
}
|
||||
|
||||
/* blend between the max value and gauss blue - gives nice feather */
|
||||
|
@@ -108,11 +108,11 @@ void GaussianAlphaYBlurOperation::executePixel(float output[4], int x, int y, vo
|
||||
float multiplier_accum = 0.0f;
|
||||
|
||||
/* dilate */
|
||||
float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
|
||||
float value_max = finv_test(buffer[(x) + (y * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
|
||||
float distfacinv_max = 1.0f; /* 0 to 1 */
|
||||
|
||||
for (int ny = ymin; ny < ymax; ny += step) {
|
||||
int bufferindex = ((xmin - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
|
||||
int bufferindex = ((xmin - bufferstartx)) + ((ny - bufferstarty) * bufferwidth);
|
||||
|
||||
const int index = (ny - y) + this->m_filtersize;
|
||||
float value = finv_test(buffer[bufferindex], do_invert);
|
||||
|
@@ -293,7 +293,7 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
|
||||
int minyr = y - refrady < 0 ? -y : -refrady;
|
||||
int maxyr = y + refrady > imgy ? imgy - y : refrady;
|
||||
|
||||
float *srcd = buffer + COM_NUMBER_OF_CHANNELS * ( (y + minyr) * imgx + x + minxr);
|
||||
float *srcd = buffer + COM_NO_CHANNELS_COLOR * ( (y + minyr) * imgx + x + minxr);
|
||||
|
||||
gausstabx = m_maintabs[refradx - 1];
|
||||
gausstabcentx = gausstabx + refradx;
|
||||
@@ -301,9 +301,9 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
|
||||
gausstabcenty = gausstaby + refrady;
|
||||
|
||||
sum = gval = rval = bval = aval = 0.0f;
|
||||
for (i = minyr; i < maxyr; i++, srcd += COM_NUMBER_OF_CHANNELS * imgx) {
|
||||
for (i = minyr; i < maxyr; i++, srcd += COM_NO_CHANNELS_COLOR * imgx) {
|
||||
src = srcd;
|
||||
for (j = minxr; j < maxxr; j++, src += COM_NUMBER_OF_CHANNELS) {
|
||||
for (j = minxr; j < maxxr; j++, src += COM_NO_CHANNELS_COLOR) {
|
||||
|
||||
val = gausstabcenty[i] * gausstabcentx[j];
|
||||
sum += val;
|
||||
|
@@ -49,7 +49,7 @@ MemoryBuffer *GlareBaseOperation::createMemoryBuffer(rcti *rect2)
|
||||
rect.ymin = 0;
|
||||
rect.xmax = getWidth();
|
||||
rect.ymax = getHeight();
|
||||
MemoryBuffer *result = new MemoryBuffer(NULL, &rect);
|
||||
MemoryBuffer *result = MemoryBuffer::create(COM_DT_COLOR, &rect);
|
||||
float *data = result->getBuffer();
|
||||
this->generateGlare(data, tile, this->m_settings);
|
||||
return result;
|
||||
|
@@ -259,8 +259,8 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
|
||||
float *kernelBuffer = in2->getBuffer();
|
||||
float *imageBuffer = in1->getBuffer();
|
||||
|
||||
MemoryBuffer *rdst = new MemoryBuffer(NULL, in1->getRect());
|
||||
memset(rdst->getBuffer(), 0, rdst->getWidth() * rdst->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
|
||||
MemoryBuffer *rdst = MemoryBuffer::create(COM_DT_COLOR, in1->getRect());
|
||||
memset(rdst->getBuffer(), 0, rdst->getWidth() * rdst->getHeight() * COM_NO_CHANNELS_COLOR * sizeof(float));
|
||||
|
||||
// convolution result width & height
|
||||
w2 = 2 * kernelWidth - 1;
|
||||
@@ -276,7 +276,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
|
||||
// normalize convolutor
|
||||
wt[0] = wt[1] = wt[2] = 0.f;
|
||||
for (y = 0; y < kernelHeight; y++) {
|
||||
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS];
|
||||
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NO_CHANNELS_COLOR];
|
||||
for (x = 0; x < kernelWidth; x++)
|
||||
add_v3_v3(wt, colp[x]);
|
||||
}
|
||||
@@ -284,7 +284,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
|
||||
if (wt[1] != 0.f) wt[1] = 1.f / wt[1];
|
||||
if (wt[2] != 0.f) wt[2] = 1.f / wt[2];
|
||||
for (y = 0; y < kernelHeight; y++) {
|
||||
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS];
|
||||
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NO_CHANNELS_COLOR];
|
||||
for (x = 0; x < kernelWidth; x++)
|
||||
mul_v3_v3(colp[x], wt);
|
||||
}
|
||||
@@ -313,7 +313,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
|
||||
// in2, channel ch -> data1
|
||||
for (y = 0; y < kernelHeight; y++) {
|
||||
fp = &data1ch[y * w2];
|
||||
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS];
|
||||
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NO_CHANNELS_COLOR];
|
||||
for (x = 0; x < kernelWidth; x++)
|
||||
fp[x] = colp[x][ch];
|
||||
}
|
||||
@@ -325,7 +325,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
|
||||
int yy = ybl * ybsz + y;
|
||||
if (yy >= imageHeight) continue;
|
||||
fp = &data2[y * w2];
|
||||
colp = (fRGB *)&imageBuffer[yy * imageWidth * COM_NUMBER_OF_CHANNELS];
|
||||
colp = (fRGB *)&imageBuffer[yy * imageWidth * COM_NO_CHANNELS_COLOR];
|
||||
for (x = 0; x < xbsz; x++) {
|
||||
int xx = xbl * xbsz + x;
|
||||
if (xx >= imageWidth) continue;
|
||||
@@ -349,7 +349,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
|
||||
const int yy = ybl * ybsz + y - hh;
|
||||
if ((yy < 0) || (yy >= imageHeight)) continue;
|
||||
fp = &data2[y * w2];
|
||||
colp = (fRGB *)&rdst->getBuffer()[yy * imageWidth * COM_NUMBER_OF_CHANNELS];
|
||||
colp = (fRGB *)&rdst->getBuffer()[yy * imageWidth * COM_NO_CHANNELS_COLOR];
|
||||
for (x = 0; x < (int)w2; x++) {
|
||||
const int xx = xbl * xbsz + x - hw;
|
||||
if ((xx < 0) || (xx >= imageWidth)) continue;
|
||||
@@ -364,7 +364,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
|
||||
|
||||
MEM_freeN(data2);
|
||||
MEM_freeN(data1);
|
||||
memcpy(dst, rdst->getBuffer(), sizeof(float) * imageWidth * imageHeight * COM_NUMBER_OF_CHANNELS);
|
||||
memcpy(dst, rdst->getBuffer(), sizeof(float) * imageWidth * imageHeight * COM_NO_CHANNELS_COLOR);
|
||||
delete(rdst);
|
||||
}
|
||||
|
||||
@@ -381,7 +381,7 @@ void GlareFogGlowOperation::generateGlare(float *data, MemoryBuffer *inputTile,
|
||||
// make the convolution kernel
|
||||
rcti kernelRect;
|
||||
BLI_rcti_init(&kernelRect, 0, sz, 0, sz);
|
||||
ckrn = new MemoryBuffer(NULL, &kernelRect);
|
||||
ckrn = MemoryBuffer::create(COM_DT_COLOR, &kernelRect);
|
||||
|
||||
scale = 0.25f * sqrtf((float)(sz * sz));
|
||||
|
||||
|
@@ -97,7 +97,7 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No
|
||||
|
||||
}
|
||||
|
||||
memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
|
||||
memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NO_CHANNELS_COLOR * sizeof(float));
|
||||
for (n = 1; n < settings->iter && (!breaked); n++) {
|
||||
for (y = 0; y < gbuf->getHeight() && (!breaked); y++) {
|
||||
v = ((float)y + 0.5f) / (float)gbuf->getHeight();
|
||||
@@ -117,9 +117,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No
|
||||
}
|
||||
if (isBreaked()) breaked = true;
|
||||
}
|
||||
memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
|
||||
memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth() * tbuf1->getHeight() * COM_NO_CHANNELS_COLOR * sizeof(float));
|
||||
}
|
||||
memcpy(data, gbuf->getBuffer(), gbuf->getWidth() * gbuf->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
|
||||
memcpy(data, gbuf->getBuffer(), gbuf->getWidth() * gbuf->getHeight() * COM_NO_CHANNELS_COLOR * sizeof(float));
|
||||
|
||||
delete gbuf;
|
||||
delete tbuf1;
|
||||
|
@@ -36,7 +36,7 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile,
|
||||
bool breaked = false;
|
||||
|
||||
MemoryBuffer *tsrc = inputTile->duplicate();
|
||||
MemoryBuffer *tdst = new MemoryBuffer(NULL, inputTile->getRect());
|
||||
MemoryBuffer *tdst = MemoryBuffer::create(COM_DT_COLOR, inputTile->getRect());
|
||||
tdst->clear();
|
||||
memset(data, 0, size4 * sizeof(float));
|
||||
|
||||
|
@@ -83,8 +83,8 @@ float *InpaintSimpleOperation::get_pixel(int x, int y)
|
||||
ASSERT_XY_RANGE(x, y);
|
||||
|
||||
return &this->m_cached_buffer[
|
||||
y * width * COM_NUMBER_OF_CHANNELS +
|
||||
x * COM_NUMBER_OF_CHANNELS];
|
||||
y * width * COM_NO_CHANNELS_COLOR +
|
||||
x * COM_NO_CHANNELS_COLOR];
|
||||
}
|
||||
|
||||
int InpaintSimpleOperation::mdist(int x, int y)
|
||||
|
@@ -63,7 +63,7 @@ void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data
|
||||
int cx = x + i;
|
||||
|
||||
if (cx >= 0 && cx < bufferWidth) {
|
||||
int bufferIndex = (y * bufferWidth + cx) * 4;
|
||||
int bufferIndex = (y * bufferWidth + cx);
|
||||
|
||||
average += buffer[bufferIndex];
|
||||
count++;
|
||||
@@ -75,7 +75,7 @@ void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data
|
||||
int cy = y + i;
|
||||
|
||||
if (cy >= 0 && cy < bufferHeight) {
|
||||
int bufferIndex = (cy * bufferWidth + x) * 4;
|
||||
int bufferIndex = (cy * bufferWidth + x);
|
||||
|
||||
average += buffer[bufferIndex];
|
||||
count++;
|
||||
|
@@ -64,7 +64,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data
|
||||
|
||||
int i, j, count = 0, totalCount = 0;
|
||||
|
||||
float value = buffer[(y * bufferWidth + x) * 4];
|
||||
float value = buffer[(y * bufferWidth + x)];
|
||||
|
||||
bool ok = false;
|
||||
|
||||
@@ -76,7 +76,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data
|
||||
continue;
|
||||
|
||||
if (cx >= 0 && cx < bufferWidth && cy >= 0 && cy < bufferHeight) {
|
||||
int bufferIndex = (cy * bufferWidth + cx) * 4;
|
||||
int bufferIndex = (cy * bufferWidth + cx);
|
||||
float currentValue = buffer[bufferIndex];
|
||||
|
||||
if (fabsf(currentValue - value) < tolerance) {
|
||||
|
@@ -77,17 +77,17 @@ bool MapUVOperation::read_uv(float x, float y, float &r_u, float &r_v, float &r_
|
||||
float width = m_inputUVProgram->getWidth();
|
||||
float height = m_inputUVProgram->getHeight();
|
||||
if (x < 0.0f || x >= width || y < 0.0f || y >= height) {
|
||||
r_u = 0.0f;
|
||||
r_u = 0.0f;
|
||||
r_v = 0.0f;
|
||||
r_alpha = 0.0f;
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
float col[4];
|
||||
m_inputUVProgram->readSampled(col, x, y, COM_PS_BILINEAR);
|
||||
r_u = col[0] * m_inputColorProgram->getWidth();
|
||||
r_v = col[1] * m_inputColorProgram->getHeight();
|
||||
r_alpha = col[2];
|
||||
float vector[3];
|
||||
m_inputUVProgram->readSampled(vector, x, y, COM_PS_BILINEAR);
|
||||
r_u = vector[0] * m_inputColorProgram->getWidth();
|
||||
r_v = vector[1] * m_inputColorProgram->getHeight();
|
||||
r_alpha = vector[2];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -104,7 +104,7 @@ void *NormalizeOperation::initializeTileData(rcti *rect)
|
||||
if ((value < minv) && (value >= -BLENDER_ZMAX)) {
|
||||
minv = value;
|
||||
}
|
||||
bc += 4;
|
||||
bc += COM_NO_CHANNELS_VALUE;
|
||||
}
|
||||
|
||||
minmult->x = minv;
|
||||
|
@@ -26,7 +26,7 @@ QualityStepHelper::QualityStepHelper()
|
||||
{
|
||||
this->m_quality = COM_QUALITY_HIGH;
|
||||
this->m_step = 1;
|
||||
this->m_offsetadd = 4;
|
||||
this->m_offsetadd = 4;
|
||||
}
|
||||
|
||||
void QualityStepHelper::initExecution(QualityHelper helper)
|
||||
@@ -37,16 +37,16 @@ void QualityStepHelper::initExecution(QualityHelper helper)
|
||||
case COM_QUALITY_HIGH:
|
||||
default:
|
||||
this->m_step = 1;
|
||||
this->m_offsetadd = 4;
|
||||
break;
|
||||
this->m_offsetadd = 1;
|
||||
break;
|
||||
case COM_QUALITY_MEDIUM:
|
||||
this->m_step = 2;
|
||||
this->m_offsetadd = 8;
|
||||
break;
|
||||
this->m_offsetadd = 2;
|
||||
break;
|
||||
case COM_QUALITY_LOW:
|
||||
this->m_step = 3;
|
||||
this->m_offsetadd = 12;
|
||||
break;
|
||||
this->m_offsetadd = 3;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case COM_QH_MULTIPLY:
|
||||
@@ -54,16 +54,16 @@ void QualityStepHelper::initExecution(QualityHelper helper)
|
||||
case COM_QUALITY_HIGH:
|
||||
default:
|
||||
this->m_step = 1;
|
||||
this->m_offsetadd = 4;
|
||||
break;
|
||||
this->m_offsetadd = 4;
|
||||
break;
|
||||
case COM_QUALITY_MEDIUM:
|
||||
this->m_step = 2;
|
||||
this->m_offsetadd = 8;
|
||||
break;
|
||||
this->m_offsetadd = 8;
|
||||
break;
|
||||
case COM_QUALITY_LOW:
|
||||
this->m_step = 4;
|
||||
this->m_offsetadd = 16;
|
||||
break;
|
||||
this->m_offsetadd = 16;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@@ -24,9 +24,9 @@
|
||||
#include "COM_WriteBufferOperation.h"
|
||||
#include "COM_defines.h"
|
||||
|
||||
ReadBufferOperation::ReadBufferOperation() : NodeOperation()
|
||||
ReadBufferOperation::ReadBufferOperation(DataType type) : NodeOperation()
|
||||
{
|
||||
this->addOutputSocket(COM_DT_COLOR);
|
||||
this->addOutputSocket(type);
|
||||
this->m_single_value = false;
|
||||
this->m_offset = 0;
|
||||
this->m_buffer = NULL;
|
||||
|
@@ -33,7 +33,7 @@ private:
|
||||
unsigned int m_offset;
|
||||
MemoryBuffer *m_buffer;
|
||||
public:
|
||||
ReadBufferOperation();
|
||||
ReadBufferOperation(DataType type);
|
||||
void setMemoryProxy(MemoryProxy *memoryProxy) { this->m_memoryProxy = memoryProxy; }
|
||||
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
|
||||
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
|
||||
|
@@ -89,7 +89,6 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi
|
||||
else
|
||||
zero_v4(output);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
offset = (iy * width + ix) * this->m_elementsize;
|
||||
@@ -111,15 +110,6 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi
|
||||
BLI_bicubic_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
|
||||
break;
|
||||
}
|
||||
|
||||
if (this->m_elementsize == 1) {
|
||||
output[1] = 0.0f;
|
||||
output[2] = 0.0f;
|
||||
output[3] = 0.0f;
|
||||
}
|
||||
else if (this->m_elementsize == 3) {
|
||||
output[3] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
|
||||
@@ -148,7 +138,15 @@ void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y
|
||||
#endif
|
||||
|
||||
if (this->m_inputBuffer == NULL) {
|
||||
zero_v4(output);
|
||||
int elemsize = this->m_elementsize;
|
||||
if (elemsize == 1) {
|
||||
output[0] = 0.0f;
|
||||
}
|
||||
else if (elemsize == 3) {
|
||||
zero_v3(output);
|
||||
} else {
|
||||
zero_v4(output);
|
||||
}
|
||||
}
|
||||
else {
|
||||
doInterpolation(output, ix, iy, sampler);
|
||||
@@ -210,16 +208,10 @@ void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float
|
||||
|
||||
if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) {
|
||||
output[0] = 0.0f;
|
||||
output[1] = 0.0f;
|
||||
output[2] = 0.0f;
|
||||
output[3] = 0.0f;
|
||||
}
|
||||
else {
|
||||
unsigned int offset = (iy * this->getWidth() + ix) * 4;
|
||||
output[0] = inputBuffer[offset + 3];
|
||||
output[1] = 0.0f;
|
||||
output[2] = 0.0f;
|
||||
output[3] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,16 +244,10 @@ void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float
|
||||
|
||||
if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) {
|
||||
output[0] = 0.0f;
|
||||
output[1] = 0.0f;
|
||||
output[2] = 0.0f;
|
||||
output[3] = 0.0f;
|
||||
}
|
||||
else {
|
||||
unsigned int offset = (iy * this->getWidth() + ix);
|
||||
output[0] = inputBuffer[offset];
|
||||
output[1] = 0.0f;
|
||||
output[2] = 0.0f;
|
||||
output[3] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -33,7 +33,7 @@ void SetVectorOperation::executePixelSampled(float output[4], float x, float y,
|
||||
output[0] = this->m_x;
|
||||
output[1] = this->m_y;
|
||||
output[2] = this->m_z;
|
||||
output[3] = this->m_w;
|
||||
// output[3] = this->m_w; not supported anymore?
|
||||
}
|
||||
|
||||
void SetVectorOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
|
||||
|
@@ -77,11 +77,9 @@ void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsig
|
||||
|
||||
void TextureAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
|
||||
{
|
||||
TextureBaseOperation::executePixelSampled(output, x, y, sampler);
|
||||
output[0] = output[3];
|
||||
output[1] = 0.0f;
|
||||
output[2] = 0.0f;
|
||||
output[3] = 0.0f;
|
||||
float color[4];
|
||||
TextureBaseOperation::executePixelSampled(color, x, y, sampler);
|
||||
output[0] = color[3];
|
||||
}
|
||||
|
||||
void TextureBaseOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
|
||||
@@ -124,18 +122,23 @@ MemoryBuffer *TextureBaseOperation::createMemoryBuffer(rcti *rect2)
|
||||
{
|
||||
int height = getHeight();
|
||||
int width = getWidth();
|
||||
DataType datatype = this->getOutputSocket()->getDataType();
|
||||
int add = 4;
|
||||
if (datatype == COM_DT_VALUE) {
|
||||
add = 1;
|
||||
}
|
||||
|
||||
rcti rect;
|
||||
rect.xmin = 0;
|
||||
rect.ymin = 0;
|
||||
rect.xmax = width;
|
||||
rect.ymax = height;
|
||||
MemoryBuffer *result = new MemoryBuffer(NULL, &rect);
|
||||
MemoryBuffer *result = MemoryBuffer::create(datatype, &rect);
|
||||
|
||||
float *data = result->getBuffer();
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++, data += 4) {
|
||||
for (int x = 0; x < width; x++, data += add) {
|
||||
this->executePixelSampled(data, x, y, COM_PS_NEAREST);
|
||||
}
|
||||
}
|
||||
|
@@ -137,16 +137,19 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
|
||||
copy_v4_fl(multiplier_accum, 1.0f);
|
||||
float size_center = tempSize[0] * scalar;
|
||||
|
||||
const int addXStep = QualityStepHelper::getStep() * COM_NUMBER_OF_CHANNELS;
|
||||
|
||||
const int addXStepValue = QualityStepHelper::getStep();
|
||||
const int addYStepValue = addXStepValue;
|
||||
const int addXStepColor = addXStepValue * COM_NO_CHANNELS_COLOR;
|
||||
|
||||
if (size_center > this->m_threshold) {
|
||||
for (int ny = miny; ny < maxy; ny += QualityStepHelper::getStep()) {
|
||||
for (int ny = miny; ny < maxy; ny += addYStepValue) {
|
||||
float dy = ny - y;
|
||||
int offsetNy = ny * inputSizeBuffer->getWidth() * COM_NUMBER_OF_CHANNELS;
|
||||
int offsetNxNy = offsetNy + (minx * COM_NUMBER_OF_CHANNELS);
|
||||
for (int nx = minx; nx < maxx; nx += QualityStepHelper::getStep()) {
|
||||
int offsetValueNy = ny * inputSizeBuffer->getWidth();
|
||||
int offsetValueNxNy = offsetValueNy + (minx);
|
||||
int offsetColorNxNy = offsetValueNxNy * COM_NO_CHANNELS_COLOR;
|
||||
for (int nx = minx; nx < maxx; nx += addXStepValue) {
|
||||
if (nx != x || ny != y) {
|
||||
float size = min(inputSizeFloatBuffer[offsetNxNy] * scalar, size_center);
|
||||
float size = min(inputSizeFloatBuffer[offsetValueNxNy] * scalar, size_center);
|
||||
if (size > this->m_threshold) {
|
||||
float dx = nx - x;
|
||||
if (size > fabsf(dx) && size > fabsf(dy)) {
|
||||
@@ -154,13 +157,14 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
|
||||
(float)(COM_BLUR_BOKEH_PIXELS / 2) + (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1),
|
||||
(float)(COM_BLUR_BOKEH_PIXELS / 2) + (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1)};
|
||||
inputBokehBuffer->readNoCheck(bokeh, uv[0], uv[1]);
|
||||
madd_v4_v4v4(color_accum, bokeh, &inputProgramFloatBuffer[offsetNxNy]);
|
||||
madd_v4_v4v4(color_accum, bokeh, &inputProgramFloatBuffer[offsetColorNxNy]);
|
||||
add_v4_v4(multiplier_accum, bokeh);
|
||||
}
|
||||
}
|
||||
}
|
||||
offsetNxNy += addXStep;
|
||||
}
|
||||
offsetColorNxNy += addXStepColor;
|
||||
offsetValueNxNy += addXStepValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,7 +290,7 @@ void InverseSearchRadiusOperation::initExecution()
|
||||
|
||||
voi *InverseSearchRadiusOperation::initializeTileData(rcti *rect)
|
||||
{
|
||||
MemoryBuffer * data = new MemoryBuffer(NULL, rect);
|
||||
MemoryBuffer * data = MemoryBuffer::(NULL, rect);
|
||||
float *buffer = data->getBuffer();
|
||||
int x, y;
|
||||
int width = this->m_inputRadius->getWidth();
|
||||
|
@@ -57,7 +57,7 @@ void VectorBlurOperation::initExecution()
|
||||
void VectorBlurOperation::executePixel(float output[4], int x, int y, void *data)
|
||||
{
|
||||
float *buffer = (float *) data;
|
||||
int index = (y * this->getWidth() + x) * COM_NUMBER_OF_CHANNELS;
|
||||
int index = (y * this->getWidth() + x) * COM_NO_CHANNELS_COLOR;
|
||||
copy_v4_v4(output, &buffer[index]);
|
||||
}
|
||||
|
||||
@@ -108,14 +108,12 @@ bool VectorBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuff
|
||||
|
||||
void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputImage, MemoryBuffer *inputSpeed, MemoryBuffer *inputZ)
|
||||
{
|
||||
float *zbuf = inputZ->convertToValueBuffer();
|
||||
NodeBlurData blurdata;
|
||||
blurdata.samples = this->m_settings->samples / QualityStepHelper::getStep();
|
||||
blurdata.maxspeed = this->m_settings->maxspeed;
|
||||
blurdata.minspeed = this->m_settings->minspeed;
|
||||
blurdata.curved = this->m_settings->curved;
|
||||
blurdata.fac = this->m_settings->fac;
|
||||
RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), zbuf);
|
||||
MEM_freeN((void *)zbuf);
|
||||
RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), inputZ->getBuffer());
|
||||
return;
|
||||
}
|
||||
|
@@ -51,7 +51,6 @@ void VectorCurveOperation::executePixelSampled(float output[4], float x, float y
|
||||
this->m_inputProgram->readSampled(input, x, y, sampler);
|
||||
|
||||
curvemapping_evaluate_premulRGBF(this->m_curveMapping, output, input);
|
||||
output[3] = input[3];
|
||||
}
|
||||
|
||||
void VectorCurveOperation::deinitExecution()
|
||||
|
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "COM_WrapOperation.h"
|
||||
|
||||
WrapOperation::WrapOperation() : ReadBufferOperation()
|
||||
WrapOperation::WrapOperation(DataType type) : ReadBufferOperation(type)
|
||||
{
|
||||
this->m_wrappingType = CMP_NODE_WRAP_NONE;
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ class WrapOperation : public ReadBufferOperation {
|
||||
private:
|
||||
int m_wrappingType;
|
||||
public:
|
||||
WrapOperation();
|
||||
WrapOperation(DataType type);
|
||||
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
|
||||
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
|
||||
|
||||
|
@@ -25,10 +25,10 @@
|
||||
#include <stdio.h>
|
||||
#include "COM_OpenCLDevice.h"
|
||||
|
||||
WriteBufferOperation::WriteBufferOperation() : NodeOperation()
|
||||
WriteBufferOperation::WriteBufferOperation(DataType type) : NodeOperation()
|
||||
{
|
||||
this->addInputSocket(COM_DT_COLOR);
|
||||
this->m_memoryProxy = new MemoryProxy();
|
||||
this->addInputSocket(type);
|
||||
this->m_memoryProxy = new MemoryProxy(type);
|
||||
this->m_memoryProxy->setWriteBufferOperation(this);
|
||||
this->m_memoryProxy->setExecutor(NULL);
|
||||
}
|
||||
@@ -61,6 +61,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
|
||||
{
|
||||
MemoryBuffer *memoryBuffer = this->m_memoryProxy->getBuffer();
|
||||
float *buffer = memoryBuffer->getBuffer();
|
||||
const int no_channels = memoryBuffer->get_no_channels();
|
||||
if (this->m_input->isComplex()) {
|
||||
void *data = this->m_input->initializeTileData(rect);
|
||||
int x1 = rect->xmin;
|
||||
@@ -71,10 +72,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
|
||||
int y;
|
||||
bool breaked = false;
|
||||
for (y = y1; y < y2 && (!breaked); y++) {
|
||||
int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS;
|
||||
int offset4 = (y * memoryBuffer->getWidth() + x1) * no_channels;
|
||||
for (x = x1; x < x2; x++) {
|
||||
this->m_input->read(&(buffer[offset4]), x, y, data);
|
||||
offset4 += COM_NUMBER_OF_CHANNELS;
|
||||
offset4 += no_channels;
|
||||
}
|
||||
if (isBreaked()) {
|
||||
breaked = true;
|
||||
@@ -96,10 +97,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
|
||||
int y;
|
||||
bool breaked = false;
|
||||
for (y = y1; y < y2 && (!breaked); y++) {
|
||||
int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS;
|
||||
int offset4 = (y * memoryBuffer->getWidth() + x1) * no_channels;
|
||||
for (x = x1; x < x2; x++) {
|
||||
this->m_input->readSampled(&(buffer[offset4]), x, y, COM_PS_NEAREST);
|
||||
offset4 += COM_NUMBER_OF_CHANNELS;
|
||||
offset4 += no_channels;
|
||||
}
|
||||
if (isBreaked()) {
|
||||
breaked = true;
|
||||
@@ -126,12 +127,9 @@ void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect,
|
||||
const unsigned int outputBufferWidth = outputBuffer->getWidth();
|
||||
const unsigned int outputBufferHeight = outputBuffer->getHeight();
|
||||
|
||||
const cl_image_format imageFormat = {
|
||||
CL_RGBA,
|
||||
CL_FLOAT
|
||||
};
|
||||
const cl_image_format *imageFormat = device->determineImageFormat(outputBuffer);
|
||||
|
||||
cl_mem clOutputBuffer = clCreateImage2D(device->getContext(), CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, &imageFormat, outputBufferWidth, outputBufferHeight, 0, outputFloatBuffer, &error);
|
||||
cl_mem clOutputBuffer = clCreateImage2D(device->getContext(), CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, imageFormat, outputBufferWidth, outputBufferHeight, 0, outputFloatBuffer, &error);
|
||||
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
|
||||
|
||||
// STEP 2
|
||||
|
@@ -35,7 +35,7 @@ class WriteBufferOperation : public NodeOperation {
|
||||
bool m_single_value; /* single value stored in buffer */
|
||||
NodeOperation *m_input;
|
||||
public:
|
||||
WriteBufferOperation();
|
||||
WriteBufferOperation(DataType type);
|
||||
~WriteBufferOperation();
|
||||
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
|
||||
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
|
||||
|
Reference in New Issue
Block a user