view dmmodel.h @ 48:0ae1ff609626

Implement diffuse setting for models in scenefile. Also refactor parsing/handling of ambient/diffuse/specular values and unify it for both models and lights.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 06 Dec 2019 01:12:23 +0200
parents 73a785323e8a
children 8b335eb444ae
line wrap: on
line source

//
// GLDragon - OpenGL PLY model viewer / simple benchmark
// -- Scene and model handling + PLY file parsing
// 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.
//
#ifndef DMMODEL_H
#define DMMODEL_H 1

#include "dmutil.h"
#include <cstdint>
#include <fstream>
#include <unordered_map>


#define PLY_PROP_VERTEX_INDICES  "vertex_indices"
#define PLY_ELEM_FACE            "face"
#define PLY_ELEM_VERTEX          "vertex"


enum DMPLYFormat
{
    PLY_FMT_UNKNOWN,
    PLY_FMT_ASCII,
    PLY_FMT_BIN_LE,
    PLY_FMT_BIN_BE
};


enum DMPLYPropType
{
    PLY_TYPE_NONE,
    PLY_TYPE_LIST,

    PLY_TYPE_UINT8,
    PLY_TYPE_INT8,
    PLY_TYPE_INT16,
    PLY_TYPE_UINT16,
    PLY_TYPE_INT32,
    PLY_TYPE_UINT32,
    PLY_TYPE_FLOAT,
    PLY_TYPE_DOUBLE
};


/* Structures
 */
union DMPLYPropValue
{
    double v_double;
    float v_float;
    unsigned int v_uint;
    int v_int;
};


struct DMPLYFileProperty
{
    std::string name;
    DMPLYPropType
        type,
        list_num_type,
        list_values_type;

    DMPLYPropValue value, list_num_value;
    std::vector<DMPLYPropValue> list_values;
};


struct DMPLYFileElement
{
    int value;
    std::string name;

    std::unordered_map<std::string, DMPLYFileProperty> prop_map;
    std::vector<DMPLYFileProperty *> properties;

    DMPLYFileProperty *checkProp(const std::string &prop)
    {
        if (prop_map.count(prop))
            return &prop_map[prop];
        else
            return 0;
    }
};


struct DMTextFileInfo
{
    int nline, state;
    std::string filename;
    std::string line;
    std::ifstream file;
    std::string *key;
};


struct DMPLYFileInfo : DMTextFileInfo
{
    DMPLYFormat format;

    std::unordered_map<std::string, DMPLYFileElement> elem_map;
    std::vector<DMPLYFileElement *> elements;
    DMPLYFileElement *element;

    DMPLYFileInfo()
    {
        element = 0;
        format = PLY_FMT_UNKNOWN;
    }

    DMPLYFileElement *checkElem(const std::string &elem)
    {
        if (elem_map.count(elem))
            return &elem_map[elem];
        else
            return 0;
    }
};


struct DMVector3
{
    float x, y, z;
};


union DMVector4
{
    struct { float x, y, z, w; } p;
    struct { float r, g, b, a; } c;
    float values[4];
};


struct DMMaterial
{
    DMVector4 ambient, diffuse, specular;
    int shininess;
};


struct DMModel
{
    int nvertices, nfaces;
    std::vector<DMVector3> vertices, normals;
    std::vector<unsigned int> faces;

    DMMaterial material;
    DMVector3 translate, scale, rotate;
    bool translateSet, scaleSet, rotateSet;

    unsigned int id_prog, id_fs, id_vs;

    std::string
        modelFile,
        fragShaderFile, vertShaderFile,
        fragShaderStr, vertShaderStr;

    bool loadFromPLY(const std::string &filename);
    bool loadFromPLY(const std::string &filename, DMPLYFileInfo &info);

    DMModel()
    {
        nfaces = nvertices = 0;

        translate.x = translate.y = translate.z = 0;
        rotate.x = rotate.y = rotate.z = 0;
        scale.x = scale.y = scale.z = 0;
        translateSet = rotateSet = scaleSet = false;

        material.diffuse.c.r = material.diffuse.p.z = 0.56471f;
        material.diffuse.c.g = 0.5f;
        material.diffuse.c.a = 1.0f;

        material.specular.c.r = material.specular.c.g = material.specular.c.b = 0.8f;
        material.specular.c.a = 1.0f;

        material.shininess = 96;
    }
};


struct DMLight
{
    DMMaterial color;
    DMVector4 position, pointAt;

    DMLight()
    {
        color.ambient.c.r  = color.ambient.c.g  = color.ambient.p.z  = 0.2f; color.ambient.c.a  = 1.0f;
        color.diffuse.c.r  = color.diffuse.c.g  = color.diffuse.p.z  = 0.8f; color.diffuse.c.a  = 1.0f;
        color.specular.c.r = color.specular.c.g = color.specular.p.z = 0.5f; color.specular.c.a = 1.0f;

        position.p.x = 10.0f;
        position.p.y = 10.0f;
        position.p.z =  0.0f;
    }
};


struct DMCamera
{
    DMVector4 position, pointAt;
};


struct DMSimpleScene
{
    DMCamera camera;
    std::vector<DMLight> lights;
    std::vector<DMModel> models;

    bool loadInfo(const std::string &filename);
};

#endif