0

我是 game3d 的新手,并且浏览了所有教程,但是我无法显示我从 Fbx 编码的这个简单(没有太多多边形和材质)模型。我用unity3D和一个使用gameplay3d的闭源软件检查了模型,一切似乎都很好。我想我错过了加载场景的一些细节。
这是模型文件,还包括原始 fbx 文件。我怀疑它是否与光 有关https://www.dropbox.com/sh/ohgpsfnkm3iv24s/AACApRcxwtbmpKu4_5nnp8rZa?dl=0 这是加载场景的类。

#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;
    };
}
4

1 回答 1

0

我无法下载您的保管箱 .fbx 文件。场景中有多少个模型?这是一种做你想做的事情的简单方法——不是最佳的,但它会让你开始......

因此,首先,我看不到您在代码中的哪个位置实际分配了要与材质一起使用的着色器。我使用这样的东西:

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

您需要分配一个着色器,上面的代码将采用顶点和片段着色器,并在需要绘制对象时使用它们。

我做了一个稍微不同的方法,不自动加载场景文件,而是创建一个空场景,然后从包中提取我的模型并手动将其添加到场景中。这样,我可以准确地看到正在发生的事情,并且我可以控制每一步。GamePlay3D 有一些花哨的属性文件,但只有在您知道该过程如何手动工作时才能使用它们。

最初,我在一个场景中创建了一个简单的立方体,并手动创建了一个场景,并将猴子添加到节点图中,如下所示:

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);
    }
}

然后我想搜索场景图,只为我想要绘制的对象(猴子)分配一个材质。如果您想手动将不同的材质分配给不同的对象,请使用此选项...

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;
}

现在对象已准备好绘制......所以我使用这些函数:

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;
}

我使用自己的着色器,所以我不必担心 Light 和 DirectionalLight 以及所有这些东西。一旦我可以看到对象,我将添加动态灯光等,但对于初学者来说,从简单开始。

问候。

于 2016-09-13T02:14:01.563 回答