/** * Copyright (c) 2006-2020 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. **/ #pragma once // LOVE #include "common/int.h" #include "common/Color.h" #include "common/StringMap.h" // C #include #include #include namespace love { namespace graphics { class Resource; // Vertex attribute indices used in shaders by LOVE. The values map to GPU // generic vertex attribute indices. enum BuiltinVertexAttribute { ATTRIB_POS = 0, ATTRIB_TEXCOORD, ATTRIB_COLOR, ATTRIB_MAX_ENUM }; enum BuiltinVertexAttributeFlags { ATTRIBFLAG_POS = 1 << ATTRIB_POS, ATTRIBFLAG_TEXCOORD = 1 << ATTRIB_TEXCOORD, ATTRIBFLAG_COLOR = 1 << ATTRIB_COLOR, }; enum BufferType { BUFFERTYPE_VERTEX = 0, BUFFERTYPE_INDEX, BUFFERTYPE_MAX_ENUM }; enum IndexDataType { INDEX_UINT16, INDEX_UINT32, INDEX_MAX_ENUM }; // http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png enum PrimitiveType { PRIMITIVE_TRIANGLES, PRIMITIVE_TRIANGLE_STRIP, PRIMITIVE_TRIANGLE_FAN, PRIMITIVE_POINTS, PRIMITIVE_MAX_ENUM }; enum AttributeStep { STEP_PER_VERTEX, STEP_PER_INSTANCE, STEP_MAX_ENUM }; enum CullMode { CULL_NONE, CULL_BACK, CULL_FRONT, CULL_MAX_ENUM }; // The expected usage pattern of buffer data. enum BufferUsage { BUFFERUSAGE_STREAM, BUFFERUSAGE_DYNAMIC, BUFFERUSAGE_STATIC, BUFFERUSAGE_MAX_ENUM }; enum DataTypeDeprecated { DATADEPRECATED_UNORM8, DATADEPRECATED_UNORM16, DATADEPRECATED_FLOAT, DATADEPRECATED_MAX_ENUM }; // Value types used when interfacing with the GPU (vertex and shader data). // The order of this enum affects the dataFormatInfo array. enum DataFormat { DATAFORMAT_FLOAT, DATAFORMAT_FLOAT_VEC2, DATAFORMAT_FLOAT_VEC3, DATAFORMAT_FLOAT_VEC4, DATAFORMAT_FLOAT_MAT2X2, DATAFORMAT_FLOAT_MAT2X3, DATAFORMAT_FLOAT_MAT2X4, DATAFORMAT_FLOAT_MAT3X2, DATAFORMAT_FLOAT_MAT3X3, DATAFORMAT_FLOAT_MAT3X4, DATAFORMAT_FLOAT_MAT4X2, DATAFORMAT_FLOAT_MAT4X3, DATAFORMAT_FLOAT_MAT4X4, DATAFORMAT_INT32, DATAFORMAT_INT32_VEC2, DATAFORMAT_INT32_VEC3, DATAFORMAT_INT32_VEC4, DATAFORMAT_UINT32, DATAFORMAT_UINT32_VEC2, DATAFORMAT_UINT32_VEC3, DATAFORMAT_UINT32_VEC4, DATAFORMAT_SNORM8_VEC4, DATAFORMAT_UNORM8_VEC4, DATAFORMAT_INT8_VEC4, DATAFORMAT_UINT8_VEC4, DATAFORMAT_SNORM16_VEC2, DATAFORMAT_SNORM16_VEC4, DATAFORMAT_UNORM16_VEC2, DATAFORMAT_UNORM16_VEC4, DATAFORMAT_INT16_VEC2, DATAFORMAT_INT16_VEC4, DATAFORMAT_UINT16, DATAFORMAT_UINT16_VEC2, DATAFORMAT_UINT16_VEC4, DATAFORMAT_BOOL, DATAFORMAT_BOOL_VEC2, DATAFORMAT_BOOL_VEC3, DATAFORMAT_BOOL_VEC4, DATAFORMAT_MAX_ENUM }; enum DataBaseType { DATA_BASETYPE_FLOAT, DATA_BASETYPE_INT, DATA_BASETYPE_UINT, DATA_BASETYPE_SNORM, DATA_BASETYPE_UNORM, DATA_BASETYPE_BOOL, DATA_BASETYPE_MAX_ENUM }; enum Winding { WINDING_CW, WINDING_CCW, WINDING_MAX_ENUM }; enum TriangleIndexMode { TRIANGLEINDEX_NONE, TRIANGLEINDEX_STRIP, TRIANGLEINDEX_FAN, TRIANGLEINDEX_QUADS, }; enum class CommonFormat { NONE, XYf, XYZf, RGBAub, STf_RGBAub, STPf_RGBAub, XYf_STf, XYf_STPf, XYf_STf_RGBAub, XYf_STus_RGBAub, XYf_STPf_RGBAub, }; struct DataFormatInfo { DataBaseType baseType; bool isMatrix; int components; int matrixRows; int matrixColumns; size_t componentSize; size_t size; }; struct STf_RGBAub { float s, t; Color32 color; }; struct STPf_RGBAub { float s, t, p; Color32 color; }; struct XYf_STf { float x, y; float s, t; }; struct XYf_STPf { float x, y; float s, t, p; }; struct XYf_STf_RGBAub { float x, y; float s, t; Color32 color; }; typedef XYf_STf_RGBAub Vertex; struct XYf_STus_RGBAub { float x, y; uint16 s, t; Color32 color; }; struct XYf_STPf_RGBAub { float x, y; float s, t, p; Color32 color; }; struct BufferBindings { static const uint32 MAX = 32; uint32 useBits = 0; struct { Resource *buffer; size_t offset; } info[MAX]; void set(uint32 index, Resource *r, size_t offset) { useBits |= (1u << index); info[index] = {r, offset}; } void disable(uint32 index) { useBits &= (1u << index); } void clear() { useBits = 0; } }; struct VertexAttributeInfo { uint8 bufferIndex; DataFormat format : 8; uint16 offsetFromVertex; }; struct VertexBufferLayout { uint16 stride; }; struct VertexAttributes { static const uint32 MAX = 32; uint32 enableBits = 0; // indexed by attribute uint32 instanceBits = 0; // indexed by buffer VertexAttributeInfo attribs[MAX]; VertexBufferLayout bufferLayouts[BufferBindings::MAX]; VertexAttributes() {} VertexAttributes(CommonFormat format, uint8 bufferindex) { setCommonFormat(format, bufferindex); } void set(uint32 index, DataFormat format, uint16 offsetfromvertex, uint8 bufferindex) { enableBits |= (1u << index); attribs[index].bufferIndex = bufferindex; attribs[index].format = format; attribs[index].offsetFromVertex = offsetfromvertex; } void setBufferLayout(uint32 bufferindex, uint16 stride, AttributeStep step = STEP_PER_VERTEX) { uint32 bufferbit = (1u << bufferindex); if (step == STEP_PER_INSTANCE) instanceBits |= bufferbit; else instanceBits &= ~bufferbit; bufferLayouts[bufferindex].stride = stride; } void disable(uint32 index) { enableBits &= ~(1u << index); } void clear() { enableBits = 0; } bool isEnabled(uint32 index) const { return (enableBits & (1u << index)) != 0; } AttributeStep getBufferStep(uint32 index) const { return (instanceBits & (1u << index)) != 0 ? STEP_PER_INSTANCE : STEP_PER_VERTEX; } void setCommonFormat(CommonFormat format, uint8 bufferindex); }; size_t getFormatStride(CommonFormat format); uint32 getFormatFlags(CommonFormat format); int getFormatPositionComponents(CommonFormat format); inline CommonFormat getSinglePositionFormat(bool is2D) { return is2D ? CommonFormat::XYf : CommonFormat::XYZf; } const DataFormatInfo &getDataFormatInfo(DataFormat format); size_t getIndexDataSize(IndexDataType type); IndexDataType getIndexDataTypeFromMax(size_t maxvalue); DataFormat getIndexDataFormat(IndexDataType type); int getIndexCount(TriangleIndexMode mode, int vertexCount); void fillIndices(TriangleIndexMode mode, uint16 vertexStart, uint16 vertexCount, uint16 *indices); void fillIndices(TriangleIndexMode mode, uint32 vertexStart, uint32 vertexCount, uint32 *indices); DECLARE_STRINGMAP(BuiltinVertexAttribute); DECLARE_STRINGMAP(IndexDataType); DECLARE_STRINGMAP(BufferUsage); DECLARE_STRINGMAP(PrimitiveType); DECLARE_STRINGMAP(AttributeStep); DECLARE_STRINGMAP(DataTypeDeprecated); DECLARE_STRINGMAP(DataFormat); DECLARE_STRINGMAP(DataBaseType); DECLARE_STRINGMAP(CullMode); DECLARE_STRINGMAP(Winding); const char *getConstant(BuiltinVertexAttribute attrib); } // graphics } // love