0

I am a newbie with gameplay3d and went through all tutorials, however I cant manage to display this simple(not much polygons and material) model that I encoded from Fbx. I checked the model with unity3D, and a closed source software that uses gameplay3d and all seems to fine. I guess I am missing some detail loading the scene.
This is the model file including also the original fbx file. I suspect if it has something to do with light https://www.dropbox.com/sh/ohgpsfnkm3iv24s/AACApRcxwtbmpKu4_5nnp8rZa?dl=0 This is the class that loads the scene.

#include "Demo.h"

// Declare our game instance
Demo game;

Demo::Demo()
    : _scene(NULL), _wireframe(false)
{
}

void Demo::initialize()
{
    // Load game scene from file
    Bundle* bundle = Bundle::create("KGN56AI30N.gpb");
    _scene = bundle->loadScene();
    SAFE_RELEASE(bundle);
    // Get the box model and initialize its material parameter values and bindings

    Camera* camera = Camera::createPerspective(45.0f, getAspectRatio(), 1.0f, 20.0f);
    Node* cameraNode = _scene->addNode("camera");

    // Attach the camera to a node. This determines the position of the camera.
    cameraNode->setCamera(camera);

    // Make this the active camera of the scene.
    _scene->setActiveCamera(camera);
    SAFE_RELEASE(camera);
    // Move the camera to look at the origin.
    cameraNode->translate(0,0, 10);
    cameraNode->rotateX(MATH_DEG_TO_RAD(0.25f));
    // Update the aspect ratio for our scene's camera to match the current device resolution
    _scene->getActiveCamera()->setAspectRatio(getAspectRatio());
    // Set the aspect ratio for the scene's camera to match the current resolution
    _scene->getActiveCamera()->setAspectRatio(getAspectRatio());

    Light* directionalLight = Light::createDirectional(Vector3::one());
    _directionalLightNode = Node::create("directionalLight");
    _directionalLightNode->setLight(directionalLight);
    SAFE_RELEASE(directionalLight);
    _scene->addNode(_directionalLightNode);
    _scene->setAmbientColor(1.0, 1.0, 1.0);
  _scene->visit(this, &Demo::initializeMaterials);

}


bool Demo::initializeMaterials(Node* node)
{
        Model* model = dynamic_cast<Model*>(node->getDrawable());

        if (model)
        {
            for(int i=0;i<model->getMeshPartCount();i++)
            {
            Material* material = model->getMaterial(i);
            if(material)
            {
            // For this sample we will only bind a single light to each object in the scene.
            MaterialParameter* colorParam = material->getParameter("u_directionalLightColor[0]");
            colorParam->setValue(Vector3(0.75f, 0.75f, 0.75f));
            MaterialParameter* directionParam = material->getParameter("u_directionalLightDirection[0]");
            directionParam->setValue(Vector3(1, 1, 1));
            }
            }
        }
        return true;
}

void Demo::finalize()
{
    SAFE_RELEASE(_scene);
}

void Demo::update(float elapsedTime)
{
    // Rotate model
    //_scene->findNode("box")->rotateY(MATH_DEG_TO_RAD((float)elapsedTime / 1000.0f * 180.0f));
}

void Demo::render(float elapsedTime)
{
    // Clear the color and depth buffers
    clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0);

    // Visit all the nodes in the scene for drawing
    _scene->visit(this, &Demo::drawScene);
}

bool Demo::drawScene(Node* node)
{
    // If the node visited contains a drawable object, draw it
    Drawable* drawable = node->getDrawable(); 
    if (drawable)
        drawable->draw(_wireframe);

    return true;
}

void Demo::keyEvent(Keyboard::KeyEvent evt, int key)
{
    if (evt == Keyboard::KEY_PRESS)
    {
        switch (key)
        {
        case Keyboard::KEY_ESCAPE:
            exit();
            break;
        }
    }
}

