博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

NDK学习笔记(二)

Posted on 2015-11-06 19:37  SolHe  阅读(282)  评论(0编辑  收藏  举报

花了点时间把pixeliop的部分看完了,拿到开发文档提供的案例稍事修改,把画面左半边压暗。

这个案例重点在于理清pixel_engine()函数中的坐标与scanline的关系。

y代表当前正在调用的行高,x代表该行左头坐标,r代表该行右头坐标,foreach循环会逐通道执行内部代码块,inptr是Row类型的输入指针,outptr是Row类型的输出指针,赋值结果是inptr指针与outptr指针指向当前操作行的左边起始位置,END指针指向当前操作行的右边结尾位置。

左半边的循环亮度衰减0.5,这个循环很简单,详细见代码块。

重点在于右半边亮度不变的代码块,如果不写的话会不会默认不变呢?简单测试了下,如果不写右半边的代码块,nuke显示会出问题,会有花屏情况。所以严谨起见,画面中每一个区域都不应该忽略,要写全。这算是学习c++的第一个教训及收获吧。

通过这个简单的小案例也意识到了一点,利用alpha通道预乘的操作也可以通过这种相乘的方式进行。更进一步,动画以及一些更为抽象的数据是否也可以通过乘法来进行呢?答案是肯定的,功能的实现需要探索。

加油吧,贴个代码:

static const char* const HELP = "Basic: Does nothing but copy the input from input0 to the output";

#include <DDImage/NukeWrapper.h>
#include <DDImage/PixelIop.h>
#include <DDImage/Row.h>
#include <DDImage/Knobs.h>

using namespace DD::Image;

class Basic : public PixelIop {
public:
	void in_channels(int input, ChannelSet& mask) const;
Basic(Node *node) : PixelIop(node) {
}

void pixel_engine(const Row& in, int y, int x, int r, ChannelMask, Row& out);
static const Iop::Description d;
const char* Class() const {return d.name;}
const char* node_help() const {return HELP;}
void _validate(bool);
};

void Basic::_validate(bool for_real) {
  copy_info();
  //set_out_channels(Mask_Red);
  //set_out_channels(Mask_RGB);
  //PixelIop::_validate(for_real);
}

void Basic::in_channels(int input, ChannelSet& mask) const {
  //mask &= Mask_Red;
//mask is unchanged
}

void Basic::pixel_engine(const Row& in, int y, int x, int r, ChannelMask channels, Row& out){
  foreach (z, channels) {
    const float* inptr = in[z]+x;
    const float* END = inptr+(r-x);
    float* outptr = out.writable(z)+x;
    for (int num = x ; num < (r-x+1)/2 ; num++)
    {
      outptr[num] = 0.5f * inptr[num];
    }
	for (int num = (r-x+1)/2 ; num < r ; num++)
    {
      outptr[num] = inptr[num];
    }
  }
}

static Iop* build(Node *node) {return new NukeWrapper(new Basic(node));}
const Iop::Description Basic::d("Basic", "Basic", build);