view dmscene.cpp @ 107:2b30217a3c39 default tip

Fix verbose build echos.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 29 Feb 2024 21:48:47 +0200
parents 03aa729a9e90
children
line wrap: on
line source

//
// GLDragon - OpenGL PLY model viewer / simple benchmark
// -- Scene file handling
// Programmed and designed by Matti 'ccr' Hämäläinen <ccr@tnsp.org>
// (C) Copyright 2019 Tecnic Software productions (TNSP)
//
// See file "COPYING" for license information.
//
#include "dmscene.h"


bool dmParseVector(DMTextFileInfo &info, const std::vector<std::string> tokens, const size_t offs, DMVector3 &vec)
{
    if (tokens.size() == offs + 1)
    {
        vec.x = vec.y = vec.z = std::stof(tokens[offs]);
    }
    else
    if (tokens.size() == offs + 3)
    {
        vec.x = std::stof(tokens[offs]);
        vec.y = std::stof(tokens[offs + 1]);
        vec.z = std::stof(tokens[offs + 2]);
    }
    else
    {
        return info.syntaxError(
            "Expected 1/3 value vector for '"+ *info.key +"'");
    }

    return true;
}


bool dmParseVector(DMTextFileInfo &info, const std::vector<std::string> tokens, const size_t offs, DMVector4 &vec)
{
    if (tokens.size() == offs + 1)
    {
        vec.p.x = vec.p.y = vec.p.z = std::stof(tokens[offs]);
    }
    else
    if (tokens.size() == offs + 3 || tokens.size() == offs + 4)
    {
        vec.p.x = std::stof(tokens[offs]);
        vec.p.y = std::stof(tokens[offs + 1]);
        vec.p.z = std::stof(tokens[offs + 2]);

        if (tokens.size() == offs + 4)
            vec.p.w = std::stof(tokens[offs + 3]);
    }
    else
    {
        return info.syntaxError(
            "Expected 1/3/4 value vector for '"+ *info.key +"'");
    }

    return true;
}


bool DMSimpleScene::loadInfo(const std::string &filename)
{
    DMTextFileInfo info;
    DMModel *model = 0;
    DMLight *light = 0;
    DMVector4 *ppos = 0, *ppointAt = 0;
    DMMaterial *pmat = 0;

    info.filename = filename;
    info.nline = info.state = 0;
    info.file.open(info.filename.c_str(), std::fstream::in | std::fstream::binary);

    dmMsg("Trying to read scene data from '%s'.\n",
        info.filename.c_str());

    if (!info.file.is_open())
    {
        dmError("Unable to open file '%s'.\n",
            info.filename.c_str());
        return false;
    }

    while (info.state >= 0)
    {
        // Read one line
        if (!info.readLine())
        {
            info.state = -1;
            break;
        }

        // Skip empty lines and comments
        if (info.line.empty() ||
            info.line[0] == '#' ||
            info.line[0] == ';')
            continue;

        // Split key and values
        std::vector<std::string> tokens = dmStrSplit(info.line);
        std::string key = tokens[0];
        info.key = &key;

        if (key == "model")
        {
            DMModel newmodel;
            if (tokens.size() != 2)
            {
                return info.syntaxError(
                    "Keyword model expects a filename argument");
            }

            models.push_back(newmodel);
            model = &models.back();
            model->modelFile = tokens[1];
            pmat = &model->material;
            info.state = 1;
        }
        else
        if (info.state == 1 && (key == "shaderfile"))
        {
            if (tokens.size() != 3)
            {
                return info.syntaxError(
                    "Keyword shaderfile expects shader type (fs, vs) and filename arguments");
            }

            std::string
                &shtype = tokens[1],
                &shfile = tokens[2];

            if (shtype == "fs")
                model->fragShaderFile = shfile;
            else
            if (shtype == "vs")
                model->vertShaderFile = shfile;
            else
            {
                return info.syntaxError(
                    "Invalid shaderfile type '"+ shtype +"'");
            }
        }
        else
        if (info.state == 1 && (key == "translate" || key == "rotate" || key == "scale"))
        {
            DMVector3 vec;

            if (!dmParseVector(info, tokens, 1, vec))
                return false;

            if (!model)
                return false;

            if (key == "translate")
            {
                model->translate = vec;
                model->translateSet = true;
            }
            else
            if (key == "rotate")
            {
                model->rotate = vec;
                model->rotateSet = true;
            }
            else
            if (key == "scale")
            {
                model->scale = vec;
                model->scaleSet = true;
            }
        }
        else
        if (info.state == 1 && key == "shininess")
        {
            if (tokens.size() != 2)
            {
                return info.syntaxError(
                    "Expected argument for shininess");
            }

            model->material.shininess = std::stoi(tokens[1], 0, 0);
        }
        else
        if (key == "light")
        {
            DMLight newlight;

            if (lights.size() >= 4)
            {
                return info.textError(
                "Too many lights defined (max 4)");
            }

            lights.push_back(newlight);
            light = &lights.back();
            ppos = &light->position;
            ppointAt = &light->pointAt;
            pmat = &light->color;
            info.state = 2;
        }
        else
        if ((info.state == 1 || info.state == 2) &&
            (key == "ambient" || key == "diffuse" || key == "specular"))
        {
            DMVector4 val;
            val.c.a = 1.0f;

            if (!dmParseVector(info, tokens, 1, val))
                return false;

            if (key == "ambient")
                pmat->ambient = val;
            else
            if (key == "diffuse")
                pmat->diffuse = val;
            else
            if (key == "specular")
                pmat->specular = val;
        }
        else
        if (key == "camera")
        {
            info.state = 3;

            ppos = &camera.position;
            ppointAt = &camera.pointAt;
        }
        else
        if ((info.state == 3 || info.state == 2) &&
            (key == "position" || key == "pos" || key == "point_at"))
        {
            DMVector4 vec;
            vec.p.w = 0;

            if (!dmParseVector(info, tokens, 1, vec))
                return false;

            if (key == "position" || key == "pos")
                *ppos = vec;
            else
            if (key == "point_at")
                *ppointAt = vec;
        }
        else
        {
            return info.syntaxError(
                "Unexpected key '"+ key +"'");
        }
    }

    return true;
}