aap / librw

A re-implementation of the RenderWare Graphics engine
MIT License
567 stars 90 forks source link

[Question] Why does my code fail to render color on a cube? #129

Closed Davilarek closed 5 months ago

Davilarek commented 5 months ago

I know I probably shouldn't be asking this in Issues but this project as far as I know doesn't have a discord or any other way of communication.

rw::Atomic* CreateCube()
{
    float size = 0.25f; // Size of the cube

    rw::V3d vertices[8] = {
        {-size, -size, -size},
        {size, -size, -size},
        {size, size, -size},
        {-size, size, -size},
        {-size, -size, size},
        {size, -size, size},
        {size, size, size},
        {-size, size, size} };

    rw::uint16 indices[36] = {
        0, 1, 2, 0, 2, 3, // Front face
        1, 5, 6, 1, 6, 2, // Right face
        5, 4, 7, 5, 7, 6, // Back face
        4, 0, 3, 4, 3, 7, // Left face
        3, 2, 6, 3, 6, 7, // Top face
        4, 5, 1, 4, 1, 0  // Bottom face
    };

    rw::Geometry* geometry = rw::Geometry::create(8, 36, 0);
    for (int i = 0; i < 36; ++i)
    {
        rw::Triangle* triangle = &(geometry->triangles[i]);
        triangle->matId = 0;
        triangle->v[0] = indices[i * 3];
        triangle->v[1] = indices[i * 3 + 1];
        triangle->v[2] = indices[i * 3 + 2];
    }
    auto mat = rw::Material::create();
    mat->color = rw::makeRGBA(200, 64, 200, 255);
    geometry->matList.appendMaterial(mat);

    geometry->unlock();

    size_t meshI = geometry->meshHeader->numMeshes;
    for (int i = 0; i < meshI; i++)
    {
        rw::Mesh* t = geometry->meshHeader->getMeshes();
        t[i].material = mat;
    }
    geometry->morphTargets->vertices = (rw::V3d*)rwMalloc(sizeof(rw::V3d)*(sizeof(vertices)/sizeof(*vertices)),0);
    for (int i = 0; i < 8; ++i)
    {
        geometry->morphTargets->vertices[i] = vertices[i];
    }

    rw::Atomic* atomic = rw::Atomic::create();
    atomic->geometry = geometry;
    return atomic;
}

This code renders the cube plain black

aap commented 5 months ago

Looks like you're doing a lot of unnecessary work that librw should be doing. I guess I'm to blame for not documenting things properly. I have something similar here, but it looks like i wrote this before i implemented Geometry::unlock() so it calls buildMeshes directly. Just replace that with unlock: https://github.com/aap/librwgta/blob/master/tools/storiesview/main.cpp#L279

Also you the proper way to give an atomic a geometry would be atomic->setGeometry(geometry, 0)

The reason why it's black could be because you have no lights? Adding an ambient light might help.

Davilarek commented 5 months ago

I tried adding this to my 3d init function but sadly no result...

    auto pAmbient = rw::Light::create(rw::Light::AMBIENT);
    pAmbient->setColor(1.0f, 1.0f, 1.0f);
    world->addLight(pAmbient);

Edit: I also replaced my code with the one you provided and changed Geometry::buildMeshes with Geometry::unlock, still the cube is black. obraz

aap commented 5 months ago

hm, or perhaps you need some geometry flags. LIGHT and MODULATE. Although without MODULATE the material color will be taken as white, but i think you indeed are missing LIGHT.

Davilarek commented 5 months ago

Looks like we are getting somewhere. Adding LIGHT flag made so I'm now affected by the issue that #125 fixes.

Program received signal SIGSEGV, Segmentation fault.
0x0000555555648366 in rw::World::enumerateLights (this=0x0, atomic=atomic@entry=0x5555561bf9e0, lightData=lightData@entry=0x7fffffffd580) at /home/davil/Projects/Engine3D_No_Name_/librw/src/world.cpp:160
160             FORLIST(lnk, this->globalLights){
(gdb) print this
$1 = (rw::World * const) 0x0
(gdb) bt
#0  0x0000555555648366 in rw::World::enumerateLights (this=0x0, atomic=atomic@entry=0x5555561bf9e0, lightData=lightData@entry=0x7fffffffd580) at /home/davil/Projects/Engine3D_No_Name_/librw/src/world.cpp:160
#1  0x0000555555655d72 in rw::gl3::lightingCB (atomic=atomic@entry=0x5555561bf9e0) at /home/davil/Projects/Engine3D_No_Name_/librw/src/gl/gl3render.cpp:125
#2  0x0000555555655e75 in rw::gl3::defaultRenderCB (atomic=0x5555561bf9e0, header=0x55555617d9e0) at /home/davil/Projects/Engine3D_No_Name_/librw/src/gl/gl3render.cpp:154

somehow the world is gone? Edit: world was indeed gone. Fixed by setting camera's world property. Thank you for help. obraz