On 01/05/2013 at 14:11, xxxxxxxx wrote:
Hi,
here's a quick example of drawing an image over the editor window:
/**
* Copyright (C) 2013, Niklas Rosenstein
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
*
* You should have received a copy of the Lesser GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <c4d.h>
#include <lib_clipmap.h>
typedef struct Rect {
LONG x1, y1, x2, y2;
} Rect_t;
class OverlayHook : public SceneHookData {
AutoAlloc<GeClipMap> image;
BaseTime last_time;
Bool drawn;
public:
static NodeData* Alloc() { return gNew OverlayHook; }
OverlayHook();
void FillOverlay(const Rect_t& rect, LONG frame, Bool update_fill);
//////// SceneHookData Overrides
Bool Draw(BaseSceneHook* host, BaseDocument* doc, BaseDraw* bd, BaseDrawHelp* bh,
BaseThread* bt, SCENEHOOKDRAW flags);
};
OverlayHook::OverlayHook() : drawn(FALSE) {
}
void OverlayHook::FillOverlay(const Rect_t& rect, LONG frame, Bool update_fill) {
LONG width = rect.x2 - rect.x1;
LONG height = rect.y2 - rect.y1;
// Ensure that the image is large enough, reallocate if
// necessary!
if (image->GetBw() < width || image->GetBh() < height) {
GeDebugOut(" Reallocating image...");
image->Destroy();
if (image->Init(width, height, 32) != IMAGERESULT_OK) {
return;
}
update_fill = TRUE;
}
if (!update_fill) return;
GeDebugOut(" Updating fill..");
image->BeginDraw();
for (LONG x=0; x < width; x++) {
for (LONG y=0; y < height; y++) {
Real v = (SNoise(Vector(x / 50.0, y / 50.0, frame)) + 1) / 2;
v *= (Real) x / width;
LONG g = (LONG) (v * 255);
image->SetPixelRGBA(x, y, 255, 255, 255, g);
}
}
image->EndDraw();
drawn = TRUE;
}
Bool OverlayHook::Draw(BaseSceneHook* host, BaseDocument* doc, BaseDraw* bd, BaseDrawHelp* bh,
BaseThread* bt, SCENEHOOKDRAW flags) {
if (!host || !doc || !bd || !bh || !bt) return FALSE;
if (flags != SCENEHOOKDRAW_DRAW_PASS) return TRUE;
Rect_t rect;
bd->GetSafeFrame(&rect.x1, &rect.y1, &rect.x2, &rect.y2);
// Draw something on the overlay image.
BaseTime time = doc->GetTime();
Bool update_fill = time != last_time || !drawn;
last_time = time;
FillOverlay(rect, time.GetFrame(doc->GetFps()), update_fill);
// Draw the overlay image on the screen.
BaseBitmap* bmp = image->GetBitmap();
if (!bmp) return TRUE;
bd->SetMatrix_Screen();
Vector padr4[4];
padr4[0] = Vector(rect.x1, rect.y1, 0);
padr4[1] = Vector(rect.x2, rect.y1, 0);
padr4[2] = Vector(rect.x2, rect.y2, 0);
padr4[3] = Vector(rect.x1, rect.y2, 0);
Vector uvadr[4];
uvadr[0] = Vector(0, 0, 0);
uvadr[1] = Vector(1, 0, 0);
uvadr[2] = Vector(1, 1, 0);
uvadr[3] = Vector(0, 1, 0);
bd->DrawTexture(bmp, padr4, NULL, NULL, uvadr, 4,
DRAW_ALPHA_FROM_IMAGE, DRAW_TEXTUREFLAGS_0);
return TRUE;
}
Bool RegisterOverlayHook() {
LONG flags = PLUGINFLAG_SCENEHOOK_NOTDRAGGABLE;
DataAllocator* alloc = OverlayHook::Alloc;
return RegisterSceneHookPlugin(1000001, "Overlay Hook", flags, alloc, 0, 0);
}
Bool PluginStart() {
return RegisterOverlayHook();
}
Bool PluginMessage(LONG type, void* pData) {
return TRUE;
}
void PluginEnd() {
}
I had immense problems figuring out how to actually apply the DrawTexture() method, so that
took most of the time, the rest was really easy. It's not working 100% satisfieng (see this thread)
but actually does it's job.

What also still needs to be added, is that the pixels are actually drawn 1 by 1 on the screen. Atm,
the whole bitmap is drawn into the editor window. The bitmap might actually exceed the window
resolution because I reallocate it when it was to small to fit in it, but do not reallocate it when it
would exceed (which would eat lots of power).
Best,
-Niklas
EDIT: Added missing line (orange).