Render Preview Image of Shader
-
On 30/03/2013 at 04:08, xxxxxxxx wrote:
User Information:
Cinema 4D Version:
Platform:
Language(s) :---------
I'm trying to render a preview-image of a BaseShader, but I get crashes in sdl.cdl. I guess it's because
I don't pass a VolumeData to the ChannelData? I can't get it right. Strange thing is, that the call-stack
only shows one call to my plugin which is the BaseContainer destructor.. And I don't even use a
BaseContainer in this code.Code:
sla.cdl!5f9f1ac6()
[Unten angegebene Rahmen sind möglicherweise nicht korrekt und/oder fehlen, keine Symbole geladen für sla.cdl]
xtensions.cdl!5f73a5e7()
CINEMA 4D.exe!01718250()
CINEMA 4D.exe!01718250()
CINEMA 4D.exe!016a2b74()
CINEMA 4D.exe!01bcd2d2()
CINEMA 4D.exe!01bd0012()
CINEMA 4D.exe!01509238()
CINEMA 4D.exe!0145a4de()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!016186e1()
CINEMA 4D.exe!016186e1()
CINEMA 4D.exe!01716a94()
CINEMA 4D.exe!016a17bb()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!016186e1()
CINEMA 4D.exe!016186e1()
CINEMA 4D.exe!01716a94()
CINEMA 4D.exe!01716a94()
CINEMA 4D.exe!016a2595()
CINEMA 4D.exe!017024ef()
CINEMA 4D.exe!01711f53()
CINEMA 4D.exe!01626739()
CINEMA 4D.exe!016975ce()
CINEMA 4D.exe!01b71a3c()
CINEMA 4D.exe!0161130f()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!0161132c()
CINEMA 4D.exe!016186e1()
CINEMA 4D.exe!01716b74()
CINEMA 4D.exe!01701696()
CINEMA 4D.exe!01711f53()
CINEMA 4D.exe!01626739()
CINEMA 4D.exe!016975ce()
CINEMA 4D.exe!01716b74()
CINEMA 4D.exe!0170e612()
CINEMA 4D.exe!01716f63()
CINEMA 4D.exe!0172088e()
CINEMA 4D.exe!0171a86d()
CINEMA 4D.exe!01b71a3c()
CINEMA 4D.exe!0171cd91()
CINEMA 4D.exe!0174e19c()
CINEMA 4D.exe!0174e19c()
user32.dll!75368e63()
user32.dll!75368e9f()
msctf.dll!74dc5123()
msctf.dll!74dc439e()
msctf.dll!74dc3ad3()
user32.dll!7537491f()
user32.dll!75374902()
user32.dll!753729d5()
user32.dll!753729b8()
user32.dll!75368112()
CINEMA 4D.exe!01b58efc()
CINEMA 4D.exe!0161a415()
CINEMA 4D.exe!01619581()
CINEMA 4D.exe!016975ce()
CINEMA 4D.exe!0169fbe9()
CINEMA 4D.exe!01701696()
CINEMA 4D.exe!01711f53()
CINEMA 4D.exe!01711f53()
CINEMA 4D.exe!01711f53()
CINEMA 4D.exe!01643962()
CINEMA 4D.exe!01619581()
CINEMA 4D.exe!016975ce()
CINEMA 4D.exe!01696d7a()
CINEMA 4D.exe!01619581()
CINEMA 4D.exe!016975ce()
CINEMA 4D.exe!016975ce()
KernelBase.dll!75195338()
> myplugin.cdl!BaseContainer::~BaseContainer() Zeile 41 C++
0039c634()
CINEMA 4D.exe!01bd59cd()
CINEMA 4D.exe!01ba3054()
CINEMA 4D.exe!01b1bd67()
CINEMA 4D.exe!00e60ef9()
CINEMA 4D.exe!01bc7dbf()
CINEMA 4D.exe!01707671()
CINEMA 4D.exe!0147ad67()Code:
Bool RenderShader(BaseShader* shader, BaseBitmap* bmp, Real scale=1.0) {
InitRenderStruct irs;
if (shader->InitRender(irs) != INITRENDERRESULT_OK) return FALSE;LONG w = bmp->GetBw();
LONG h = bmp->GetBh();
ChannelData cd;for (LONG x=0; x < w; x++) {
for (LONG y=0; y < h; y++) {cd.p.x = x * scale;
cd.p.y = y * scale;
cd.p.z = 0.0;Vector pixel = shader->Sample(&cd);
LONG r = pixel.x * 255;
LONG g = pixel.y * 255;
LONG b = pixel.z * 255;
bmp->SetPixel(x, y, r, g, b);
}
}shader->FreeRender();
return TRUE;
}Any tips much appreciated. Thanks in advance!
-Niklas
-
On 30/03/2013 at 05:27, xxxxxxxx wrote:
The only bad thing I notice is that you are not checking any pointers for NULL.
An empty VolumeData pointer in the ChannelData should not a problem. -
On 30/03/2013 at 05:50, xxxxxxxx wrote:
Hi Jack,
I ensure to pass valid pointers before calling the function anyway so I
decided to not include these checks in the function.Hm.. I'll try again in another environment, since you say it actually
looks to be correct.Thanks,
-Niklas
-
On 30/03/2013 at 06:13, xxxxxxxx wrote:
I've tried to do it in Python first:
from __future__ import division import c4d from c4d.modules import render def RenderShader(shader, bmp, scale=1.0) : irs = render.InitRenderStruct(doc) if shader.InitRender(irs) != c4d.INITRENDERRESULT_OK: return False cd = render.ChannelData() w, h = bmp.GetSize() for x in xrange(w) : for y in xrange(h) : cd.p.x = x * scale cd.p.y = y * scale c = shader.Sample(cd) r = int(c.x * 255) g = int(c.y * 255) b = int(c.z * 255) bmp.SetPixel(x, y, r, g, b) shader.FreeRender() return True def main() : bmp = c4d.bitmaps.BaseBitmap() bmp.Init(128, 128, 24) mat = doc.GetActiveMaterial() sha = mat.GetFirstShader() if not RenderShader(sha, bmp, 1.0) : print "Rendering shader was not successful." return c4d.bitmaps.ShowBitmap(bmp) main()
But all I get is a mono-coloured image (black or grey, depending on the shader in the active
material). -
On 30/03/2013 at 11:06, xxxxxxxx wrote:
This works!!
Bool RenderShader(BaseShader* shader, BaseBitmap* bmp, Real scale=1.0) { InitRenderStruct irs; if (shader->InitRender(irs) != INITRENDERRESULT_OK) return FALSE; LONG w = bmp->GetBw(); LONG h = bmp->GetBh(); ChannelData cd; cd.p = Vector(0, 0, 0); cd.n = Vector(0, 0, 1); cd.d = Vector(0, 0, 0); cd.t = 0.0; cd.texflag = 0; cd.vd = NULL; cd.off = 0.0; cd.scale = 0.0; for (LONG x=0; x < w; x++) { for (LONG y=0; y < h; y++) { cd.p.x = (Real) x * scale; cd.p.y = (Real) y * scale; Vector pixel = shader->Sample(&cd); LONG r = MIN(255, pixel.x * 255); LONG g = MIN(255, pixel.y * 255); LONG b = MIN(255, pixel.z * 255); bmp->SetPixel(x, y, r, g, b); } } shader->FreeRender(); return TRUE; }
I just initialized every value of the ChannelData.
-Niklas
-
On 30/03/2013 at 11:11, xxxxxxxx wrote:
Works for most shaders.. But eg. the tile shader is black only..
-
On 30/03/2013 at 11:24, xxxxxxxx wrote:
hm,
i haven't red everything, but this might help. it is a class to sample a baseshader into
vertexmap data.