void Demo::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
{
    switch (evt)
    {
    case Touch::TOUCH_PRESS:
        _wireframe = !_wireframe;
        break;
    case Touch::TOUCH_RELEASE:
        break;
    case Touch::TOUCH_MOVE:
        break;
    };
}
happycoder
  • 33
  • 8

1 Answers1

0

I can't download your dropbox .fbx file. How many models do you have in the scene? Here's a simple way of doing what you want to do -- not optimal, but it'll get you started...

So first off, I can't see where in your code you actually assign a Shader to be used with the material. I use something like this:

material = model->setMaterial("Shaders/Animation/ADSVertexViewAnim.vsh", "Shaders/Animation/ADSVertexViewAnim.fsh");

You need to assign a Shader, and the above code will take the vertex and fragment shaders and use that when the object needs to be drawn.

I went about it a slightly different way by not loading the scene file automatically, but creating an empty scene and then extracting my model from the bundle and adding it to the scene manually. That way, I can see exactly what is happening and I'm in control of each step. GamePlay3D has some fancy property files, but use them only once you know how the process works manually..

Initially, I created a simple cube in a scene, and created a scene manually, and added the monkey to the node graph, as follows:

void GameMain::ExtractFromBundle()
{
    /// Create a new empty scene.
    _scene = Scene::create();

    // Create the Model and its Node
    Bundle* bundle = Bundle::create("res/monkey.gpb");          // Create the bundle from GPB file

    /// Create the Cube
    {
        Mesh* meshMonkey = bundle->loadMesh("Character_Mesh");              // Load the mesh from the bundle
        Model* modelMonkey = Model::create(meshMonkey);
        Node* nodeMonkey = _scene->addNode("Monkey");
        nodeMonkey->setTranslation(0,0,0);
        nodeMonkey->setDrawable(modelMonkey);
    }
}

Then I want to search the scene graph and only assign a material to the object that I want to draw (the monkey). Use this if you want to assign different materials to different objects manually...

bool GameMain::initializeScene(Node* node)
{
    Material* material;

    std::cout << node->getId() << std::endl;

    // find the node in the scene
    if (strcmp(node->getId(), "Monkey") != 0)
        return false;

    Model* model = dynamic_cast<Model*>(node->getDrawable());
    if( !model )
        return false;

    material = model->setMaterial("Shaders/Animation/ADSVertexViewAnim.vsh", "Shaders/Animation/ADSVertexViewAnim.fsh");

    material->getStateBlock()->setCullFace(true);
    material->getStateBlock()->setDepthTest(true);
    material->getStateBlock()->setDepthWrite(true);

    // The World-View-Projection Matrix is needed to be able to see view the 3D world thru the camera
    material->setParameterAutoBinding("u_worldViewProjectionMatrix", "WORLD_VIEW_PROJECTION_MATRIX");

    // This matrix is necessary to calculate normals properly, but the WORLD_MATRIX would also work
    material->setParameterAutoBinding("u_worldViewMatrix", "WORLD_VIEW_MATRIX");
    material->setParameterAutoBinding("u_viewMatrix", "VIEW_MATRIX");

    return true;
}

Now the object is ready to be drawn.... so I use these functions:

void GameMain::render(float elapsedTime)
{
    // Clear the color and depth buffers
    clear(CLEAR_COLOR_DEPTH, Vector4(0.0, 0.0, 0.0, 0.0), 1.0f, 0);

    // Visit all the nodes in the scene for drawing
    _scene->visit(this, &GameMain::drawScene);
}

bool GameMain::drawScene(Node* node)
{
    // If the node visited contains a drawable object, draw it
    Drawable* drawable = node->getDrawable();
    if (drawable)
        drawable->draw(_wireframe);

    return true;
}

I use my own shaders, so I don't have to worry about Light and DirectionalLight and all that stuff. Once I can see the object, then I'll add dynamic lights, etc, but for starters, start simple.

Regards.

Michael
  • 84
  • 6