Beispiel #1
0
void Render(Gfx::CGLDevice *device, Gfx::CModelFile *modelFile)
{
    device->BeginScene();

    Math::Matrix persp;
    Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.0f), 0.1f, 100.0f);
    device->SetTransform(Gfx::TRANSFORM_PROJECTION, persp);

    Math::Matrix id;
    id.LoadIdentity();
    device->SetTransform(Gfx::TRANSFORM_WORLD, id);

    Math::Matrix viewMat;
    Math::LoadTranslationMatrix(viewMat, TRANSLATION);
    Math::Matrix rot;
    Math::LoadRotationXZYMatrix(rot, ROTATION);
    viewMat = Math::MultiplyMatrices(viewMat, rot);
    device->SetTransform(Gfx::TRANSFORM_VIEW, viewMat);

    const std::vector<Gfx::ModelTriangle> &triangles = modelFile->GetTriangles();

    Gfx::VertexTex2 tri[3];

    for (int i = 0; i < static_cast<int>( triangles.size() ); ++i)
    {
        device->SetTexture(0, GetTexture(triangles[i].tex1Name));
        device->SetTexture(1, GetTexture(triangles[i].tex2Name));
        device->SetTextureEnabled(0, true);
        device->SetTextureEnabled(1, true);

        device->SetMaterial(triangles[i].material);

        tri[0] = triangles[i].p1;
        tri[1] = triangles[i].p2;
        tri[2] = triangles[i].p3;

        device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, tri, 3);
    }

    device->EndScene();
}
Beispiel #2
0
void CCloud::Draw()
{
    if (! m_enabled) return;
    if (m_level == 0.0f) return;
    if (m_lines.empty()) return;

    std::vector<VertexTex2> vertices((m_brickCount+2)*2, VertexTex2());

    float iDeep = m_engine->GetDeepView();
    float deep = (m_brickCount*m_brickSize)/2.0f;
    m_engine->SetDeepView(deep);
    m_engine->SetFocus(m_engine->GetFocus());
    m_engine->UpdateMatProj();  // increases the depth of view

    float fogStart = deep*0.15f;
    float fogEnd   = deep*0.24f;

    CDevice* device = m_engine->GetDevice();

    // TODO: do this better?
    device->SetFogParams(FOG_LINEAR, m_engine->GetFogColor( m_engine->GetRankView() ),
                        fogStart, fogEnd, 1.0f);

    device->SetTransform(TRANSFORM_VIEW, m_engine->GetMatView());

    Material material;
    material.diffuse = m_diffuse;
    material.ambient = m_ambient;
    m_engine->SetMaterial(material);

    m_engine->SetTexture(m_fileName, 0);
    m_engine->SetTexture(m_fileName, 1);

    m_engine->SetState(ENG_RSTATE_TTEXTURE_BLACK | ENG_RSTATE_FOG | ENG_RSTATE_WRAP);

    Math::Matrix matrix;
    matrix.LoadIdentity();
    device->SetTransform(TRANSFORM_WORLD, matrix);

    float size = m_brickSize/2.0f;
    Math::Vector eye = m_engine->GetEyePt();
    Math::Vector n = Math::Vector(0.0f, -1.0f, 0.0f);

    // Draws all the lines
    for (int i = 0; i < static_cast<int>( m_lines.size() ); i++)
    {
        Math::Vector pos;
        pos.y = m_level;
        pos.z = m_lines[i].pz;
        pos.x = m_lines[i].px1;

        int vertexIndex = 0;

        Math::Vector p;
        Math::Point uv1, uv2;

        p.x = pos.x-size;
        p.z = pos.z+size;
        p.y = pos.y;
        AdjustLevel(p, eye, deep, uv1, uv2);
        vertices[vertexIndex++] = VertexTex2(p, n, uv1, uv2);

        p.x = pos.x-size;
        p.z = pos.z-size;
        p.y = pos.y;
        AdjustLevel(p, eye, deep, uv1, uv2);
        vertices[vertexIndex++] = VertexTex2(p, n, uv1, uv2);

        for (int j = 0; j < m_lines[i].len; j++)
        {
            p.x = pos.x+size;
            p.z = pos.z+size;
            p.y = pos.y;
            AdjustLevel(p, eye, deep, uv1, uv2);
            vertices[vertexIndex++] = VertexTex2(p, n, uv1, uv2);

            p.x = pos.x+size;
            p.z = pos.z-size;
            p.y = pos.y;
            AdjustLevel(p, eye, deep, uv1, uv2);
            vertices[vertexIndex++] = VertexTex2(p, n, uv1, uv2);

            pos.x += size*2.0f;
        }

        device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, &vertices[0], vertexIndex);
        m_engine->AddStatisticTriangle(vertexIndex - 2);
    }

    m_engine->SetDeepView(iDeep);
    m_engine->SetFocus(m_engine->GetFocus());
    m_engine->UpdateMatProj();  // gives depth to initial
}
Beispiel #3
0
void CLightning::Draw()
{
    if (!m_lightningExists) return;
    if (m_phase != LP_FLASH) return;

    CDevice* device = m_engine->GetDevice();

    Math::Matrix mat;
    mat.LoadIdentity();
    device->SetTransform(TRANSFORM_WORLD, mat);

    m_engine->SetTexture("effect00.png");
    m_engine->SetState(ENG_RSTATE_TTEXTURE_BLACK);

    Math::Point texInf;
    texInf.x = 64.5f/256.0f;
    texInf.y = 33.0f/256.0f;
    Math::Point texSup;
    texSup.x = 95.5f/256.0f;
    texSup.y = 34.0f/256.0f;  // blank

    Math::Vector p1 = m_pos;
    Math::Vector eye = m_engine->GetEyePt();
    float a = Math::RotateAngle(eye.x-p1.x, eye.z-p1.z);
    Math::Vector n = Math::Normalize(p1-eye);

    Math::Vector corner[4];
    Vertex vertex[4];

    for (int i = 0; i < FLASH_SEGMENTS-1; i++)
    {
        Math::Vector p2 = p1;
        p2.y += 8.0f+0.2f*i;

        Math::Point rot;

        Math::Vector p = p1;
        p.x += m_width[i];
        rot = Math::RotatePoint(Math::Point(p1.x, p1.z), a+Math::PI/2.0f, Math::Point(p.x, p.z));
        corner[0].x = rot.x+m_shift[i].x;
        corner[0].y = p1.y;
        corner[0].z = rot.y+m_shift[i].y;
        rot = Math::RotatePoint(Math::Point(p1.x, p1.z), a-Math::PI/2.0f, Math::Point(p.x, p.z));
        corner[1].x = rot.x+m_shift[i].x;
        corner[1].y = p1.y;
        corner[1].z = rot.y+m_shift[i].y;

        p = p2;
        p.x += m_width[i+1];
        rot = Math::RotatePoint(Math::Point(p2.x, p2.z), a+Math::PI/2.0f, Math::Point(p.x, p.z));
        corner[2].x = rot.x+m_shift[i+1].x;
        corner[2].y = p2.y;
        corner[2].z = rot.y+m_shift[i+1].y;
        rot = Math::RotatePoint(Math::Point(p2.x, p2.z), a-Math::PI/2.0f, Math::Point(p.x, p.z));
        corner[3].x = rot.x+m_shift[i+1].x;
        corner[3].y = p2.y;
        corner[3].z = rot.y+m_shift[i+1].y;

        if (p2.y < p1.y)
        {
            vertex[0] = Vertex(corner[1], n, Math::Point(texSup.x, texSup.y));
            vertex[1] = Vertex(corner[0], n, Math::Point(texInf.x, texSup.y));
            vertex[2] = Vertex(corner[3], n, Math::Point(texSup.x, texInf.y));
            vertex[3] = Vertex(corner[2], n, Math::Point(texInf.x, texInf.y));
        }
        else
        {
            vertex[0] = Vertex(corner[0], n, Math::Point(texSup.x, texSup.y));
            vertex[1] = Vertex(corner[1], n, Math::Point(texInf.x, texSup.y));
            vertex[2] = Vertex(corner[2], n, Math::Point(texSup.x, texInf.y));
            vertex[3] = Vertex(corner[3], n, Math::Point(texInf.x, texInf.y));
        }

        device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
        m_engine->AddStatisticTriangle(2);

        p1 = p2;
    }
}
Beispiel #4
0
void Render(Gfx::CGLDevice *device)
{
    device->BeginScene();

    /* Unlit part of scene */

    device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false);
    device->SetRenderState(Gfx::RENDER_STATE_CULLING, false); // Double-sided drawing

    Math::Matrix persp;
    Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.0f), 0.1f, 50.0f);
    device->SetTransform(Gfx::TRANSFORM_PROJECTION, persp);


    Math::Matrix viewMat;
    Math::Matrix mat;

    viewMat.LoadIdentity();

    Math::LoadRotationXMatrix(mat, -ROTATION.x);
    viewMat = Math::MultiplyMatrices(viewMat, mat);

    Math::LoadRotationYMatrix(mat, -ROTATION.y);
    viewMat = Math::MultiplyMatrices(viewMat, mat);

    Math::LoadTranslationMatrix(mat, -TRANSLATION);
    viewMat = Math::MultiplyMatrices(viewMat, mat);

    device->SetTransform(Gfx::TRANSFORM_VIEW, viewMat);

    Math::Matrix worldMat;
    worldMat.LoadIdentity();
    device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);

    Gfx::VertexCol line[2] = {};

    for (int x = -40; x <= 40; ++x)
    {
        line[0].color = Gfx::Color(0.7f + x / 120.0f, 0.0f, 0.0f);
        line[0].coord.z = -40;
        line[0].coord.x = x;
        line[1].color = Gfx::Color(0.7f + x / 120.0f, 0.0f, 0.0f);
        line[1].coord.z =  40;
        line[1].coord.x = x;
        device->DrawPrimitive(Gfx::PRIMITIVE_LINES, line, 2);
    }

    for (int z = -40; z <= 40; ++z)
    {
        line[0].color = Gfx::Color(0.0f, 0.7f + z / 120.0f, 0.0f);
        line[0].coord.z = z;
        line[0].coord.x = -40;
        line[1].color = Gfx::Color(0.0f, 0.7f + z / 120.0f, 0.0f);
        line[1].coord.z = z;
        line[1].coord.x =  40;
        device->DrawPrimitive(Gfx::PRIMITIVE_LINES, line, 2);
    }


    Gfx::VertexCol quad[6] = {};

    quad[0].coord = Math::Vector(-1.0f, -1.0f, 0.0f);
    quad[1].coord = Math::Vector( 1.0f, -1.0f, 0.0f);
    quad[2].coord = Math::Vector(-1.0f,  1.0f, 0.0f);
    quad[3].coord = Math::Vector( 1.0f,  1.0f, 0.0f);

    for (int i = 0; i < 6; ++i)
        quad[i].color = Gfx::Color(1.0f, 1.0f, 0.0f);

    Math::LoadTranslationMatrix(worldMat, Math::Vector(40.0f, 2.0f, 40.0f));
    device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);

    device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);

    for (int i = 0; i < 6; ++i)
        quad[i].color = Gfx::Color(0.0f, 1.0f, 1.0f);

    Math::LoadTranslationMatrix(worldMat, Math::Vector(-40.0f, 2.0f, -40.0f));
    device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);

    int planes = device->ComputeSphereVisibility(Math::Vector(0.0f, 0.0f, 0.0f), 1.0f);
    printf("Planes:");
    if (planes == 0)
        printf(" (none)");

    if (planes & Gfx::FRUSTUM_PLANE_LEFT)
        printf(" LEFT");

    if (planes & Gfx::FRUSTUM_PLANE_RIGHT)
        printf(" RIGHT");

    if (planes & Gfx::FRUSTUM_PLANE_BOTTOM)
        printf(" BOTTOM");

    if (planes & Gfx::FRUSTUM_PLANE_TOP)
        printf(" TOP");

    if (planes & Gfx::FRUSTUM_PLANE_FRONT)
        printf(" FRONT");

    if (planes & Gfx::FRUSTUM_PLANE_BACK)
        printf(" BACK");

    printf("\n");

    device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);

    for (int i = 0; i < 6; ++i)
        quad[i].color = Gfx::Color(1.0f, 0.0f, 1.0f);

    Math::LoadTranslationMatrix(worldMat, Math::Vector(10.0f, 4.5f, 5.0f));
    device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);

    device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);

    /* Moving lit cube */
    device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, true);
    device->SetRenderState(Gfx::RENDER_STATE_CULLING, true); // Culling (CCW faces)

    device->SetGlobalAmbient(Gfx::Color(0.4f, 0.4f, 0.4f));

    Gfx::Light light1;
    light1.type = Gfx::LIGHT_POINT;
    light1.position = Math::Vector(10.0f, 4.5f, 5.0f);
    light1.ambient = Gfx::Color(0.2f, 0.2f, 0.2f);
    light1.diffuse = Gfx::Color(1.0f, 0.1f, 0.1f);
    light1.specular = Gfx::Color(0.0f, 0.0f, 0.0f);
    device->SetLight(0, light1);
    device->SetLightEnabled(0, true);

    /*Gfx::Light light2;
    device->SetLight(1, light2);
    device->SetLightEnabled(1, true);*/

    Gfx::Material material;
    material.ambient = Gfx::Color(0.3f, 0.3f, 0.3f);
    material.diffuse = Gfx::Color(0.8f, 0.7f, 0.6f);
    material.specular = Gfx::Color(0.0f, 0.0f, 0.0f);
    device->SetMaterial(material);

    const Gfx::Vertex cube[6][4] =
    {
        {
            // Front
            Gfx::Vertex(Math::Vector(-1.0f, -1.0f, -1.0f), Math::Vector( 0.0f,  0.0f, -1.0f)),
            Gfx::Vertex(Math::Vector( 1.0f, -1.0f, -1.0f), Math::Vector( 0.0f,  0.0f, -1.0f)),
            Gfx::Vertex(Math::Vector(-1.0f,  1.0f, -1.0f), Math::Vector( 0.0f,  0.0f, -1.0f)),
            Gfx::Vertex(Math::Vector( 1.0f,  1.0f, -1.0f), Math::Vector( 0.0f,  0.0f, -1.0f))
        },

        {
            // Back
            Gfx::Vertex(Math::Vector( 1.0f, -1.0f,  1.0f), Math::Vector( 0.0f,  0.0f,  1.0f)),
            Gfx::Vertex(Math::Vector(-1.0f, -1.0f,  1.0f), Math::Vector( 0.0f,  0.0f,  1.0f)),
            Gfx::Vertex(Math::Vector( 1.0f,  1.0f,  1.0f), Math::Vector( 0.0f,  0.0f,  1.0f)),
            Gfx::Vertex(Math::Vector(-1.0f,  1.0f,  1.0f), Math::Vector( 0.0f,  0.0f,  1.0f))
        },

        {
            // Top
            Gfx::Vertex(Math::Vector(-1.0f,  1.0f, -1.0f), Math::Vector( 0.0f,  1.0f,  0.0f)),
            Gfx::Vertex(Math::Vector( 1.0f,  1.0f, -1.0f), Math::Vector( 0.0f,  1.0f,  0.0f)),
            Gfx::Vertex(Math::Vector(-1.0f,  1.0f,  1.0f), Math::Vector( 0.0f,  1.0f,  0.0f)),
            Gfx::Vertex(Math::Vector( 1.0f,  1.0f,  1.0f), Math::Vector( 0.0f,  1.0f,  0.0f))
        },

        {
            // Bottom
            Gfx::Vertex(Math::Vector(-1.0f, -1.0f,  1.0f), Math::Vector( 0.0f, -1.0f,  0.0f)),
            Gfx::Vertex(Math::Vector( 1.0f, -1.0f,  1.0f), Math::Vector( 0.0f, -1.0f,  0.0f)),
            Gfx::Vertex(Math::Vector(-1.0f, -1.0f, -1.0f), Math::Vector( 0.0f, -1.0f,  0.0f)),
            Gfx::Vertex(Math::Vector( 1.0f, -1.0f, -1.0f), Math::Vector( 0.0f, -1.0f,  0.0f))
        },

        {
            // Left
            Gfx::Vertex(Math::Vector(-1.0f, -1.0f,  1.0f), Math::Vector(-1.0f,  0.0f,  0.0f)),
            Gfx::Vertex(Math::Vector(-1.0f, -1.0f, -1.0f), Math::Vector(-1.0f,  0.0f,  0.0f)),
            Gfx::Vertex(Math::Vector(-1.0f,  1.0f,  1.0f), Math::Vector(-1.0f,  0.0f,  0.0f)),
            Gfx::Vertex(Math::Vector(-1.0f,  1.0f, -1.0f), Math::Vector(-1.0f,  0.0f,  0.0f))
        },

        {
            // Right
            Gfx::Vertex(Math::Vector( 1.0f, -1.0f, -1.0f), Math::Vector( 1.0f,  0.0f,  0.0f)),
            Gfx::Vertex(Math::Vector( 1.0f, -1.0f,  1.0f), Math::Vector( 1.0f,  0.0f,  0.0f)),
            Gfx::Vertex(Math::Vector( 1.0f,  1.0f, -1.0f), Math::Vector( 1.0f,  0.0f,  0.0f)),
            Gfx::Vertex(Math::Vector( 1.0f,  1.0f,  1.0f), Math::Vector( 1.0f,  0.0f,  0.0f))
        }
    };

    Math::Matrix cubeTrans;
    Math::LoadTranslationMatrix(cubeTrans, Math::Vector(10.0f, 2.0f, 5.0f));
    Math::Matrix cubeRot;
    Math::LoadRotationMatrix(cubeRot, Math::Vector(0.0f, 1.0f, 0.0f), CUBE_ORBIT);
    Math::Matrix cubeRotInv;
    Math::LoadRotationMatrix(cubeRotInv, Math::Vector(0.0f, 1.0f, 0.0f), -CUBE_ORBIT);
    Math::Matrix cubeTransRad;
    Math::LoadTranslationMatrix(cubeTransRad, Math::Vector(0.0f, 0.0f, 6.0f));
    worldMat = Math::MultiplyMatrices(cubeTransRad, cubeRotInv);
    worldMat = Math::MultiplyMatrices(cubeRot, worldMat);
    worldMat = Math::MultiplyMatrices(cubeTrans, worldMat);
    device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);

    for (int i = 0; i < 6; ++i)
        device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, cube[i], 4);

    device->EndScene();
}
void Render(Gfx::CGLDevice *device)
{
    device->BeginScene();

    Math::Matrix persp;
    Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.0f), 0.1f, 100.0f);
    device->SetTransform(Gfx::TRANSFORM_PROJECTION, persp);


    Math::Matrix viewMat;
    Math::Matrix mat;

    viewMat.LoadIdentity();

    Math::LoadRotationXMatrix(mat, -ROTATION.x);
    viewMat = Math::MultiplyMatrices(viewMat, mat);

    Math::LoadRotationYMatrix(mat, -ROTATION.y);
    viewMat = Math::MultiplyMatrices(viewMat, mat);

    Math::LoadTranslationMatrix(mat, -TRANSLATION);
    viewMat = Math::MultiplyMatrices(viewMat, mat);

    device->SetTransform(Gfx::TRANSFORM_VIEW, viewMat);


    Math::Matrix worldMat;
    worldMat.LoadIdentity();
    device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);

    Gfx::VertexCol line[2] = { Gfx::VertexCol() };

    for (int x = -40; x <= 40; ++x)
    {
        line[0].color = Gfx::Color(0.7f + x / 120.0f, 0.0f, 0.0f);
        line[0].coord.z = -40;
        line[0].coord.x = x;
        line[1].color = Gfx::Color(0.7f + x / 120.0f, 0.0f, 0.0f);
        line[1].coord.z =  40;
        line[1].coord.x = x;
        device->DrawPrimitive(Gfx::PRIMITIVE_LINES, line, 2);
    }

    for (int z = -40; z <= 40; ++z)
    {
        line[0].color = Gfx::Color(0.0f, 0.7f + z / 120.0f, 0.0f);
        line[0].coord.z = z;
        line[0].coord.x = -40;
        line[1].color = Gfx::Color(0.0f, 0.7f + z / 120.0f, 0.0f);
        line[1].coord.z = z;
        line[1].coord.x =  40;
        device->DrawPrimitive(Gfx::PRIMITIVE_LINES, line, 2);
    }


    Gfx::VertexCol quad[6] = { Gfx::VertexCol() };

    for (int i = 0; i < 6; ++i)
        quad[i].color = Gfx::Color(1.0f, 1.0f, 0.0f);

    quad[0].coord = Math::Vector(-1.0f, -1.0f, 0.0f);
    quad[1].coord = Math::Vector( 1.0f, -1.0f, 0.0f);
    quad[2].coord = Math::Vector( 1.0f,  1.0f, 0.0f);
    quad[3].coord = Math::Vector( 1.0f,  1.0f, 0.0f);
    quad[4].coord = Math::Vector(-1.0f,  1.0f, 0.0f);
    quad[5].coord = Math::Vector(-1.0f, -1.0f, 0.0f);

    Math::LoadTranslationMatrix(worldMat, Math::Vector(40.0f, 2.0f, 40.0f));
    device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);

    device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);

    for (int i = 0; i < 6; ++i)
        quad[i].color = Gfx::Color(0.0f, 1.0f, 1.0f);

    Math::LoadTranslationMatrix(worldMat, Math::Vector(-40.0f, 2.0f, -40.0f));
    device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);

    device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);

    for (int i = 0; i < 6; ++i)
        quad[i].color = Gfx::Color(1.0f, 0.0f, 1.0f);

    Math::LoadTranslationMatrix(worldMat, Math::Vector(0.0f, 10.0f, 0.0f));
    device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat);

    device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);

    device->EndScene();
}
void Render(Gfx::CGLDevice *device)
{
    device->BeginScene();

    Math::Matrix ortho;
    Math::LoadOrthoProjectionMatrix(ortho, -10, 10, -10, 10);
    device->SetTransform(Gfx::TRANSFORM_PROJECTION, ortho);

    Math::Matrix id;
    id.LoadIdentity();

    device->SetTransform(Gfx::TRANSFORM_WORLD, id);
    device->SetTransform(Gfx::TRANSFORM_VIEW, id);

    static Gfx::VertexTex2 quad[] =
    {
        Gfx::VertexTex2(Math::Vector(-2.0f,  2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 0.0f), Math::Point(0.0f, 0.0f)),
        Gfx::VertexTex2(Math::Vector( 2.0f,  2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 0.0f), Math::Point(1.0f, 0.0f)),
        Gfx::VertexTex2(Math::Vector( 2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 1.0f), Math::Point(1.0f, 1.0f)),

        Gfx::VertexTex2(Math::Vector( 2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 1.0f), Math::Point(1.0f, 1.0f)),
        Gfx::VertexTex2(Math::Vector(-2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 1.0f), Math::Point(0.0f, 1.0f)),
        Gfx::VertexTex2(Math::Vector(-2.0f,  2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 0.0f), Math::Point(0.0f, 0.0f)),
    };

    Gfx::TextureStageParams tex1StageParams;
    tex1StageParams.colorOperation = Gfx::TEX_MIX_OPER_DEFAULT;
    tex1StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT;
    device->SetTextureStageParams(0, tex1StageParams);

    Gfx::TextureStageParams tex2StageParams;
    tex2StageParams.colorOperation = Gfx::TEX_MIX_OPER_DEFAULT;
    tex2StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT;
    device->SetTextureStageParams(1, tex2StageParams);

    Math::Matrix t;
    Math::LoadTranslationMatrix(t, Math::Vector(-4.0f, 4.0f, 0.0f));
    device->SetTransform(Gfx::TRANSFORM_VIEW, t);

    device->SetTextureEnabled(0, true);
    device->SetTextureEnabled(1, false);

    device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);

    Math::LoadTranslationMatrix(t, Math::Vector( 4.0f, 4.0f, 0.0f));
    device->SetTransform(Gfx::TRANSFORM_VIEW, t);

    device->SetTextureEnabled(0, false);
    device->SetTextureEnabled(1, true);

    device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);

    Math::LoadTranslationMatrix(t, Math::Vector( 0.0f, -4.0f, 0.0f));
    device->SetTransform(Gfx::TRANSFORM_VIEW, t);

    device->SetTextureEnabled(0, true);
    device->SetTextureEnabled(1, true);

    tex1StageParams.colorOperation = Gfx::TEX_MIX_OPER_DEFAULT;
    tex1StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT;
    device->SetTextureStageParams(0, tex1StageParams);

    tex2StageParams.colorOperation = Gfx::TEX_MIX_OPER_ADD;
    tex2StageParams.colorArg1 = Gfx::TEX_MIX_ARG_COMPUTED_COLOR;
    tex2StageParams.colorArg2 = Gfx::TEX_MIX_ARG_TEXTURE;
    tex2StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT;
    device->SetTextureStageParams(1, tex2StageParams);

    device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6);

    device->EndScene();
}