Toon Shader

Hi all,
I’m trying to convert the python code with panda to c++ version, but i have a problem with that :

Python version :

 tempnode = NodePath(PandaNode("temp node"))
        tempnode.setShader(loader.loadShader("lightingGen.sha"))
        base.cam.node().setInitialState(tempnode.getState())
        
        # This is the object that represents the single "light", as far
        # the shader is concerned.  It's not a real Panda3D LightNode, but
        # the shader doesn't care about that.

        light = render.attachNewNode("light")
        light.setPos(30,-50,0)
                
        # this call puts the light's nodepath into the render state.
        # this enables the shader to access this light by name.

        render.setShaderInput("light", light)

My convertion :

PT(PointLight) p_light;
p_light = new PointLight("light");
p_light->set_color(LVecBase4f(0.8, 0.8, 0.5, 1));
NodePath plnp = window->get_render().attach_new_node(p_light);

NodePath plight;
plight = new PandaNode("temp node");
PT(Shader) Light_Shader = Shader::load("lightingGen.sha");
plight.set_shader(Light_Shader);
plight.reparent_to(window->get_render());

plight.set_shader_input("light", p_light);
plnp.set_hpr(30, 60, 85);
plnp.set_pos(30,160,200);

But it’s say’s that this line :
plight.set_shader_input(“light”, p_light);

Have a problem, and i don’t know how to resolve it!

Thanks all !

You probably meant “plnp”, not “p_light”, in that line.

After the build windows says me that an error has occured and an access violation of memory.
I just want a basic toon shading :cry:

NodePath plight;
plight = new PandaNode("temp node"); 

That doesn’t make much sense. I don’t know what exactly you’re trying to do (it doesn’t look like this is supposed to be a translation of above Python code), but your code doesn’t make very much sense to me.

Yes it’s that line wich make the problem,
There is the python’s one :

tempnode = NodePath(PandaNode(“temp node”))

My translation of that Python code: (untested)

NodePath tempnode ("temp node");
tempnode.set_shader(Shader::load("lightingGen.sha"));
window->get_camera(0)->set_initial_state(tempnode.get_state());

// This is the object that represents the single "light", as far
// the shader is concerned.  It's not a real Panda3D LightNode, but
// the shader doesn't care about that.

NodePath light = window->get_render().attach_new_node("light");
light.set_pos(30, -50, 0);
   
// this call puts the light's nodepath into the render state.
// this enables the shader to access this light by name.

window->get_render().set_shader_input("light", light); 

Thanks it works, but why it doesn’t making anything ?

The same python code draw a correct toon shading ( without border but it’s not the point ) but in c++ it’s don’t draw the shading, my question is why you deleted the “PandaNode” function ? because it’s the only difference between them

Here is the full concerned python code :

#Author: Kwasi Mensah
#Date: 7/11/2005
#
# This is a tutorial to show some of the more advanced things
# you can do with Cg. Specifically, with Non Photo Realistic
# effects like Toon Shading. It also shows how to implement
# multiple buffers in Panda.


import direct.directbase.DirectStart
from panda3d.core import PandaNode,LightNode,TextNode
from panda3d.core import Filename
from panda3d.core import NodePath
from panda3d.core import Shader
from panda3d.core import Point3,Vec4
from direct.task.Task import Task
from direct.actor.Actor import Actor
from direct.gui.OnscreenText import OnscreenText
from direct.showbase.DirectObject import DirectObject
from direct.showbase.BufferViewer import BufferViewer
import sys,os

# Function to put instructions on the screen.


class ToonMaker(DirectObject):
    def __init__(self):
        camera.setPos(0, -50, 0)
        tempnode = NodePath(PandaNode("temp node"))
   tempnode.setShader(loader.loadShader("lightingGen.sha"))
      base.cam.node().setInitialState(tempnode.getState())
        light = render.attachNewNode("light")
        light.setPos(30,-50,0)
 
        render.setShaderInput("light", light)
        self.character=Actor()
        self.character.loadModel('models/nik-dragon')
        self.character.reparentTo(render)
        self.accept("escape", sys.exit, [0])

t=ToonMaker()

run()


And there is my code :

#include "pandaFramework.h"
#include "pandaSystem.h"
 
#include "genericAsyncTask.h"
#include "asyncTaskManager.h"
#include "shader.h"
#include "ambientLight.h"
#include "directionalLight.h"
#include "pointLight.h"
#include "spotlight.h"

// Global stuff
PandaFramework framework;
PT(AsyncTaskManager) taskMgr = AsyncTaskManager::get_global_ptr(); 
PT(ClockObject) globalClock = ClockObject::get_global_clock();
NodePath camera;
 
// Task to move the camera
AsyncTask::DoneStatus SpinCameraTask(GenericAsyncTask* task, void* data) {
    double time = globalClock->get_real_time();
    double angledegrees = time * 6.0;
    double angleradians = angledegrees * (3.14 / 180.0);



    return AsyncTask::DS_cont;
}
 
int main(int argc, char *argv[]) {
    // Open a new window framework and set the title
    framework.open_framework(argc, argv);
    framework.set_window_title("Illiade");
 
    // Open the window
    WindowFramework *window = framework.open_window();
    camera = window->get_camera_group(); // Get the camera and store it
	window->setup_trackball();
    // Load 

//NodePath plnp = window->get_render().attach_new_node(p_light);
NodePath tempnode ("temp node");
tempnode.set_shader(Shader::load("lightingGen.sha"));
window->get_camera(0)->set_initial_state(tempnode.get_state());

NodePath light = window->get_render().attach_new_node("light");
window->get_render().set_shader_input("light", light);
light.set_pos(30, 60, 100);

    NodePath pandaActor = window->load_model(framework.get_models(), "mm/nik-dragon");

    pandaActor.set_scale(0.05);
    pandaActor.reparent_to(window->get_render());
	pandaActor.set_pos(30,60, 15);

    taskMgr->add(new GenericAsyncTask("Spins the camera", &SpinCameraTask, (void*) NULL));
    framework.main_loop();
    framework.close_framework();
    return (0);
}

There is no difference…


EDIT : Fixed when i run the folder’s exe, because he don’t find the SHA file.

Another problem this time, ( i write it in the same post because it’s related to the toon shading )

When i apply the shader, the texture disapear oO

Look by yourself :

How can I solve it? Thanks for your help !

That’s because the shader you used simply does not respect any assigned textures.

Modify the shader so that it does respect textures. If you don’t know how, search the forums. This question has come up several times before.

They say to use the CommonFilters, but in c++ this function isn’t there, so the only solution is to learn the cg and apply the shader to the texture ?