@@ -82,6 +82,7 @@ liblolcore_sources = \ | |||
generated/easymesh-scanner.cpp \ | |||
\ | |||
base/assert.cpp base/hash.cpp base/log.cpp base/string.cpp \ | |||
base/enum.cpp \ | |||
\ | |||
math/vector.cpp math/real.cpp math/half.cpp math/trig.cpp \ | |||
math/constants.cpp math/geometry.cpp \ | |||
@@ -107,7 +108,7 @@ liblolcore_sources = \ | |||
mesh/primitive.cpp mesh/primitive.h \ | |||
\ | |||
sys/init.cpp sys/timer.cpp sys/file.cpp \ | |||
sys/threadbase.h \ | |||
sys/thread.cpp sys/threadbase.h \ | |||
\ | |||
image/image.cpp image/image-private.h \ | |||
image/codec/gdiplus-image.cpp \ | |||
@@ -0,0 +1,65 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// | |||
#if defined HAVE_CONFIG_H | |||
# include "config.h" | |||
#endif | |||
#include "core.h" | |||
namespace lol | |||
{ | |||
/* | |||
* Safe enum helpers | |||
*/ | |||
Map<int64_t, String> BuildEnumMap(char const *str) | |||
{ | |||
Map<int64_t, String> ret; | |||
char const *parser = str; | |||
int64_t next_value = 0; | |||
for (;;) | |||
{ | |||
/* Find name */ | |||
while (*parser == ' ' || *parser == ',') | |||
++parser; | |||
if (!*parser) | |||
break; | |||
/* Parse name */ | |||
char const *name = parser; | |||
while (*parser && *parser != ' ' && *parser != ',' && *parser != '=') | |||
++parser; | |||
char const *name_end = parser; | |||
/* Find the value (if any) */ | |||
uint64_t current_value = next_value; | |||
while (*parser == ' ' || *parser == '=') | |||
++parser; | |||
if (*parser && *parser != ',') | |||
{ | |||
current_value = strtoll(parser, nullptr, 0); | |||
while (*parser && *parser != ' ' && *parser != ',') | |||
++parser; | |||
} | |||
/* Store in the map */ | |||
ret[current_value] = String(name, (int)(name_end - name)); | |||
next_value = current_value + 1; | |||
} | |||
return ret; | |||
} | |||
} /* namespace lol */ | |||
@@ -26,42 +26,27 @@ namespace lol | |||
{ | |||
/* A safe enum for MeshCSG operations. */ | |||
struct CSGUsageDef | |||
{ | |||
enum Type | |||
{ | |||
Union, | |||
Substract, | |||
SubstractLoss, //will remove B from A, but not add inverted B | |||
And, | |||
Xor, | |||
}; | |||
}; | |||
typedef SafeEnum<CSGUsageDef> CSGUsage; | |||
LOL_SAFE_ENUM(CSGUsage, | |||
Union, | |||
Substract, | |||
SubstractLoss, // will remove B from A, but not add inverted B | |||
And, | |||
Xor | |||
); | |||
struct AxisDef | |||
{ | |||
enum Type | |||
{ | |||
X, | |||
Y, | |||
Z, | |||
}; | |||
}; | |||
typedef SafeEnum<AxisDef> Axis; | |||
LOL_SAFE_ENUM(Axis, | |||
X, | |||
Y, | |||
Z | |||
); | |||
struct MeshTransformDef | |||
{ | |||
enum Type | |||
{ | |||
Taper, | |||
Twist, | |||
Bend, | |||
Stretch, | |||
Shear, | |||
}; | |||
}; | |||
typedef SafeEnum<MeshTransformDef> MeshTransform; | |||
LOL_SAFE_ENUM(MeshTransform, | |||
Taper, | |||
Twist, | |||
Bend, | |||
Stretch, | |||
Shear | |||
); | |||
class EasyMesh | |||
{ | |||
@@ -86,25 +86,21 @@ struct EasyMeshCmdType | |||
LOL_DECLARE_ENUM_METHODS(EasyMeshCmdType) | |||
}; | |||
struct MeshTypeDef | |||
{ | |||
enum Type | |||
{ | |||
Triangle, | |||
Quad, | |||
Box, | |||
Sphere, | |||
Capsule, | |||
Torus, | |||
Cylinder, | |||
Disc, | |||
Star, | |||
ExpandedStar, | |||
Cog, | |||
MAX, | |||
}; | |||
}; | |||
typedef SafeEnum<MeshTypeDef> MeshType; | |||
LOL_SAFE_ENUM(MeshType, | |||
Triangle, | |||
Quad, | |||
Box, | |||
Sphere, | |||
Capsule, | |||
Torus, | |||
Cylinder, | |||
Disc, | |||
Star, | |||
ExpandedStar, | |||
Cog, | |||
MAX | |||
); | |||
struct TexCoordBuildType | |||
{ | |||
@@ -128,33 +124,24 @@ struct TexCoordBuildType | |||
LOL_DECLARE_ENUM_METHODS(TexCoordBuildType) | |||
}; | |||
struct MeshFaceTypeDef | |||
{ | |||
enum Type | |||
{ | |||
BoxFront = 0, | |||
QuadDefault = 0, | |||
BoxLeft = 1, | |||
BoxBack = 2, | |||
BoxRight = 3, | |||
BoxTop = 4, | |||
BoxBottom = 5, | |||
Max, | |||
}; | |||
}; | |||
typedef SafeEnum<MeshFaceTypeDef> MeshFaceType; | |||
struct TexCoordPosDef | |||
{ | |||
enum Type | |||
{ | |||
BL, //BottomLeft | |||
BR, //BottomRight | |||
TL, //TopLeft | |||
TR, //TopRight | |||
}; | |||
}; | |||
typedef SafeEnum<TexCoordPosDef> TexCoordPos; | |||
LOL_SAFE_ENUM(MeshFaceType, | |||
BoxFront = 0, | |||
QuadDefault = 0, | |||
BoxLeft = 1, | |||
BoxBack = 2, | |||
BoxRight = 3, | |||
BoxTop = 4, | |||
BoxBottom = 5, | |||
Max | |||
); | |||
LOL_SAFE_ENUM(TexCoordPos, | |||
BL, // Bottom Left | |||
BR, // Bottom Right | |||
TL, // Top Left | |||
TR // Top Right | |||
); | |||
class EasyMeshBuildData | |||
{ | |||
@@ -227,14 +214,14 @@ public: | |||
mt = mt; | |||
else if (mt == MeshType::Quad) | |||
{ | |||
//There's nothin' else than QuadDefault | |||
// There's nothin' else than QuadDefault | |||
BL = vec2(0.f); | |||
TR = vec2(1.f); | |||
} | |||
else if (mt == MeshType::Box) | |||
{ | |||
vec2 data[][2] = | |||
{ //TexCoordBuildType::BoxDefault | |||
{ // TexCoordBuildType::BoxDefault | |||
{ vec2(0.f), vec2(.5f) }, | |||
{ vec2(.5f, 0.f), vec2(1.f, .5f) }, | |||
{ vec2(0.f), vec2(.5f) }, | |||
@@ -242,8 +229,8 @@ public: | |||
{ vec2(0.f, .5f), vec2(.5f, 1.f) }, | |||
{ vec2(.5f, .5f), vec2(1.f, 1.f) } | |||
}; | |||
BL = data[face.ToScalar()][0]; //[tcbt] | |||
TR = data[face.ToScalar()][1]; //[tcbt] | |||
BL = data[face.ToScalar()][0]; // [tcbt] | |||
TR = data[face.ToScalar()][1]; // [tcbt] | |||
} | |||
else if (mt == MeshType::Sphere) | |||
mt = mt; | |||
@@ -276,7 +263,7 @@ public: | |||
return res * m_texcoord_scale + m_texcoord_offset2; | |||
} | |||
//UV2 | |||
// UV2 | |||
void SetTexCoordBuildType2(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type2[mt.ToScalar()] = (1 << (tcbt + 1)) | (m_texcoord_build_type2[mt.ToScalar()] & 1); } | |||
TexCoordBuildType GetTexCoordBuildType2(MeshType mt) | |||
{ | |||
@@ -313,14 +300,14 @@ public: | |||
mt = mt; | |||
else if (mt == MeshType::Quad) | |||
{ | |||
//There's nothin' else than QuadDefault | |||
// There's nothin' else than QuadDefault | |||
BL = vec2(0.f); | |||
TR = vec2(1.f); | |||
} | |||
else if (mt == MeshType::Box) | |||
{ | |||
vec2 data[][2] = | |||
{ //TexCoordBuildType::BoxDefault | |||
{ // TexCoordBuildType::BoxDefault | |||
{ vec2(0.f), vec2(.5f) }, | |||
{ vec2(.5f, 0.f), vec2(1.f, .5f) }, | |||
{ vec2(0.f), vec2(.5f) }, | |||
@@ -328,8 +315,8 @@ public: | |||
{ vec2(0.f, .5f), vec2(.5f, 1.f) }, | |||
{ vec2(.5f, .5f), vec2(1.f, 1.f) } | |||
}; | |||
BL = data[face.ToScalar()][0]; //[tcbt] | |||
TR = data[face.ToScalar()][1]; //[tcbt] | |||
BL = data[face.ToScalar()][0]; // [tcbt] | |||
TR = data[face.ToScalar()][1]; // [tcbt] | |||
} | |||
else if (mt == MeshType::Sphere) | |||
mt = mt; | |||
@@ -211,8 +211,7 @@ void GpuEasyMeshData::AddGpuData(GpuShaderData* gpudata, EasyMesh* src_mesh) | |||
BUILD_VFLAG(has_color, VertexUsage::Color, vflags); | |||
BUILD_VFLAG(has_texcoord, VertexUsage::TexCoord, vflags); | |||
BUILD_VFLAG_OR(has_texcoord, VertexUsage::TexCoordExt, vflags); | |||
ASSERT(!vflags, "Vertex Usage setup is not implemented for %s, feel free to do so.", | |||
VertexUsage::GetNameList(vflags).C()); | |||
ASSERT(!vflags, "no Vertex Usage setup for 0x%04x", vflags); | |||
if (has_position) gpudata->AddAttribute(VertexUsage::Position, 0); | |||
if (has_normal) gpudata->AddAttribute(VertexUsage::Normal, 0); | |||
@@ -280,8 +279,7 @@ void GpuEasyMeshData::SetupVertexData(uint16_t vflags, EasyMesh* src_mesh) | |||
BUILD_VFLAG_COUNT(has_color, VertexUsage::Color, saveflags, flagnb); | |||
BUILD_VFLAG_COUNT(has_texcoord, VertexUsage::TexCoord, saveflags, flagnb); | |||
BUILD_VFLAG_COUNT(has_texcoordExt,VertexUsage::TexCoordExt, saveflags, flagnb); | |||
ASSERT(!saveflags, "Vertex Declaration setup is not implemented for %s, feel free to do so.", | |||
VertexUsage::GetNameList(vflags).C()); | |||
ASSERT(!saveflags, "no Vertex Declaration setup for 0x%04x", vflags); | |||
if (flagnb == 5 && has_position && has_normal && has_color && has_texcoord && has_texcoordExt) | |||
{ | |||
@@ -369,8 +367,7 @@ void GpuEasyMeshData::SetupVertexData(uint16_t vflags, EasyMesh* src_mesh) | |||
COPY_VBO; | |||
} | |||
else | |||
ASSERT(0, "Vertex Declaration combination is not implemented for %s, feel free to do so.", | |||
VertexUsage::GetNameList(vflags).C()); | |||
ASSERT(0, "no Vertex Declaration combination for 0x%04x", vflags); | |||
m_vdatas.Push(vflags, new_vdecl, new_vbo); | |||
} | |||
@@ -404,8 +401,7 @@ void GpuEasyMeshData::RenderMeshData(mat4 const &model, int render_mode) | |||
BUILD_VFLAG(has_color, VertexUsage::Color, vflags); | |||
BUILD_VFLAG(has_texcoord, VertexUsage::TexCoord, vflags); | |||
BUILD_VFLAG_OR(has_texcoord,VertexUsage::TexCoordExt, vflags); | |||
ASSERT(!vflags, "Vertex Stream setup is not implemented for %s, feel free to do so.", | |||
VertexUsage::GetNameList(vflags).C()); | |||
ASSERT(!vflags, "no Vertex Stream setup for 0x%04x", vflags); | |||
int idx = 0; | |||
ShaderAttrib Attribs[4] = { lol::ShaderAttrib(), lol::ShaderAttrib(), lol::ShaderAttrib(), lol::ShaderAttrib() }; | |||
@@ -21,18 +21,13 @@ | |||
namespace lol | |||
{ | |||
//Utility enum for renderers | |||
struct MeshRenderDef | |||
{ | |||
enum Type | |||
{ | |||
NeedData, | |||
NeedConvert, | |||
CanRender, | |||
IgnoreRender, | |||
}; | |||
}; | |||
typedef SafeEnum<MeshRenderDef> MeshRender; | |||
// Utility enum for renderers | |||
LOL_SAFE_ENUM(MeshRender, | |||
NeedData, | |||
NeedConvert, | |||
CanRender, | |||
IgnoreRender, | |||
); | |||
//Vertex datas for easymesh vertex list. | |||
//TODO : <COORD, NORM, COLOR, UV> | |||
@@ -391,7 +391,7 @@ Shader::Shader(char const *vert, char const *frag) | |||
String name(name_buffer); | |||
int index = -1; | |||
VertexUsage usage = VertexUsage::MAX; | |||
for (int j = 0; j < VertexUsage::MAX; ++j) | |||
for (int j = 0; j < (int)VertexUsage::MAX; ++j) | |||
{ | |||
if (name.StartsWith(attribute_names[j])) | |||
{ | |||
@@ -402,7 +402,7 @@ Shader::Shader(char const *vert, char const *frag) | |||
} | |||
} | |||
if ((int)usage == VertexUsage::MAX || index == -1) | |||
if (usage == VertexUsage::MAX || index == -1) | |||
{ | |||
Log::Error("unable to parse attribute semantic from name: %s", | |||
name_buffer); | |||
@@ -410,7 +410,7 @@ Shader::Shader(char const *vert, char const *frag) | |||
else | |||
{ | |||
GLint location = glGetAttribLocation(data->prog_id, name_buffer); | |||
uint64_t flags = (uint64_t)(uint16_t)usage << 16; | |||
uint64_t flags = (uint64_t)(uint16_t)usage.ToScalar() << 16; | |||
flags |= (uint64_t)(uint16_t)index; | |||
// TODO: this is here just in case. Remove this once everything has been correctly tested | |||
#ifdef _DEBUG | |||
@@ -440,7 +440,7 @@ int Shader::GetAttribCount() const | |||
ShaderAttrib Shader::GetAttribLocation(VertexUsage usage, int index) const | |||
{ | |||
ShaderAttrib ret; | |||
ret.m_flags = (uint64_t)(uint16_t)usage << 16; | |||
ret.m_flags = (uint64_t)(uint16_t)usage.ToScalar() << 16; | |||
ret.m_flags |= (uint64_t)(uint16_t)index; | |||
#if defined USE_D3D9 || defined _XBOX | |||
#elif !defined __CELLOS_LV2__ | |||
@@ -139,7 +139,7 @@ void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count) | |||
return; | |||
#if defined _XBOX || defined USE_D3D9 | |||
switch (type) | |||
switch (type.ToScalar()) | |||
{ | |||
case MeshPrimitive::Triangles: | |||
if (FAILED(m_data->m_dev->DrawPrimitive(D3DPT_TRIANGLELIST, | |||
@@ -169,7 +169,7 @@ void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count) | |||
} | |||
#else | |||
/* FIXME: this has nothing to do here! */ | |||
switch (type) | |||
switch (type.ToScalar()) | |||
{ | |||
case MeshPrimitive::Triangles: | |||
glDrawArrays(GL_TRIANGLES, skip, count); | |||
@@ -198,7 +198,7 @@ void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase, | |||
return; | |||
#if defined _XBOX || defined USE_D3D9 | |||
switch (type) | |||
switch (type.ToScalar()) | |||
{ | |||
case MeshPrimitive::Triangles: | |||
count = count / 3; | |||
@@ -231,7 +231,7 @@ void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase, | |||
} | |||
#else | |||
/* FIXME: this has nothing to do here! */ | |||
switch (type) | |||
switch (type.ToScalar()) | |||
{ | |||
case MeshPrimitive::Triangles: | |||
/* FIXME: ignores most of the arguments! */ | |||
@@ -330,7 +330,7 @@ void VertexDeclaration::SetStream(VertexBuffer *vb, ShaderAttrib attribs[]) | |||
/* Only the first item is required to know which stream this | |||
* is about; the rest of the information is stored in the | |||
* vertex declaration already. */ | |||
uint32_t usage = (attr1.m_flags >> 16) & 0xffff; | |||
VertexUsage usage = VertexUsage((attr1.m_flags >> 16) & 0xffff); | |||
uint32_t index = attr1.m_flags & 0xffff; | |||
/* Find the stream number */ | |||
@@ -362,15 +362,15 @@ void VertexDeclaration::SetStream(VertexBuffer *vb, ShaderAttrib attribs[]) | |||
glBindBuffer(GL_ARRAY_BUFFER, vb->m_data->m_vbo); | |||
for (int n = 0; n < 12 && attribs[n].m_flags != (uint64_t)0 - 1; n++) | |||
{ | |||
uint32_t reg = attribs[n].m_flags >> 32; | |||
uint32_t usage = (attribs[n].m_flags >> 16) & 0xffff; | |||
VertexUsage usage = VertexUsage((attribs[n].m_flags >> 16) & 0xffff); | |||
uint32_t index = attribs[n].m_flags & 0xffff; | |||
uint32_t reg = attribs[n].m_flags >> 32; | |||
# if !defined __CELLOS_LV2__ | |||
if (reg != 0xffffffff) | |||
glEnableVertexAttribArray((GLint)reg); | |||
# else | |||
switch (usage) | |||
switch (usage.ToScalar()) | |||
{ | |||
case VertexUsage::Position: | |||
glEnableClientState(GL_VERTEX_ARRAY); | |||
@@ -627,26 +627,26 @@ VertexStreamBase VertexDeclaration::GetStream(int index) const | |||
switch (m_streams[i].stream_type) | |||
{ | |||
#define LOL_TYPE(T) \ | |||
#define __T(T) \ | |||
case VertexStreamBase::Type##T: stream.AddStream<T>(n++, m_streams[i].usage); break; | |||
LOL_TYPE(void) | |||
LOL_TYPE(half) LOL_TYPE(f16vec2) LOL_TYPE(f16vec3) LOL_TYPE(f16vec4) | |||
LOL_TYPE(float) LOL_TYPE(vec2) LOL_TYPE(vec3) LOL_TYPE(vec4) | |||
LOL_TYPE(double) LOL_TYPE(dvec2) LOL_TYPE(dvec3) LOL_TYPE(dvec4) | |||
LOL_TYPE(int8_t) LOL_TYPE(i8vec2) LOL_TYPE(i8vec3) LOL_TYPE(i8vec4) | |||
LOL_TYPE(uint8_t) LOL_TYPE(u8vec2) LOL_TYPE(u8vec3) LOL_TYPE(u8vec4) | |||
LOL_TYPE(int16_t) LOL_TYPE(i16vec2) LOL_TYPE(i16vec3) LOL_TYPE(i16vec4) | |||
LOL_TYPE(uint16_t) LOL_TYPE(u16vec2) LOL_TYPE(u16vec3) LOL_TYPE(u16vec4) | |||
LOL_TYPE(int32_t) LOL_TYPE(ivec2) LOL_TYPE(ivec3) LOL_TYPE(ivec4) | |||
LOL_TYPE(uint32_t) LOL_TYPE(uvec2) LOL_TYPE(uvec3) LOL_TYPE(uvec4) | |||
#undef LOL_TYPE | |||
__T(void) | |||
__T(half) __T(f16vec2) __T(f16vec3) __T(f16vec4) | |||
__T(float) __T(vec2) __T(vec3) __T(vec4) | |||
__T(double) __T(dvec2) __T(dvec3) __T(dvec4) | |||
__T(int8_t) __T(i8vec2) __T(i8vec3) __T(i8vec4) | |||
__T(uint8_t) __T(u8vec2) __T(u8vec3) __T(u8vec4) | |||
__T(int16_t) __T(i16vec2) __T(i16vec3) __T(i16vec4) | |||
__T(uint16_t) __T(u16vec2) __T(u16vec3) __T(u16vec4) | |||
__T(int32_t) __T(ivec2) __T(ivec3) __T(ivec4) | |||
__T(uint32_t) __T(uvec2) __T(uvec3) __T(uvec4) | |||
#undef __T | |||
} | |||
++count; | |||
} | |||
while (count < 12) | |||
stream.AddStream<void>(count++, VertexStreamBase::Typevoid); | |||
stream.AddStream<void>(count++, VertexUsage::Position); | |||
return stream; | |||
} | |||
@@ -12,13 +12,13 @@ | |||
#define __LOL_BASE_ALL_H__ | |||
#include <lol/base/types.h> | |||
#include <lol/base/enum.h> | |||
#include <lol/base/log.h> | |||
#include <lol/base/assert.h> | |||
#include <lol/base/array.h> | |||
#include <lol/base/string.h> | |||
#include <lol/base/hash.h> | |||
#include <lol/base/map.h> | |||
#include <lol/base/enum.h> | |||
#endif // __LOL_BASE_ALL_H__ | |||
@@ -14,8 +14,10 @@ | |||
namespace lol | |||
{ | |||
template<typename DEF, typename T = typename DEF::Type> | |||
class SafeEnum : public DEF | |||
extern Map<int64_t, String> BuildEnumMap(char const *str); | |||
template<typename BASE, typename T = typename BASE::Type> | |||
class SafeEnum : public BASE | |||
{ | |||
typedef T Type; | |||
Type m_value; | |||
@@ -24,9 +26,27 @@ public: | |||
inline SafeEnum() : m_value() {} | |||
inline SafeEnum(Type v) : m_value(v) {} | |||
/* Allow conversion from/to int */ | |||
/* Allow conversion from int and to the underlying type */ | |||
inline explicit SafeEnum(int i) : m_value(T(i)) {} | |||
inline Type ToScalar() const { return m_value; } | |||
/* Convert to string description */ | |||
inline class String ToString() const | |||
{ | |||
/* FIXME: we all know this isn’t thread safe. But is it really | |||
* a big deal? */ | |||
static Map<int64_t, String> map; | |||
static bool ready = false; | |||
if (!ready) | |||
map = BuildEnumMap(BASE::GetDescription()); | |||
ready = true; | |||
if (map.HasKey((int64_t)m_value)) | |||
return map[(int64_t)m_value]; | |||
return "<invalid enum>"; | |||
} | |||
/* Safe comparisons between enums of the same type */ | |||
friend bool operator == (SafeEnum const &a, SafeEnum const &b) | |||
{ | |||
@@ -54,6 +74,15 @@ public: | |||
} | |||
}; | |||
#define LOL_SAFE_ENUM(name, ...) \ | |||
struct name ## Base \ | |||
{ \ | |||
enum Type {__VA_ARGS__}; \ | |||
protected: \ | |||
static inline char const *GetDescription() { return #__VA_ARGS__; } \ | |||
}; \ | |||
typedef SafeEnum<name ## Base> name; | |||
//-- STRUCT TEMPLATE: | |||
// enum E { | |||
// DEF_VALUE | |||
@@ -25,79 +25,24 @@ namespace lol | |||
* now there is only TexCoord and not TexCoord0 TexCoord1 etc. because | |||
* we can always reorganise the vertex declaration for the indices to | |||
* match. If the need arises these enums will be added. */ | |||
struct VertexUsage | |||
{ | |||
DEF_VALUE | |||
ADD_VALUE(Position) | |||
ADD_VALUE(BlendWeight) | |||
ADD_VALUE(BlendIndices) | |||
ADD_VALUE(Normal) | |||
ADD_VALUE(PointSize) | |||
ADD_VALUE(TexCoord) | |||
ADD_VALUE(TexCoordExt) | |||
ADD_VALUE(Tangent) | |||
ADD_VALUE(Binormal) | |||
ADD_VALUE(TessFactor) | |||
ADD_VALUE(PositionT) | |||
ADD_VALUE(Color) | |||
ADD_VALUE(Fog) | |||
ADD_VALUE(Depth) | |||
ADD_VALUE(Sample) | |||
END_E_VALUE | |||
DEF_TEXT | |||
ADD_TEXT(Position) | |||
ADD_TEXT(BlendWeight) | |||
ADD_TEXT(BlendIndices) | |||
ADD_TEXT(Normal) | |||
ADD_TEXT(PointSize) | |||
ADD_TEXT(TexCoord) | |||
ADD_TEXT(TexCoordExt) | |||
ADD_TEXT(Tangent) | |||
ADD_TEXT(Binormal) | |||
ADD_TEXT(TessFactor) | |||
ADD_TEXT(PositionT) | |||
ADD_TEXT(Color) | |||
ADD_TEXT(Fog) | |||
ADD_TEXT(Depth) | |||
ADD_TEXT(Sample) | |||
END_TEXT | |||
LOL_DECLARE_ENUM_METHODS(VertexUsage); | |||
private: | |||
static String GetName(Value v, bool use_simple) | |||
{ | |||
String tmp = String(""); | |||
if (!use_simple) tmp += "<"; | |||
tmp += VertexUsage(v).C(); | |||
if (!use_simple) tmp += ">"; | |||
return tmp; | |||
} | |||
public: | |||
static String GetName(Value v) | |||
{ | |||
return GetName(v, false); | |||
} | |||
static String GetNameList(uint32_t v) | |||
{ | |||
String tmp = String("<"); | |||
int nb = 0; | |||
for (int i = 0; i < MAX; ++i) | |||
{ | |||
if (v & (1<<i)) | |||
{ | |||
if (nb != 0) | |||
tmp += ", "; | |||
tmp += GetName(Value(i), true); | |||
++nb; | |||
} | |||
} | |||
return tmp + ">"; | |||
} | |||
}; | |||
LOL_SAFE_ENUM(VertexUsage, | |||
Position, | |||
BlendWeight, | |||
BlendIndices, | |||
Normal, | |||
PointSize, | |||
TexCoord, | |||
TexCoordExt, | |||
Tangent, | |||
Binormal, | |||
TessFactor, | |||
PositionT, | |||
Color, | |||
Fog, | |||
Depth, | |||
Sample, | |||
MAX, | |||
); | |||
struct ShaderUniform | |||
{ | |||
@@ -152,7 +97,7 @@ public: | |||
static void Destroy(Shader *shader); | |||
int GetAttribCount() const; | |||
ShaderAttrib GetAttribLocation(struct VertexUsage usage, int index) const; | |||
ShaderAttrib GetAttribLocation(VertexUsage usage, int index) const; | |||
ShaderUniform GetUniformLocation(char const *uni) const; | |||
void SetUniform(ShaderUniform const &uni, int i); | |||
@@ -40,21 +40,13 @@ private: | |||
/* A safe enum to indicate what kind of primitive to draw. Used in | |||
* VertexDeclaration::DrawElements() for instance. */ | |||
struct MeshPrimitive | |||
{ | |||
enum Value | |||
{ | |||
Triangles, | |||
TriangleStrips, | |||
TriangleFans, | |||
Points, | |||
Lines, | |||
} | |||
m_value; | |||
inline MeshPrimitive(Value v) : m_value(v) {} | |||
inline operator Value() { return m_value; } | |||
}; | |||
LOL_SAFE_ENUM(MeshPrimitive, | |||
Triangles, | |||
TriangleStrips, | |||
TriangleFans, | |||
Points, | |||
Lines, | |||
); | |||
class VertexStreamBase | |||
{ | |||
@@ -107,20 +99,20 @@ public: | |||
protected: | |||
#define LOL_TYPE(T) \ | |||
#define __T(T) \ | |||
static uint8_t GetType(T *x) { UNUSED(x); return Type##T; } | |||
LOL_TYPE(void) | |||
LOL_TYPE(half) LOL_TYPE(f16vec2) LOL_TYPE(f16vec3) LOL_TYPE(f16vec4) | |||
LOL_TYPE(float) LOL_TYPE(vec2) LOL_TYPE(vec3) LOL_TYPE(vec4) | |||
LOL_TYPE(double) LOL_TYPE(dvec2) LOL_TYPE(dvec3) LOL_TYPE(dvec4) | |||
LOL_TYPE(int8_t) LOL_TYPE(i8vec2) LOL_TYPE(i8vec3) LOL_TYPE(i8vec4) | |||
LOL_TYPE(uint8_t) LOL_TYPE(u8vec2) LOL_TYPE(u8vec3) LOL_TYPE(u8vec4) | |||
LOL_TYPE(int16_t) LOL_TYPE(i16vec2) LOL_TYPE(i16vec3) LOL_TYPE(i16vec4) | |||
LOL_TYPE(uint16_t) LOL_TYPE(u16vec2) LOL_TYPE(u16vec3) LOL_TYPE(u16vec4) | |||
LOL_TYPE(int32_t) LOL_TYPE(ivec2) LOL_TYPE(ivec3) LOL_TYPE(ivec4) | |||
LOL_TYPE(uint32_t) LOL_TYPE(uvec2) LOL_TYPE(uvec3) LOL_TYPE(uvec4) | |||
#undef LOL_TYPE | |||
__T(void) | |||
__T(half) __T(f16vec2) __T(f16vec3) __T(f16vec4) | |||
__T(float) __T(vec2) __T(vec3) __T(vec4) | |||
__T(double) __T(dvec2) __T(dvec3) __T(dvec4) | |||
__T(int8_t) __T(i8vec2) __T(i8vec3) __T(i8vec4) | |||
__T(uint8_t) __T(u8vec2) __T(u8vec3) __T(u8vec4) | |||
__T(int16_t) __T(i16vec2) __T(i16vec3) __T(i16vec4) | |||
__T(uint16_t) __T(u16vec2) __T(u16vec3) __T(u16vec4) | |||
__T(int32_t) __T(ivec2) __T(ivec3) __T(ivec4) | |||
__T(uint32_t) __T(uvec2) __T(uvec3) __T(uvec4) | |||
#undef __T | |||
template<typename T> inline void AddStream(int n, VertexUsage usage) | |||
{ | |||
@@ -132,7 +124,7 @@ protected: | |||
VertexStreamBase() {} | |||
private: | |||
struct { uint8_t stream_type, usage, size; } m_streams[12 + 1]; | |||
struct { uint8_t stream_type, size; VertexUsage usage; } m_streams[12 + 1]; | |||
static VertexStreamBase const Empty; | |||
}; | |||
@@ -226,7 +218,13 @@ private: | |||
void Initialize(); | |||
void AddStream(VertexStreamBase const &); | |||
struct { uint8_t stream_type, index, usage, size; int reg; } m_streams[12 + 1]; | |||
struct | |||
{ | |||
uint8_t stream_type, index, size; | |||
VertexUsage usage; | |||
int reg; | |||
} m_streams[12 + 1]; | |||
int m_count; | |||
private: | |||
@@ -21,28 +21,18 @@ | |||
namespace lol | |||
{ | |||
struct FileAccessDef | |||
{ | |||
enum Type | |||
{ | |||
Read = 0, | |||
Write, | |||
}; | |||
}; | |||
typedef SafeEnum<FileAccessDef> FileAccess; | |||
struct StreamTypeDef | |||
{ | |||
enum Type | |||
{ | |||
StdIn, | |||
StdOut, | |||
StdErr, | |||
File, | |||
FileBinary, | |||
}; | |||
}; | |||
typedef SafeEnum<StreamTypeDef> StreamType; | |||
LOL_SAFE_ENUM(FileAccess, | |||
Read = 0, | |||
Write | |||
); | |||
LOL_SAFE_ENUM(StreamType, | |||
StdIn, | |||
StdOut, | |||
StdErr, | |||
File, | |||
FileBinary | |||
); | |||
class File | |||
{ | |||
@@ -58,19 +58,14 @@ struct ThreadStatus | |||
LOL_DECLARE_ENUM_METHODS(ThreadStatus) | |||
}; | |||
struct ThreadJobTypeDef | |||
{ | |||
enum Type | |||
{ | |||
NONE, | |||
WORK_TODO, | |||
WORK_DONE, | |||
WORK_FAILED, | |||
WORK_FETCHED, | |||
THREAD_STOP, | |||
}; | |||
}; | |||
typedef SafeEnum<ThreadJobTypeDef> ThreadJobType; | |||
LOL_SAFE_ENUM(ThreadJobType, | |||
NONE, | |||
WORK_TODO, | |||
WORK_DONE, | |||
WORK_FAILED, | |||
WORK_FETCHED, | |||
THREAD_STOP | |||
); | |||
class ThreadJob | |||
{ | |||
@@ -106,6 +106,7 @@ | |||
<ClCompile Include="audio.cpp" /> | |||
<ClCompile Include="camera.cpp" /> | |||
<ClCompile Include="base\assert.cpp" /> | |||
<ClCompile Include="base\enum.cpp" /> | |||
<ClCompile Include="base\hash.cpp" /> | |||
<ClCompile Include="base\log.cpp" /> | |||
<ClCompile Include="base\string.cpp" /> | |||
@@ -285,6 +285,9 @@ | |||
<ClCompile Include="base\assert.cpp"> | |||
<Filter>base</Filter> | |||
</ClCompile> | |||
<ClCompile Include="base\enum.cpp"> | |||
<Filter>base</Filter> | |||
</ClCompile> | |||
<ClCompile Include="base\hash.cpp"> | |||
<Filter>base</Filter> | |||
</ClCompile> | |||
@@ -92,7 +92,8 @@ void SubMesh::Render(Shader* shader) | |||
for (int j = 0; j < stream.GetStreamCount(); ++j) | |||
{ | |||
VertexUsage usage = stream.GetUsage(j); | |||
attribs[j] = shader->GetAttribLocation(usage, indices[usage]++); | |||
int usage_index = usage.ToScalar(); | |||
attribs[j] = shader->GetAttribLocation(usage, indices[usage_index]++); | |||
} | |||
vertex_count = m_vbos[i]->GetSize() / m_vdecl->GetStream(i).GetSize(); | |||
@@ -20,7 +20,7 @@ testsuite_SOURCES = testsuite.cpp \ | |||
unit/build.cpp unit/real.cpp unit/image.cpp unit/quat.cpp unit/cmplx.cpp \ | |||
unit/array.cpp unit/rotation.cpp unit/string.cpp unit/map.cpp \ | |||
unit/color.cpp unit/atomic.cpp unit/interp.cpp unit/box.cpp \ | |||
unit/rand.cpp unit/thread.cpp unit/camera.cpp | |||
unit/rand.cpp unit/thread.cpp unit/camera.cpp unit/enum.cpp | |||
testsuite_CPPFLAGS = $(AM_CPPFLAGS) | |||
testsuite_DEPENDENCIES = @LOL_DEPS@ | |||
noinst_DATA = data/gradient.png | |||
@@ -50,6 +50,7 @@ | |||
<ClCompile Include="unit\camera.cpp" /> | |||
<ClCompile Include="unit\cmplx.cpp" /> | |||
<ClCompile Include="unit\color.cpp" /> | |||
<ClCompile Include="unit\enum.cpp" /> | |||
<ClCompile Include="unit\half.cpp" /> | |||
<ClCompile Include="unit\image.cpp" /> | |||
<ClCompile Include="unit\interp.cpp" /> | |||
@@ -0,0 +1,52 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// | |||
#if defined HAVE_CONFIG_H | |||
# include "config.h" | |||
#endif | |||
#include "core.h" | |||
#include "lol/unit.h" | |||
namespace lol | |||
{ | |||
LOLUNIT_FIXTURE(EnumTest) | |||
{ | |||
void SetUp() {} | |||
void TearDown() {} | |||
LOLUNIT_TEST(EnumToString) | |||
{ | |||
LOL_SAFE_ENUM(MyEnum, | |||
First = -10, | |||
Second, | |||
Third = 5, | |||
); | |||
MyEnum e = MyEnum::First; | |||
LOLUNIT_ASSERT(e.ToString() == "First"); | |||
e = MyEnum::Second; | |||
LOLUNIT_ASSERT(e.ToString() == "Second"); | |||
e = MyEnum::Third; | |||
LOLUNIT_ASSERT(e.ToString() == "Third"); | |||
e = MyEnum(42); | |||
LOLUNIT_ASSERT(e.ToString() != "First"); | |||
LOLUNIT_ASSERT(e.ToString() != "Second"); | |||
LOLUNIT_ASSERT(e.ToString() != "Third"); | |||
} | |||
}; | |||
} /* namespace lol */ | |||