花了点时间把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);