From f3db38de56a123cf27fa8f7accb46b22027e6a82 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 21 Mar 2013 15:26:41 +0000 Subject: Render border + crop will be handled correct in compositor now This commit simply implements mapping from centered cropped canvas to a full-frame coordinates, so operations like alpha-overing render result on top of image will be properly aligned. --- .../compositor/intern/COM_ExecutionSystem.cpp | 6 +-- .../compositor/nodes/COM_RenderLayersNode.cpp | 1 + .../operations/COM_CompositorOperation.cpp | 46 ++++++++++++++++++++-- .../operations/COM_RenderLayersBaseProg.cpp | 24 +++++++++-- .../operations/COM_RenderLayersBaseProg.h | 8 +++- 5 files changed, 73 insertions(+), 12 deletions(-) (limited to 'source') diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 76381261576..450d1b03917 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -96,10 +96,8 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re executionGroup->determineResolution(resolution); if (rendering) { - /* TODO: would be nice to support cropping as well, but for now - * don't use border for compo when crop is enabled, - * otherwise area of interest will be a way off from rendered - * stuff + /* case when cropping to render border happens is handled in + * compositor output and render layer nodes */ if ((rd->mode & R_BORDER) && !(rd->mode & R_CROP)) { executionGroup->setRenderBorder(rd->border.xmin, rd->border.xmax, diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp index b57e99754d6..daad3bf4be0 100644 --- a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp +++ b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp @@ -61,6 +61,7 @@ void RenderLayersNode::testSocketConnection(ExecutionSystem *system, CompositorC if (outputSocket->isConnected()) { operation->setScene(scene); operation->setLayerId(layerId); + operation->setRenderData(context->getRenderData()); outputSocket->relinkConnections(operation->getOutputSocket()); system->addOperation(operation); if (outputSocketNumber == 0) { // only do for image socket if connected diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index 81e86efed42..56527da47bc 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -143,23 +143,63 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber) int x; int y; bool breaked = false; + int dx = 0, dy = 0; + + const RenderData *rd = this->m_rd; + + if (rd->mode & R_BORDER && rd->mode & R_CROP) { + /*! + When using cropped render result, need to re-position area of interest, + so it'll natch bounds of render border within frame. By default, canvas + will be centered between full frame and cropped frame, so we use such + scheme to map cropped coordinates to full-frame coordinates + + ^ Y + | Width + +------------------------------------------------+ + | | + | | + | Centered canvas, we map coordinate from it | + | +------------------+ | + | | | | H + | | | | e + | +------------------+ . Center | | i + | | | | | | g + | | | | | | h + | |....dx.... +------|-----------+ | t + | | . dy | | + | +------------------+ | + | Render border, we map coordinates to it | + | | X + +------------------------------------------------+----> + Full frame + */ + + int full_width = rd->xsch * rd->size / 100; + int full_height =rd->ysch * rd->size / 100; + + dx = rd->border.xmin * full_width - (full_width - this->getWidth()) / 2.0f; + dy = rd->border.ymin * full_height - (full_height - this->getHeight()) / 2.0f; + } for (y = y1; y < y2 && (!breaked); y++) { for (x = x1; x < x2 && (!breaked); x++) { - this->m_imageInput->read(color, x, y, COM_PS_NEAREST); + int input_x = x + dx, input_y = y + dy; + + this->m_imageInput->read(color, input_x, input_y, COM_PS_NEAREST); if (this->m_ignoreAlpha) { color[3] = 1.0f; } else { if (this->m_alphaInput != NULL) { - this->m_alphaInput->read(&(color[3]), x, y, COM_PS_NEAREST); + this->m_alphaInput->read(&(color[3]), input_x, input_y, COM_PS_NEAREST); } } copy_v4_v4(buffer + offset4, color); if (this->m_depthInput != NULL) { - this->m_depthInput->read(color, x, y, COM_PS_NEAREST); + this->m_depthInput->read(color, input_x, input_y, COM_PS_NEAREST); zbuffer[offset] = color[0]; } offset4 += COM_NUMBER_OF_CHANNELS; diff --git a/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp index 2ca499683d3..ad642795240 100644 --- a/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp @@ -37,6 +37,7 @@ RenderLayersBaseProg::RenderLayersBaseProg(int renderpass, int elementsize) : No this->setScene(NULL); this->m_inputBuffer = NULL; this->m_elementsize = elementsize; + this->m_rd = NULL; } @@ -111,14 +112,29 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi void RenderLayersBaseProg::executePixel(float output[4], float x, float y, PixelSampler sampler) { - int ix = x; - int iy = y; - + const RenderData *rd = this->m_rd; + + int dx = 0, dy = 0; + + if (rd->mode & R_BORDER && rd->mode & R_CROP) { + /* see comment in executeRegion describing coordinate mapping, + * here it simply goes other way around + */ + int full_width = rd->xsch * rd->size / 100; + int full_height =rd->ysch * rd->size / 100; + + dx = rd->border.xmin * full_width - (full_width - this->getWidth()) / 2.0f; + dy = rd->border.ymin * full_height - (full_height - this->getHeight()) / 2.0f; + } + + int ix = x - dx; + int iy = y - dy; + if (this->m_inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) { zero_v4(output); } else { - doInterpolation(output, x, y, sampler); + doInterpolation(output, ix, iy, sampler); } } diff --git a/source/blender/compositor/operations/COM_RenderLayersBaseProg.h b/source/blender/compositor/operations/COM_RenderLayersBaseProg.h index 3916862a0b3..84d6c1ee188 100644 --- a/source/blender/compositor/operations/COM_RenderLayersBaseProg.h +++ b/source/blender/compositor/operations/COM_RenderLayersBaseProg.h @@ -63,7 +63,12 @@ private: int m_renderpass; int m_elementsize; - + + /** + * @brief render data used for active rendering + */ + const RenderData *m_rd; + protected: /** * Constructor @@ -89,6 +94,7 @@ public: */ void setScene(Scene *scene) { this->m_scene = scene; } Scene *getScene() { return this->m_scene; } + void setRenderData(const RenderData *rd) { this->m_rd = rd; } void setLayerId(short layerId) { this->m_layerId = layerId; } short getLayerId() { return this->m_layerId; } void initExecution(); -- cgit v1.2.3