Browse Source

LolImGui integration 2nd pass: It now works perfectly (to the extent of the api)

SDL2: Mouse is back ! With correct focus support
SDL2: Added typing support with keyboard
ShaderBuilder: Refactored and simplified Shader block creation
Several warning removal
Fixed Image::Copy
undefined
Benjamin ‘Touky’ Huet Sam Hocevar <sam@hocevar.net> 9 years ago
parent
commit
f139a7e164
20 changed files with 951 additions and 273 deletions
  1. +7
    -6
      doc/tutorial/08_fbo.cpp
  2. +47
    -42
      doc/tutorial/13_shader_builder.cpp
  3. +61
    -31
      src/gpu/shader.cpp
  4. +49
    -0
      src/image/color/color.cpp
  5. +1
    -1
      src/image/image.cpp
  6. +241
    -140
      src/imgui/lolimgui.cpp
  7. +130
    -0
      src/imgui/lolimgui.h
  8. +1
    -0
      src/input/controller.h
  9. +3
    -0
      src/input/input.h
  10. +1
    -1
      src/input/input_internal.h
  11. +5
    -0
      src/input/keys.h
  12. +1
    -0
      src/lol/base/enum.h
  13. +61
    -29
      src/lol/base/string.h
  14. +170
    -2
      src/lol/gpu/shader.h
  15. +16
    -0
      src/lol/image/color.h
  16. +1
    -0
      src/lol/sys/file.h
  17. +3
    -0
      src/lolcore.vcxproj
  18. +129
    -17
      src/platform/sdl/sdlinput.cpp
  19. +21
    -1
      src/sys/file.cpp
  20. +3
    -3
      src/sys/thread.cpp

+ 7
- 6
doc/tutorial/08_fbo.cpp View File

@@ -39,12 +39,13 @@ public:
WorldEntity::TickGame(seconds);

m_time += seconds;
m_hotspot = 0.4f * vec3(lol::sin(m_time * 4.f) + lol::cos(m_time * 5.3f),
lol::sin(m_time * 5.7f) + lol::cos(m_time * 4.4f),
lol::sin(m_time * 5.f));
m_color = 0.25f * vec3(1.1f + lol::sin(m_time * 2.5f + 1.f),
1.1f + lol::sin(m_time * 2.8f + 1.3f),
1.1f + lol::sin(m_time * 2.7f));
m_hotspot = 0.4f * vec3(
lol::sin((float)m_time * 4.f) + lol::cos((float)m_time * 5.3f),
lol::sin((float)m_time * 5.7f) + lol::cos((float)m_time * 4.4f),
lol::sin((float)m_time * 5.f));
m_color = 0.25f * vec3(1.1f + lol::sin((float)m_time * 2.5f + 1.f),
1.1f + lol::sin((float)m_time * 2.8f + 1.3f),
1.1f + lol::sin((float)m_time * 2.7f));
/* Saturate dot color */
float x = std::max(m_color.x, std::max(m_color.y, m_color.z));
m_color /= x;


+ 47
- 42
doc/tutorial/13_shader_builder.cpp View File

@@ -45,58 +45,63 @@ public:
ShaderBlock green_pixel("GreenPixel");
ShaderBlock blue_pixel("BluePixel");

String vertex_out = Shader::GetProgramOutVariableLocal(ShaderProgram::Vertex);
String pixel_out = Shader::GetProgramOutVariableLocal(ShaderProgram::Pixel);
String in_position = Shader::GetVariablePrefix(ShaderVariable::Attribute) + "position";
String in_color = Shader::GetVariablePrefix(ShaderVariable::Attribute) + "color";
String pass_color = Shader::GetVariablePrefix(ShaderVariable::Varying) + "color";
nothing_vertex.Add(ShaderVariable::Attribute, "vec3", "position");
nothing_vertex.Add(ShaderVariable::Attribute, "vec4", "color");
nothing_vertex.Add(ShaderVariable::Varying, "vec4", "color");
nothing_vertex.Add(ShaderVariable::InOut, "vec4", vertex_out);
nothing_vertex.SetMainCode(
String(" ") + pass_color + " = " + in_color + ";\n" +
String(" ") + vertex_out + " = vec4(" + in_position + ", 0.f);\n"
ShaderVar out_vertex = ShaderVar::GetShaderOut(ShaderProgram::Vertex);
ShaderVar out_pixel = ShaderVar::GetShaderOut(ShaderProgram::Pixel);
ShaderVar in_position = ShaderVar(ShaderVariable::Attribute, ShaderVariableType::Vec3, "position");
ShaderVar in_color = ShaderVar(ShaderVariable::Attribute, ShaderVariableType::Vec4, "color");
ShaderVar pass_color = ShaderVar(ShaderVariable::Varying, ShaderVariableType::Vec4, "color");
nothing_vertex << in_position
<< in_color
<< pass_color;
nothing_vertex.AddVar(out_vertex);
nothing_vertex.SetMainCode(String() +
Line(pass_color + " = " + in_color + ";") +
Line(out_vertex + " = vec4(" + in_position + ", 0.f);")
);

red_pixel.Add(ShaderVariable::Varying, "vec4", "color");
red_pixel.Add(ShaderVariable::InOut, "vec4", pixel_out);
red_pixel.Add(ShaderVariable::InOut, "vec4", "ambient");
red_pixel.SetMainCode(
String(" ") + pixel_out + " = " + pass_color + ";\n" +
String(" ") + pixel_out + ".r = 1.0;\n" +
String(" ") + "ambient = vec4(1.0);\n"
ShaderVar ambient = ShaderVar(ShaderVariable::InOut, ShaderVariableType::Vec4, "ambient");

red_pixel.AddVar(pass_color);
red_pixel.AddVar(out_pixel);
red_pixel.AddVar(ambient);
red_pixel.SetMainCode(String() +
out_pixel + " = " + pass_color + ";\n" +
out_pixel + ".r = 1.0;\n" +
"ambient = vec4(1.0);\n"
);

green_pixel.Add(ShaderVariable::Varying, "vec4", "color");
green_pixel.Add(ShaderVariable::InOut, "vec4", pixel_out);
green_pixel.Add(ShaderVariable::InOut, "vec4", "ambient");
green_pixel.SetMainCode(
String(" ") + pixel_out + " = " + pass_color + ";\n" +
String(" ") + pixel_out + ".g = 1.0;\n" +
String(" ") + "ambient.r = 0.0;\n"
green_pixel.AddVar(pass_color);
green_pixel.AddVar(out_pixel);
green_pixel.AddVar(ambient);
green_pixel.SetMainCode(String() +
out_pixel + " = " + pass_color + ";\n" +
out_pixel + ".g = 1.0;\n" +
"ambient.r = 0.0;\n"
);

blue_pixel.Add(ShaderVariable::Varying, "vec4", "color");
blue_pixel.Add(ShaderVariable::InOut, "vec4", pixel_out);
blue_pixel.Add(ShaderVariable::InOut, "vec4", "ambient");
blue_pixel.SetCustomCode(
String("void SetAmbient(inout vec4 ambient)\n{\n ambient = vec4(1.0, 1.0, 1.0, 1.0);\n}"));
blue_pixel.SetMainCode(
String(" ") + pixel_out + " = " + pass_color + ";\n" +
String(" ") + pixel_out + ".b = 1.0;\n" +
String(" ") + "SetAmbient(ambient);\n" +
String(" ") + pixel_out + " *= ambient;\n"
blue_pixel.AddVar(pass_color);
blue_pixel.AddVar(out_pixel);
blue_pixel.AddVar(ambient);
blue_pixel.SetCustomCode(String() +
"void SetAmbient(inout vec4 ambient)\n" +
"{\n" +
" ambient = vec4(1.0, 1.0, 1.0, 1.0);\n" +
"}\n");
blue_pixel.SetMainCode(String() +
out_pixel + " = " + pass_color + ";\n" +
out_pixel + ".b = 1.0;\n" +
"SetAmbient(ambient);\n" +
out_pixel + " *= ambient;\n"
);

builder << ShaderProgram::Vertex
<< &nothing_vertex
<< nothing_vertex
<< ShaderProgram::Pixel
<< &red_pixel
<< &green_pixel
<< &blue_pixel;
<< red_pixel
<< green_pixel
<< blue_pixel;

builder.Build(code);



+ 61
- 31
src/gpu/shader.cpp View File

@@ -442,7 +442,7 @@ Shader::Shader(String const &name,

int Shader::GetAttribCount() const
{
return data->attrib_locations.count();
return (int)data->attrib_locations.count();
}

ShaderAttrib Shader::GetAttribLocation(VertexUsage usage, int index) const
@@ -469,6 +469,10 @@ ShaderAttrib Shader::GetAttribLocation(VertexUsage usage, int index) const
return ret;
}

ShaderUniform Shader::GetUniformLocation(String const& uni) const
{
return GetUniformLocation(uni.C());
}
ShaderUniform Shader::GetUniformLocation(char const *uni) const
{
ShaderUniform ret;
@@ -514,7 +518,7 @@ void Shader::SetUniform(ShaderUniform const &uni, int i)
#if defined USE_D3D9 || defined _XBOX
SetUniform(uni, ivec4(i, 0, 0, 0));
#else
glUniform1i(uni.frag, i);
glUniform1i((GLint)uni.frag, i);
#endif
}

@@ -523,7 +527,7 @@ void Shader::SetUniform(ShaderUniform const &uni, ivec2 const &v)
#if defined USE_D3D9 || defined _XBOX
SetUniform(uni, ivec4(v, 0, 0));
#else
glUniform2i(uni.frag, v.x, v.y);
glUniform2i((GLint)uni.frag, v.x, v.y);
#endif
}

@@ -532,7 +536,7 @@ void Shader::SetUniform(ShaderUniform const &uni, ivec3 const &v)
#if defined USE_D3D9 || defined _XBOX
SetUniform(uni, ivec4(v, 0));
#else
glUniform3i(uni.frag, v.x, v.y, v.z);
glUniform3i((GLint)uni.frag, v.x, v.y, v.z);
#endif
}

@@ -544,7 +548,7 @@ void Shader::SetUniform(ShaderUniform const &uni, ivec4 const &v)
if (uni.flags & 2)
data->m_dev->SetVertexShaderConstantI((UINT)uni.vert, &v[0], 1);
#else
glUniform4i(uni.frag, v.x, v.y, v.z, v.w);
glUniform4i((GLint)uni.frag, v.x, v.y, v.z, v.w);
#endif
}

@@ -553,7 +557,7 @@ void Shader::SetUniform(ShaderUniform const &uni, float f)
#if defined USE_D3D9 || defined _XBOX
SetUniform(uni, vec4(f, 0, 0, 0));
#else
glUniform1f(uni.frag, f);
glUniform1f((GLint)uni.frag, f);
#endif
}

@@ -562,7 +566,7 @@ void Shader::SetUniform(ShaderUniform const &uni, vec2 const &v)
#if defined USE_D3D9 || defined _XBOX
SetUniform(uni, vec4(v, 0, 0));
#else
glUniform2fv(uni.frag, 1, &v[0]);
glUniform2fv((GLint)uni.frag, 1, &v[0]);
#endif
}

@@ -571,7 +575,7 @@ void Shader::SetUniform(ShaderUniform const &uni, vec3 const &v)
#if defined USE_D3D9 || defined _XBOX
SetUniform(uni, vec4(v, 0));
#else
glUniform3fv(uni.frag, 1, &v[0]);
glUniform3fv((GLint)uni.frag, 1, &v[0]);
#endif
}

@@ -583,7 +587,7 @@ void Shader::SetUniform(ShaderUniform const &uni, vec4 const &v)
if (uni.flags & 2)
data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &v[0], 1);
#else
glUniform4fv(uni.frag, 1, &v[0]);
glUniform4fv((GLint)uni.frag, 1, &v[0]);
#endif
}

@@ -596,7 +600,7 @@ void Shader::SetUniform(ShaderUniform const &uni, mat2 const &m)
if (uni.flags & 2)
data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &m[0][0], 1);
#else
glUniformMatrix2fv(uni.frag, 1, GL_FALSE, &m[0][0]);
glUniformMatrix2fv((GLint)uni.frag, 1, GL_FALSE, &m[0][0]);
#endif
}

@@ -611,7 +615,7 @@ void Shader::SetUniform(ShaderUniform const &uni, mat3 const &m)
if (uni.flags & 2)
data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &tmp[0][0], 3);
#else
glUniformMatrix3fv(uni.frag, 1, GL_FALSE, &m[0][0]);
glUniformMatrix3fv((GLint)uni.frag, 1, GL_FALSE, &m[0][0]);
#endif
}

@@ -623,7 +627,7 @@ void Shader::SetUniform(ShaderUniform const &uni, mat4 const &m)
if (uni.flags & 2)
data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &m[0][0], 4);
#else
glUniformMatrix4fv(uni.frag, 1, GL_FALSE, &m[0][0]);
glUniformMatrix4fv((GLint)uni.frag, 1, GL_FALSE, &m[0][0]);
#endif
}

@@ -658,7 +662,7 @@ void Shader::SetUniform(ShaderUniform const &uni, array<float> const &v)
data->m_dev->SetVertexShaderConstantF((UINT)uni.vert,
&v[0], v.Count() / 4);
#else
glUniform1fv(uni.frag, v.Count(), &v[0]);
glUniform1fv((GLint)uni.frag, (GLsizei)v.Count(), &v[0]);
#endif
}

@@ -674,7 +678,7 @@ void Shader::SetUniform(ShaderUniform const &uni, array<vec2> const &v)
data->m_dev->SetVertexShaderConstantF((UINT)uni.vert,
&v[0][0], v.Count() / 2);
#else
glUniform2fv(uni.frag, v.Count(), &v[0][0]);
glUniform2fv((GLint)uni.frag, (GLsizei)v.Count(), &v[0][0]);
#endif
}

@@ -690,7 +694,7 @@ void Shader::SetUniform(ShaderUniform const &uni, array<vec3> const &v)
data->m_dev->SetVertexShaderConstantF((UINT)uni.vert,
&v[0][0], v.Count());
#else
glUniform3fv(uni.frag, v.Count(), &v[0][0]);
glUniform3fv((GLint)uni.frag, (GLsizei)v.Count(), &v[0][0]);
#endif
}

@@ -704,7 +708,7 @@ void Shader::SetUniform(ShaderUniform const &uni, array<vec4> const &v)
data->m_dev->SetVertexShaderConstantF((UINT)uni.vert,
&v[0][0], v.Count());
#else
glUniform4fv(uni.frag, v.Count(), &v[0][0]);
glUniform4fv((GLint)uni.frag, (GLsizei)v.Count(), &v[0][0]);
#endif
}

@@ -934,6 +938,9 @@ String ShaderData::Patch(String const &code, ShaderType type)
}

static const String g_ret = "\n";
static const String g_eol = ";";
static const String g_bop = "{";
static const String g_bcl = "}";
static const String g_tab = " ";

//----
@@ -1008,7 +1015,7 @@ String Shader::GetProgramQualifier(const ShaderProgram program)
{
switch (program.ToScalar())
{
case ShaderProgram::Geometry: return String(); //TODO : L O L ----------------
case ShaderProgram::Geometry: return String(); //TODO : L O L ---------
case ShaderProgram::Vertex: return String("[vert.glsl]");
case ShaderProgram::Pixel: return String("[frag.glsl]");
default: return String();
@@ -1020,7 +1027,7 @@ String Shader::GetProgramOutVariable(const ShaderProgram program)
{
switch (program.ToScalar())
{
case ShaderProgram::Geometry: return String(); //TODO : L O L ----------------
case ShaderProgram::Geometry: return String(); //TODO : L O L ---------
case ShaderProgram::Vertex: return String("gl_Position");
case ShaderProgram::Pixel: return String("gl_FragColor");
default: return String();
@@ -1032,29 +1039,44 @@ String Shader::GetProgramOutVariableLocal(const ShaderProgram program)
{
switch (program.ToScalar())
{
case ShaderProgram::Geometry: return String(); //TODO : L O L ----------------
case ShaderProgram::Geometry: return String(); //TODO : L O L ---------
case ShaderProgram::Vertex: return String("out_position");
case ShaderProgram::Pixel: return String("out_frag_color");
default: return String();
}
}

//ShaderVar -------------------------------------------------------------------
ShaderVar ShaderVar::GetShaderOut(ShaderProgram program)
{
switch (program.ToScalar())
{
case ShaderProgram::Geometry: //TODO : L O L ------------------------------
default: ASSERT(false); return ShaderVar();
case ShaderProgram::Vertex: return ShaderVar(ShaderVariable::InOut, ShaderVariableType::Vec4, Shader::GetProgramOutVariableLocal(program));
case ShaderProgram::Pixel: return ShaderVar(ShaderVariable::InOut, ShaderVariableType::Vec4, Shader::GetProgramOutVariableLocal(program));
}
}

//Shader Block implementation class -------------------------------------------
void ShaderBlock::Add(const ShaderVariable parameter, String const &type, String const &name)
void ShaderBlock::AddVar(ShaderVar const& var)
{
ASSERT(!m_parameters[parameter.ToScalar()].has_key(name));
m_parameters[parameter.ToScalar()][name] = type;
ShaderVariable qualifier = var.GetQualifier();
String type = var.GetType();
String name = Shader::GetVariablePrefix(qualifier) + var.m_name;
ASSERT(!m_parameters[qualifier.ToScalar()].has_key(name));
m_parameters[qualifier.ToScalar()][name] = type;
}

//----
void ShaderBlock::AddCallParameters(const ShaderVariable type, map<String, String> const& variables, String& result)
void ShaderBlock::AddCallParameters(map<String, String> const& variables, String& result)
{
array<String> keys = variables.keys();
for (String key : keys)
{
if (result.Count() > 0)
result += ", ";
result += Shader::GetVariablePrefix(type) + key;
result += key;
}
}

@@ -1069,7 +1091,6 @@ void ShaderBlock::AddDefinitionParameters(const ShaderVariable type, const Shade
result += Shader::GetFunctionQualifier(type, program) + " ";
result += variables[key];
result += String(" ");
result += Shader::GetVariablePrefix(type);
result += key;
}
}
@@ -1085,7 +1106,7 @@ void ShaderBlock::Build(const ShaderProgram program, String& call, String& funct
call = call_name + "(";
String call_parameters;
for (int i = 0; i < ShaderVariable::MAX; i++)
AddCallParameters((ShaderVariable)i, m_parameters[i], call_parameters);
AddCallParameters(/*(ShaderVariable)i, */m_parameters[i], call_parameters);
call += call_parameters + ");";

//Build function declaration
@@ -1133,6 +1154,14 @@ ShaderBuilder& ShaderBuilder::operator<<(ShaderBlock* block)
return *this;
}

//----
ShaderBuilder& ShaderBuilder::operator<<(ShaderBlock const& block)
{
ASSERT(m_current_program != ShaderProgram::MAX);
m_blocks[m_current_program.ToScalar()].PushUnique(new ShaderBlock(block));
return *this;
}

//----
String ShaderBuilder::AddSlotOutVariableLocal(const ShaderProgram program)
{
@@ -1170,8 +1199,11 @@ void ShaderBuilder::MergeParameters(map<String, String>& variables, map<String,
for (String key : keys)
{
bool has_key = merged.has_key(key);

//Key exists, check the type to make sure it's the same
ASSERT(!(has_key && merged[key] != variables[key]));
ASSERT(!has_key || (has_key && merged[key] == variables[key]),
"has_key=%d, key=%s merged[key]=%s, variables[key]=%s\n",
(int)has_key, key.C(), merged[key].C(), variables[key].C());

//does not exist, had it
if (!has_key)
@@ -1217,8 +1249,7 @@ void ShaderBuilder::Build(String& code)
for (String key : keys)
{
code += Shader::GetVariableQualifier((ShaderVariable)var) + " ";
code += m_parameters[prog][var][key] + " " +
Shader::GetVariablePrefix((ShaderVariable)var) + key + ";" + g_ret;
code += m_parameters[prog][var][key] + " " + key + ";" + g_ret;
}
if (var + 1 < ShaderVariable::InOut)
code += g_ret;
@@ -1254,8 +1285,7 @@ void ShaderBuilder::Build(String& code)
{
if (keys.Count())
{
code += g_tab + m_parameters[prog][var][key] + " " +
Shader::GetVariablePrefix((ShaderVariable)var) + key + ";" + g_ret;
code += g_tab + m_parameters[prog][var][key] + " " + key + ";" + g_ret;
}
}
code += g_ret;


+ 49
- 0
src/image/color/color.cpp View File

@@ -55,6 +55,55 @@ String Color::HexString8Bpp(vec4 c)
return String::Printf("%02x%2x%02x%02x", c2.r, c2.g, c2.b, c2.a);
}

/*
* Convert uint color to vec4.
*/
vec4 Color::FromRGBA32(uint32_t c)
{
ivec4 v(c >> 24, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff);
return vec4(v) * (1.f / 255.f);
}
vec4 Color::FromRGB32(uint32_t c)
{
return Color::FromRGBA32((c << 8) | 0x000000ffu);
}
vec4 Color::FromRGBA16(uint16_t c)
{
return Color::FromRGBA32
( 0x11000000u * (c >> 12)
| 0x00110000u * ((c >> 8) & 0xf)
| 0x00001100u * ((c >> 4) & 0xf)
| 0x00000011u * (c & 0xf));
}
vec4 Color::FromRGB16(uint16_t c)
{
return Color::FromRGBA16((c << 4) | 0xfu);
}

/*
* Convert uint color to vec4.
*/
uint32_t Color::ToRGBA32(vec4 c)
{
ivec4 v(c * 0xff);
return (uint32_t)((v.r << 24) | (v.g << 16) | (v.b << 8) | v.a);
}
uint32_t Color::ToRGB32(vec4 c)
{
ivec4 v(c * 0xff);
return (uint32_t)((v.r << 16) | (v.g << 8) | v.b);
}
uint16_t Color::ToRGBA16(vec4 c)
{
ivec4 v(c * 0xf);
return (uint16_t)((v.r << 12) | (v.g << 8) | (v.b << 4) | v.a);
}
uint16_t Color::ToRGB16(vec4 c)
{
ivec4 v(c * 0xf);
return (uint16_t)((v.r << 8) | (v.g << 4) | v.b);
}

/*
* Conversion from colours to hexadecimal
*/


+ 1
- 1
src/image/image.cpp View File

@@ -133,8 +133,8 @@ void Image::DummyFill()
void Image::Copy(uint8_t* pixels, ivec2 const& size, PixelFormat fmt)
{
ASSERT(fmt != PixelFormat::Unknown);
SetFormat(fmt);
SetSize(size);
SetFormat(fmt);
memcpy(m_data->m_pixels[(int)fmt]->data(), pixels,
size.x * size.y * BytesPerPixel(fmt));
}


+ 241
- 140
src/imgui/lolimgui.cpp View File

@@ -19,13 +19,77 @@ using namespace lol;
//-----------------------------------------------------------------------------
LolImGui::LolImGui()
{
m_gamegroup = GAMEGROUP_BEFORE;
m_drawgroup = DRAWGROUP_HUD;

//Build shader code -------------------------------------------------------
ShaderVar out_vertex = ShaderVar::GetShaderOut(ShaderProgram::Vertex);
ShaderVar out_pixel = ShaderVar::GetShaderOut(ShaderProgram::Pixel);

ShaderVar pass_texcoord = ShaderVar(ShaderVariable::Varying, ShaderVariableType::Vec2, "texcoord");
ShaderVar pass_color = ShaderVar(ShaderVariable::Varying, ShaderVariableType::Vec4, "color");

ShaderVar in_position = ShaderVar(ShaderVariable::Attribute, ShaderVariableType::Vec2, "position");
ShaderVar in_texcoord = ShaderVar(ShaderVariable::Attribute, ShaderVariableType::Vec2, "texcoord");
ShaderVar in_color = ShaderVar(ShaderVariable::Attribute, ShaderVariableType::Vec4, "color");

m_ortho.m_var = ShaderVar(ShaderVariable::Uniform, ShaderVariableType::Mat4, "ortho");
m_texture.m_var = ShaderVar(ShaderVariable::Uniform, ShaderVariableType::sampler2D, "texture");

ShaderBlock imgui_vertex("imgui_vertex");
imgui_vertex
<< out_vertex << m_ortho << in_position
<< pass_texcoord << in_texcoord
<< pass_color << in_color;
imgui_vertex.SetMainCode(String() +
Line(out_vertex + " = .5 *" + m_ortho + " * vec4(" + in_position + ", -1.0, 1.0);")
+ Line(pass_texcoord + " = " + in_texcoord + ";")
+ Line(pass_color + " = " + in_color + ";")
);

ShaderBlock imgui_pixel("imgui_pixel");
imgui_pixel << m_texture << pass_texcoord << pass_color << out_pixel;
imgui_pixel.SetMainCode(String() +
Line(String()
+ "vec4 col = " + pass_color + " * texture2D(" + m_texture + ", " + pass_texcoord + ");")
+ Line("if (col.a == 0.0) discard; ")
+ Line(out_pixel + " = col;")
);

m_builder
<< ShaderProgram::Vertex << imgui_vertex
<< ShaderProgram::Pixel << imgui_pixel;

//Input Setup -------------------------------------------------------------
for (int i = LolImGuiKey::KEY_START; i < LolImGuiKey::KEY_END; ++i)
m_profile << InputProfile::Keyboard(i, LolImGuiKey(i).ToString());
for (int i = LolImGuiKey::MOUSE_KEY_START; i < LolImGuiKey::MOUSE_KEY_END; ++i)
m_profile << InputProfile::MouseKey(i, LolImGuiKey(i).ToString());

for (int i = LolImGuiAxis::MOUSE_AXIS_START; i < LolImGuiAxis::MOUSE_AXIS_END; ++i)
m_profile << InputProfile::MouseAxis(i, LolImGuiAxis(i).ToString());

Ticker::Ref(m_controller = new Controller("ImGui_Controller"));
m_controller->Init(m_profile);
//InputDevice::CaptureMouse(true);
m_mouse = InputDevice::GetMouse();
m_keyboard = InputDevice::GetKeyboard();

//m_controller->Get
//# define KB InputProfile::Keyboard
// m_profile
// << InputProfile::Keyboard(idx, g_name_key_Left);
//# undef KB

}
LolImGui::~LolImGui()
{
ImGui::GetIO().Fonts->TexID = nullptr;
Ticker::Unref(m_font);
m_font = nullptr;

Shader::Destroy(m_shader);
delete m_vdecl;
}

//-------------------------------------------------------------------------
@@ -35,69 +99,34 @@ void LolImGui::Init()
Ticker::Ref(g_lolimgui = new LolImGui());

ImGuiIO& io = ImGui::GetIO();
//io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
//io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
//io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
//io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
//io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
//io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
//io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
//io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
//io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
//io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
//io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
//io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
//io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
//io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
//io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
//io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
//io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
//ImFont* font0 = io.Fonts->AddFontDefault();

// Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
io.KeyMap[ImGuiKey_Tab] = LolImGuiKey::Tab;
io.KeyMap[ImGuiKey_LeftArrow] = LolImGuiKey::LeftArrow;
io.KeyMap[ImGuiKey_RightArrow] = LolImGuiKey::RightArrow;
io.KeyMap[ImGuiKey_UpArrow] = LolImGuiKey::UpArrow;
io.KeyMap[ImGuiKey_DownArrow] = LolImGuiKey::DownArrow;
io.KeyMap[ImGuiKey_Home] = LolImGuiKey::Home;
io.KeyMap[ImGuiKey_End] = LolImGuiKey::End;
io.KeyMap[ImGuiKey_Delete] = LolImGuiKey::Delete;
io.KeyMap[ImGuiKey_Backspace] = LolImGuiKey::Backspace;
io.KeyMap[ImGuiKey_Enter] = LolImGuiKey::Enter;
io.KeyMap[ImGuiKey_Escape] = LolImGuiKey::Escape;
io.KeyMap[ImGuiKey_A] = LolImGuiKey::A;
io.KeyMap[ImGuiKey_C] = LolImGuiKey::C;
io.KeyMap[ImGuiKey_V] = LolImGuiKey::V;
io.KeyMap[ImGuiKey_X] = LolImGuiKey::X;
io.KeyMap[ImGuiKey_Y] = LolImGuiKey::Y;
io.KeyMap[ImGuiKey_Z] = LolImGuiKey::Z;

//Func pointer
io.RenderDrawListsFn = LolImGui::RenderDrawLists;
io.SetClipboardTextFn = LolImGui::SetClipboard;
io.GetClipboardTextFn = LolImGui::GetClipboard;

/* nope
#ifdef _MSC_VER
io.ImeWindowHandle = glfwGetWin32Window(g_Window);
#endif
*/

/* Callback not needed but look into these to send IO stuff
if (install_callbacks)
{
glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback);
glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback);
glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback);
glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback);
}
*/
}

/* CALLBACKS
void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
{
if (action == GLFW_PRESS && button >= 0 && button < 3)
g_MousePressed[button] = true;
}

void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
{
g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines.
}

void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
ImGuiIO& io = ImGui::GetIO();
if (action == GLFW_PRESS)
io.KeysDown[key] = true;
if (action == GLFW_RELEASE)
io.KeysDown[key] = false;
io.KeyCtrl = (mods & GLFW_MOD_CONTROL) != 0;
io.KeyShift = (mods & GLFW_MOD_SHIFT) != 0;
}

void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
{
ImGuiIO& io = ImGui::GetIO();
@@ -138,25 +167,12 @@ void LolImGui::TickGame(float seconds)
// Build texture
unsigned char* pixels;
ivec2 size;
io.Fonts->GetTexDataAsAlpha8(&pixels, &size.x, &size.y);
io.Fonts->GetTexDataAsRGBA32(&pixels, &size.x, &size.y);

Image* image = new Image();
image->Copy(pixels, size, PixelFormat::RGBA_8);
image->SetSize(size);

Ticker::Ref(m_font = new TextureImage("", image));

//// Create texture
//glGenTextures(1, &g_FontTexture);
//glBindTexture(GL_TEXTURE_2D, g_FontTexture);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels);

//// Store our identifier
//io.Fonts->TexID = (void *)(intptr_t)g_FontTexture;

//return true;
}
//Texture has been created
if (m_font && m_font->GetTexture())
@@ -169,40 +185,73 @@ void LolImGui::TickGame(float seconds)
video_size = vec2(Video::GetSize());
io.DisplaySize = ImVec2(video_size.x, video_size.y);

// Setup time step
//Setup time step
io.DeltaTime = seconds;
io.MouseDrawCursor = true;

// Setup inputs
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
//double mouse_x, mouse_y;
//glfwGetCursorPos(g_Window, &mouse_x, &mouse_y);
//mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels
//mouse_y *= (float)display_h / h;
//io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)

/*
for (int i = 0; i < 3; i++)
//Update Keyboard
io.KeyCtrl = false;
io.KeyShift = false;
for (int i = LolImGuiKey::KEY_START; i < LolImGuiKey::KEY_END; ++i)
{
io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
g_MousePressed[i] = false;
switch (i)
{
default:
io.KeysDown[i] = m_controller->GetKey(i).IsPressed();
break;
case LolImGuiKey::LShift:
case LolImGuiKey::RShift:
io.KeyShift = (io.KeyShift || m_controller->GetKey(i).IsPressed());
break;
case LolImGuiKey::LCtrl:
case LolImGuiKey::RCtrl:
io.KeyCtrl = (io.KeyCtrl || m_controller->GetKey(i).IsPressed());
break;
}
}

io.MouseWheel = g_MouseWheel;
g_MouseWheel = 0.0f;
*/
//Update text input
String text = m_keyboard->GetText();
//text.case_change(io.KeyShift);
for (int i = 0; i < text.count(); ++i)
io.AddInputCharacter(text[i]);

//Update mouse
if (m_mouse)
{
vec2 cursor = m_mouse->GetCursor(0);
cursor.y = 1.f - cursor.y;
cursor *= video_size;
io.MousePos = ImVec2(cursor.x, cursor.y);
io.MouseWheel = m_controller->GetAxis(LolImGuiAxis::Scroll).GetValue();

for (int i = LolImGuiKey::MOUSE_KEY_START; i < LolImGuiKey::MOUSE_KEY_END; ++i)
{
switch (i)
{
default:
io.MouseDown[i - LolImGuiKey::MOUSE_KEY_START] = m_controller->GetKey(i).IsPressed();
break;
case LolImGuiKey::Focus:
if (m_controller->GetKey(i).IsPressed())
io.MousePos = ImVec2(-1.f, -1.f);
break;
}
}
}

// Start the frame
ImGui::NewFrame();

}
void LolImGui::TickDraw(float seconds, Scene &scene)
{
super::TickDraw(seconds, scene);

ImGui::Render();
}

ImGuiIO& io = ImGui::GetIO();

if (io.Fonts->TexID)
ImGui::Render();
}



@@ -219,74 +268,126 @@ void LolImGui::TickDraw(float seconds, Scene &scene)
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
//-------------------------------------------------------------------------
void LolImGui::RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
{
g_lolimgui->RenderDrawListsMethod(cmd_lists, cmd_lists_count);
}
void LolImGui::RenderDrawListsMethod(ImDrawList** const cmd_lists, int cmd_lists_count)
{
if (cmd_lists_count == 0)
return;

/*
// We are using the OpenGL fixed pipeline to make the example code simpler to read!
// A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer.
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers.
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnable(GL_TEXTURE_2D);

// Setup orthographic projection matrix
const float width = ImGui::GetIO().DisplaySize.x;
const float height = ImGui::GetIO().DisplaySize.y;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

// Render command lists
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
vec2 size = vec2(Video::GetSize());
float alpha = 1.f;
mat4 ortho = mat4::ortho(size.x * alpha, size.y * alpha, -1000.f, 1000.f)
* mat4::lookat(vec3::axis_z, vec3::zero, vec3::axis_y)
* mat4::scale(vec3::axis_x - vec3::axis_y - vec3::axis_z)
* mat4::translate(-size.x * .5f * alpha, -size.y * .5f * alpha, 0.f);

//Create shader
if (!m_shader)
{
String code;
m_builder.Build(code);

m_shader = Shader::Create(m_builder.GetName(), code);
ASSERT(m_shader);

m_ortho.m_uniform = m_shader->GetUniformLocation(m_ortho.m_var);
m_texture.m_uniform = m_shader->GetUniformLocation(m_texture.m_var);

m_attribs
<< m_shader->GetAttribLocation(VertexUsage::Position, 0)
<< m_shader->GetAttribLocation(VertexUsage::TexCoord, 0)
<< m_shader->GetAttribLocation(VertexUsage::Color, 0);

m_vdecl = new VertexDeclaration(
VertexStream<vec2, vec2, u8vec4>(
VertexUsage::Position,
VertexUsage::TexCoord,
VertexUsage::Color));
}

//Do not render without shader
if (!m_shader)
return;

RenderContext rc;
rc.SetCullMode(CullMode::Disabled);
rc.SetDepthFunc(DepthFunc::Disabled);

m_shader->Bind();
for (int n = 0; n < cmd_lists_count; n++)
{
const ImDrawList* cmd_list = cmd_lists[n];
const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->vtx_buffer.front();
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos)));
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv)));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col)));

//Register uniforms
m_shader->SetUniform(m_ortho, ortho);
m_shader->SetUniform(m_texture, m_font->GetTexture()->GetTextureUniform(), 0);

int vtx_offset = 0;
for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i];
if (pcmd->user_callback)

struct Vertex
{
pcmd->user_callback(cmd_list, pcmd);
}
else
vec2 pos, tex;
u8vec4 color;
};

VertexBuffer* vbo = new VertexBuffer(pcmd->vtx_count * sizeof(Vertex));
Vertex *vert = (Vertex *)vbo->Lock(0, 0);

#ifdef SHOW_IMGUI_DEBUG
//-----------------------------------------------------------------
//<Debug render> --------------------------------------------------
//-----------------------------------------------------------------
float mod = -200.f;
vec3 off = vec3(vec2(-size.x, -size.y), 0.f);
vec3 pos[4] = {
(1.f / mod) * (off + vec3(0.f)),
(1.f / mod) * (off + size.x * vec3::axis_x),
(1.f / mod) * (off + size.x * vec3::axis_x + size.y * vec3::axis_y),
(1.f / mod) * (off + size.y * vec3::axis_y)
};
for (int i = 0; i < 4; ++i)
Debug::DrawLine(pos[i], pos[(i + 1) % 4], Color::white);
ImDrawVert* buf = (ImDrawVert*)(vtx_buffer + vtx_offset);
for (uint16_t i = 0; i < pcmd->vtx_count; i += 3)
{
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->texture_id);
glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y));
glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count);
vec2 pos[3];
pos[0] = vec2(buf[i + 0].pos.x, buf[i + 0].pos.y);
pos[1] = vec2(buf[i + 1].pos.x, buf[i + 1].pos.y);
pos[2] = vec2(buf[i + 2].pos.x, buf[i + 2].pos.y);
vec4 col[3];
col[0] = vec4(Color::FromRGBA32(buf[i + 0].col).arg, 1.f);
col[1] = vec4(Color::FromRGBA32(buf[i + 1].col).arg, 1.f);
col[2] = vec4(Color::FromRGBA32(buf[i + 2].col).arg, 1.f);
Debug::DrawLine((off + vec3(pos[0], 0.f)) / mod, (off + vec3(pos[1], 0.f)) / mod, col[0]);
Debug::DrawLine((off + vec3(pos[1], 0.f)) / mod, (off + vec3(pos[2], 0.f)) / mod, col[1]);
Debug::DrawLine((off + vec3(pos[2], 0.f)) / mod, (off + vec3(pos[0], 0.f)) / mod, col[2]);
}
vtx_offset += pcmd->vtx_count;
//-----------------------------------------------------------------
//<\Debug render> -------------------------------------------------
//-----------------------------------------------------------------
#endif //SHOW_IMGUI_DEBUG

memcpy(vert, vtx_buffer + vtx_offset, pcmd->vtx_count * sizeof(Vertex));
vbo->Unlock();

m_font->Bind();
m_vdecl->Bind();
m_vdecl->SetStream(vbo, m_attribs[0], m_attribs[1], m_attribs[2]);
m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, pcmd->vtx_count);
m_vdecl->Unbind();
m_font->Unbind();

vtx_offset += pcmd->vtx_count * sizeof(Vertex);

delete vbo;
}
}
#undef OFFSETOF

// Restore modified state
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
*/
m_shader->Unbind();
}


+ 130
- 0
src/imgui/lolimgui.h View File

@@ -22,6 +22,112 @@ class LolImGui : public Entity
{
typedef Entity super;

//ImGuiKeyBase ------------------------------------------------------------
struct LolImGuiKeyBase : public StructSafeEnum
{
enum Type
{
KEY_START,

Tab = KEY_START,
LeftArrow,
RightArrow,
UpArrow,
DownArrow,
Home,
End,
Delete,
Backspace,
Enter,
Escape,

A,
C,
V,
X,
Y,
Z,

LShift,
RShift,
LCtrl,
RCtrl,

KEY_END,

MOUSE_KEY_START = KEY_END,

LeftClick = MOUSE_KEY_START,
RightClick,
MiddleClick,
Focus,

MOUSE_KEY_END,

MAX = MOUSE_KEY_END,
};
protected:
virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
{
enum_map[Tab] = g_name_key_Tab;
enum_map[LeftArrow] = g_name_key_Left;
enum_map[RightArrow] = g_name_key_Right;
enum_map[UpArrow] = g_name_key_Up;
enum_map[DownArrow] = g_name_key_Down;
enum_map[Home] = g_name_key_Home;
enum_map[End] = g_name_key_End;
enum_map[Delete] = g_name_key_Delete;
enum_map[Backspace] = g_name_key_Backspace;
enum_map[Enter] = g_name_key_Return;
enum_map[Escape] = g_name_key_Escape;

enum_map[A] = g_name_key_A;
enum_map[C] = g_name_key_C;
enum_map[V] = g_name_key_V;
enum_map[X] = g_name_key_X;
enum_map[Y] = g_name_key_Y;
enum_map[Z] = g_name_key_Z;

enum_map[LShift] = g_name_key_LShift;
enum_map[RShift] = g_name_key_RShift;
enum_map[LCtrl] = g_name_key_LCtrl;
enum_map[RCtrl] = g_name_key_RCtrl;

enum_map[LeftClick] = g_name_mouse_key_left;
enum_map[RightClick] = g_name_mouse_key_right;
enum_map[MiddleClick] = g_name_mouse_key_middle;

return true;
}
};
typedef SafeEnum<LolImGuiKeyBase> LolImGuiKey;

//ImGuiKeyBase ------------------------------------------------------------
struct LolImGuiAxisBase : public StructSafeEnum
{
enum Type
{
MOUSE_AXIS_START = 0,

Scroll = MOUSE_AXIS_START,

MOUSE_AXIS_END,

MAX = MOUSE_AXIS_END,
};
protected:
virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
{
enum_map[Scroll] = g_name_mouse_axis_scroll;

return true;
}
};
typedef SafeEnum<LolImGuiAxisBase> LolImGuiAxis;



public:
//-------------------------------------------------------------------------
LolImGui();
~LolImGui();
@@ -40,8 +146,32 @@ protected:
virtual void TickDraw(float seconds, Scene &scene);

static void RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count);
void RenderDrawListsMethod(ImDrawList** const cmd_lists, int cmd_lists_count);

struct Uniform
{
Uniform() { }
Uniform(ShaderVar var) { m_var = var; }
operator String() { return m_var; }
operator ShaderVar() { return m_var; }
operator ShaderUniform() { return m_uniform; }
//--
ShaderVar m_var;
ShaderUniform m_uniform;
};
//-------------------------------------------------------------------------
TextureImage* m_font = nullptr;
ShaderBuilder m_builder = ShaderBuilder("imgui_shader", "120");
Shader* m_shader = nullptr;
Uniform m_ortho;
Uniform m_texture;
array<ShaderAttrib> m_attribs;
VertexDeclaration* m_vdecl = nullptr;
Controller* m_controller = nullptr;
InputDevice* m_mouse = nullptr;
InputDevice* m_keyboard = nullptr;
InputProfile m_profile;
//map<ImGuiKey_, LolImGuiKey> m_keys;
};

//bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks);


+ 1
- 0
src/input/controller.h View File

@@ -315,6 +315,7 @@ private:
};

//-----------------------------------------------------------------------------
//TODO: Add mask|layer system to prevent several controllers from interfering with another. (input overlay in menus)
class Controller : public Entity
{
public:


+ 3
- 0
src/input/input.h View File

@@ -21,6 +21,9 @@ static String g_name_joystick(const uint64_t num)
return String::Printf("Joystick%d", (int)num);
}

# define _SC(id, str, name) const String g_name_key_##name(#name);
# include "input/keys.h"

//Mouse default buttons/axis
const String g_name_mouse_key_left("Left");
const String g_name_mouse_key_middle("Middle");


+ 1
- 1
src/input/input_internal.h View File

@@ -16,7 +16,7 @@ namespace lol
/** Internal class (not public) that allows to construct an InputDevice
* dynamically, when the keys, axis and cursors are not known at
* compile time. */
class InputDeviceInternal : InputDevice
class InputDeviceInternal : public InputDevice
{
public:
inline InputDeviceInternal(char const * name) : InputDevice(name) { }


+ 5
- 0
src/input/keys.h View File

@@ -283,5 +283,10 @@ _SC(282, "", Sleep)
_SC(283, "", App1)
_SC(284, "", App2)

//Custom Lock management
_SC(285, "", CapsLockStatus)
_SC(286, "", ScrollLockStatus)
_SC(287, "", NumLockClearStatus)

#undef _SC


+ 1
- 0
src/lol/base/enum.h View File

@@ -54,6 +54,7 @@ public:
/* 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; }
//inline class String ToString() const { return ToString(); }

/* Convert to string stuff */
inline class String ToString()


+ 61
- 29
src/lol/base/string.h View File

@@ -127,6 +127,11 @@ public:
return String(&(*this)[start], item_count);
}

bool contains(String const &s) const
{
return index_of(s.C()) != INDEX_NONE;
}

ptrdiff_t index_of(char token) const
{
using namespace std;
@@ -135,6 +140,7 @@ public:
return tmp ? (ptrdiff_t)(tmp - C()) : INDEX_NONE;
}

ptrdiff_t index_of(String const& token) const { return index_of(token.C()); }
ptrdiff_t index_of(char const* token) const
{
using namespace std;
@@ -143,11 +149,6 @@ public:
return tmp ? (ptrdiff_t)(tmp - C()) : INDEX_NONE;
}

bool contains(String const &s) const
{
return index_of(s.C()) != INDEX_NONE;
}

ptrdiff_t last_index_of(char token) const
{
using namespace std;
@@ -156,6 +157,18 @@ public:
return tmp ? (ptrdiff_t)(tmp - C()) : INDEX_NONE;
}

ptrdiff_t last_index_of(String const& token) const { return last_index_of(token.C()); }
ptrdiff_t last_index_of(char const* token) const
{
using namespace std;

ptrdiff_t token_len = strlen(token);
for (ptrdiff_t i = count() - token_len; i >= 0; --i)
if (strstr(C() + i, token))
return i;
return -1;
}

int replace(char const old_token, char const new_token,
bool all_occurrences = false)
{
@@ -173,34 +186,32 @@ public:
return res;
}

/* FIXME: it doesn't sound safe to apply this in place */
inline String& to_lower()
{
char* p = C();
for (ptrdiff_t i = 0; i < count(); ++i)
if ('A' <= p[i] && p[i] <= 'Z')
p[i] += 'a' - 'A';
String ret(*this);
for (ptrdiff_t i = 0; i < ret.count(); ++i)
{
if ('A' <= ret[i] && ret[i] <= 'Z')
ret[i] += 'a' - 'A';
}
*this = ret;
return *this;
}

inline String& to_upper()
{
char* p = C();
for (ptrdiff_t i = 0; i < count(); ++i)
if ('a' <= p[i] && p[i] <= 'z')
p[i] += 'A' - 'a';
String ret(*this);
for (ptrdiff_t i = 0; i < ret.count(); ++i)
{
if ('a' <= ret[i] && ret[i] <= 'z')
ret[i] += 'A' - 'a';
}
*this = ret;
return *this;
}

ptrdiff_t last_index_of(char const* token) const
inline String& case_change(bool case_to_upper)
{
using namespace std;

ptrdiff_t token_len = strlen(token);
for (ptrdiff_t i = count() - token_len; i >= 0; --i)
if (strstr(C() + i, token))
return i;
return -1;
return case_to_upper ? to_upper() : to_lower();
}

bool starts_with(String const &s) const
@@ -231,6 +242,12 @@ public:
return ret += s;
}

inline String operator +(char c) const
{
String ret(*this);
return ret += c;
}

inline String& operator +=(String const &s)
{
using namespace std;
@@ -240,12 +257,6 @@ public:
return *this;
}

inline String operator +(char c) const
{
String ret(*this);
return ret += c;
}

inline String& operator +=(char c)
{
((super &)*this).last() = c;
@@ -306,6 +317,7 @@ public:
inline void Resize(ptrdiff_t item_count) { return resize(item_count); }
inline String& ToLower() { return to_lower(); }
inline String& ToUpper() { return to_upper(); }
inline String& CaseChange(bool case_to_upper) { return case_to_upper ? ToUpper() : ToLower(); }
inline String Sub(ptrdiff_t start, ptrdiff_t item_count = -1) const { return sub(start, item_count); }
inline bool Contains(String const &s) const { return contains(s); }
inline ptrdiff_t IndexOf(char token) const { return index_of(token); }
@@ -318,6 +330,26 @@ public:
inline ptrdiff_t Count() const { return count(); }
};

class Line
{
public:
Line(String const& s)
{
m_line = s + "\n";
}
inline operator String()
{
return m_line;
}
inline operator const char*()
{
return m_line.C();
}

private:
String m_line;
};

inline bool operator ==(char const* sz, String const &s)
{
return s == sz;


+ 170
- 2
src/lol/gpu/shader.h View File

@@ -134,6 +134,134 @@ protected:
};
typedef SafeEnum<ShaderProgramBase> ShaderProgram;

//ShaderProgramBase -----------------------------------------------------------
struct ShaderVariableTypeBase
{
enum Type
{
Bool,
Int, UInt,
Float,
Double,
Vec2, Vec3, Vec4,
DVec2, DVec3, DVec4,
BVec2, BVec3, BVec4,
IVec2, IVec3, IVec4,
UVec2, UVec3, UVec4,

Mat2, Mat3, Mat4,

sampler1D,
sampler2D,
sampler3D,
samplerCube,
sampler2DRect,
sampler1DArray,
sampler2DArray,
samplerCubeArray,
samplerBuffer,
sampler2DMS,
sampler2DMSArray,

isampler1D,
isampler2D,
isampler3D,
isamplerCube,
isampler2DRect,
isampler1DArray,
isampler2DArray,
isamplerCubeArray,
isamplerBuffer,
isampler2DMS,
isampler2DMSArray,

usampler1D,
usampler2D,
usampler3D,
usamplerCube,
usampler2DRect,
usampler1DArray,
usampler2DArray,
usamplerCubeArray,
usamplerBuffer,
usampler2DMS,
usampler2DMSArray,

sampler1DShadow,
sampler2DShadow,
samplerCubeShadow,
sampler2DRectShadow,
sampler1DArrayShadow,
sampler2DArrayShadow,
samplerCubeArrayShadow,

MAX
};
protected:
virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
{
enum_map[Bool] = "bool";
enum_map[Int] = "int"; enum_map[UInt] = "uint";
enum_map[Float] = "float";
enum_map[Double] = "double";
enum_map[Vec2] = "vec2"; enum_map[Vec3] = "vec3"; enum_map[Vec4] = "vec4";
enum_map[DVec2] = "dvec2"; enum_map[DVec3] = "dvec3"; enum_map[DVec4] = "dvec4";
enum_map[BVec2] = "bvec2"; enum_map[BVec3] = "bvec3"; enum_map[BVec4] = "bvec4";
enum_map[IVec2] = "ivec2"; enum_map[IVec3] = "ivec3"; enum_map[IVec4] = "ivec4";
enum_map[UVec2] = "uvec2"; enum_map[UVec3] = "uvec3"; enum_map[UVec4] = "uvec4";

enum_map[Mat2] = "mat2";
enum_map[Mat3] = "mat3";
enum_map[Mat4] = "mat4";

enum_map[sampler1D] = "sampler1D";
enum_map[sampler2D] = "sampler2D";
enum_map[sampler3D] = "sampler3D";
enum_map[samplerCube] = "samplerCube";
enum_map[sampler2DRect] = "sampler2DRect";
enum_map[sampler1DArray] = "sampler1DArray";
enum_map[sampler2DArray] = "sampler2DArray";
enum_map[samplerCubeArray] = "samplerCubeArray";
enum_map[samplerBuffer] = "samplerBuffer";
enum_map[sampler2DMS] = "sampler2DMS";
enum_map[sampler2DMSArray] = "sampler2DMSArray";

enum_map[isampler1D] = "isampler1D";
enum_map[isampler2D] = "isampler2D";
enum_map[isampler3D] = "isampler3D";
enum_map[isamplerCube] = "isamplerCube";
enum_map[isampler2DRect] = "isampler2DRect";
enum_map[isampler1DArray] = "isampler1DArray";
enum_map[isampler2DArray] = "isampler2DArray";
enum_map[isamplerCubeArray] = "isamplerCubeArray";
enum_map[isamplerBuffer] = "isamplerBuffer";
enum_map[isampler2DMS] = "isampler2DMS";
enum_map[isampler2DMSArray] = "isampler2DMSArray";

enum_map[usampler1D] = "usampler1D";
enum_map[usampler2D] = "usampler2D";
enum_map[usampler3D] = "usampler3D";
enum_map[usamplerCube] = "usamplerCube";
enum_map[usampler2DRect] = "usampler2DRect";
enum_map[usampler1DArray] = "usampler1DArray";
enum_map[usampler2DArray] = "usampler2DArray";
enum_map[usamplerCubeArray] = "usamplerCubeArray";
enum_map[usamplerBuffer] = "usamplerBuffer";
enum_map[usampler2DMS] = "usampler2DMS";
enum_map[usampler2DMSArray] = "usampler2DMSArray";

enum_map[sampler1DShadow] = "sampler1DShadow";
enum_map[sampler2DShadow] = "sampler2DShadow";
enum_map[samplerCubeShadow] = "samplerCubeShadow";
enum_map[sampler2DRectShadow] = "sampler2DRectShadow";
enum_map[sampler1DArrayShadow] = "sampler1DArrayShadow";
enum_map[sampler2DArrayShadow] = "sampler2DArrayShadow";
enum_map[samplerCubeArrayShadow] = "samplerCubeArrayShadow";
return true;
}
};
typedef SafeEnum<ShaderVariableTypeBase> ShaderVariableType;

//ShaderUniform ---------------------------------------------------------------
struct ShaderUniform
{
@@ -193,6 +321,7 @@ public:
int GetAttribCount() const;
ShaderAttrib GetAttribLocation(VertexUsage usage, int index) const;

ShaderUniform GetUniformLocation(String const& uni) const;
ShaderUniform GetUniformLocation(char const *uni) const;
void SetUniform(ShaderUniform const &uni, int i);
void SetUniform(ShaderUniform const &uni, ivec2 const &v);
@@ -231,6 +360,39 @@ public:
static String GetProgramOutVariableLocal(const ShaderProgram program);
};

//ShaderVar -------------------------------------------------------------------
class ShaderVar
{
friend class ShaderBuilder;
friend class ShaderBlock;

protected:
public:
ShaderVar() { }
ShaderVar(ShaderVariable const& qualifier, String const& type, String const& name)
{
m_qualifier = qualifier;
m_type = type;
m_name = name;
}
ShaderVar(ShaderVariable const& qualifier, ShaderVariableType const& type, String const& name)
: ShaderVar(qualifier, ShaderVariableType(type).ToString(), name)
{ }
~ShaderVar() { }

inline operator String() const { return Shader::GetVariablePrefix(m_qualifier) + m_name; }
inline ShaderVariable GetQualifier() const { return m_qualifier; }
inline String GetType() const { return m_type; }
inline String operator+(String const& value) { return String() + *this + value; }

static ShaderVar GetShaderOut(ShaderProgram program);

protected:
ShaderVariable m_qualifier;
String m_type;
String m_name;
};

//ShaderBlock -----------------------------------------------------------------
class ShaderBlock
{
@@ -260,10 +422,15 @@ public:
//Sets custom code that will be put before the main -so functions-
void SetCustomCode(String const& code_custom) { m_code_custom = code_custom; }
//Add parameter to the block
void Add(const ShaderVariable variable, String const& type, String const& name);
void AddVar(ShaderVar const& var);
inline ShaderBlock& operator<<(ShaderVar const& var)
{
AddVar(var);
return *this;
}

protected:
void AddCallParameters(const ShaderVariable variable, map<String, String> const& variables, String& result);
void AddCallParameters(map<String, String> const& variables, String& result);
void AddDefinitionParameters(const ShaderVariable variable, const ShaderProgram program, map<String, String>& variables, String& result);
void Build(const ShaderProgram program, String& call, String& function);
};
@@ -289,6 +456,7 @@ public:
String const& GetName();
ShaderBuilder& operator<<(const ShaderProgram program);
ShaderBuilder& operator<<(ShaderBlock* block);
ShaderBuilder& operator<<(ShaderBlock const& block);

protected:
String AddSlotOutVariableLocal(const ShaderProgram program);


+ 16
- 0
src/lol/image/color.h View File

@@ -316,6 +316,22 @@ public:
*/
static vec3 WavelengthToCIExyY(float nm);

/*
* Convert uint color to vec4.
*/
static vec4 FromRGBA32(uint32_t c);
static vec4 FromRGB32(uint32_t c);
static vec4 FromRGBA16(uint16_t c);
static vec4 FromRGB16(uint16_t c);

/*
* Convert uint color to vec4.
*/
static uint32_t ToRGBA32(vec4 c);
static uint32_t ToRGB32(vec4 c);
static uint16_t ToRGBA16(vec4 c);
static uint16_t ToRGB16(vec4 c);

/*
* Convert colors to hex strings.
*/


+ 1
- 0
src/lol/sys/file.h View File

@@ -107,6 +107,7 @@ public:
bool GetContent(array<Directory>& directories);
bool GetContent(array<String>& files);
String GetName();
long int GetModificationTime();

static String GetCurrent();
static bool SetCurrent(String directory);


+ 3
- 0
src/lolcore.vcxproj View File

@@ -417,6 +417,9 @@
<ProjectReference Include="bullet\lolbullet.vcxproj">
<Project>{83d3b207-c601-4025-8f41-01dedc354661}</Project>
</ProjectReference>
<ProjectReference Include="imgui\lolimgui.vcxproj">
<Project>{a7f6fdf8-937e-41ef-b44d-04cd1a48c179}</Project>
</ProjectReference>
<ProjectReference Include="lua\lollua.vcxproj">
<Project>{d84021ca-b233-4e0f-8a52-071b83bbccc4}</Project>
</ProjectReference>


+ 129
- 17
src/platform/sdl/sdlinput.cpp View File

@@ -49,6 +49,48 @@ static int sdl12_to_scancode(int ch, int sc)

return 0;
}
#else
//-------------------------------------------------------------------------
# define _SC(id, str, name) static const uint16_t SDLOL_##name = id;
# include "input/keys.h"
//-------------------------------------------------------------------------
static bool ScanCodeIsValid(int sc)
{
switch (sc)
{
# define _SC(id, str, name) \
case id: return true;
# include "input/keys.h"
default: return false;
}
return false;
}
//-------------------------------------------------------------------------
static String ScanCodeToText(int sc)
{
switch (sc)
{
# define _SC(id, str, name) \
case id: return String(str);
# include "input/keys.h"
default:
Log::Error(Line("ScanCodeToText unknown scancode %0d."), sc);
}
return String();
}
//-------------------------------------------------------------------------
static String ScanCodeToName(int sc)
{
switch (sc)
{
# define _SC(id, str, name) \
case id: return String(#name);
# include "input/keys.h"
default:
Log::Error(Line("ScanCodeToText unknown scancode %0d."), sc);
}
return String();
}
#endif

/*
@@ -218,30 +260,102 @@ void SdlInputData::Tick(float seconds)

case SDL_KEYDOWN:
case SDL_KEYUP:
#if USE_OLD_SDL
if (int sc = sdl12_to_scancode(event.key.keysym.sym,
event.key.keysym.scancode))
#else
if (int sc = event.key.keysym.scancode)
#endif
m_keyboard->SetKey(sc, event.type == SDL_KEYDOWN);
else
Log::Error("unknown keypress (sym 0x%02x, scancode %0d)\n",
event.key.keysym.sym, event.key.keysym.scancode);
# if USE_OLD_SDL
switch (int sc = sdl12_to_scancode(event.key.keysym.sym,
event.key.keysym.scancode))
# else
switch (int sc = event.key.keysym.scancode)
# endif
{
//Lock management
case SDLOL_CapsLock:
case SDLOL_ScrollLock:
case SDLOL_NumLockClear:
//Update status on key down only
if (event.type == SDL_KEYDOWN)
{
int sc2 = sc;
switch (sc)
{
case SDLOL_CapsLock:
sc2 = SDLOL_CapsLockStatus;
break;
case SDLOL_ScrollLock:
sc2 = SDLOL_ScrollLockStatus;
break;
case SDLOL_NumLockClear:
sc2 = SDLOL_NumLockClearStatus;
break;
}
m_keyboard->SetKey(sc2, !m_keyboard->GetKey(sc2));
/* DEBUG STUFF
Log::Info(Line("Repeat: 0x%02x : %s/%s/%s/%i"),
(int)m_keyboard, ScanCodeToText(sc2).C(), ScanCodeToName(sc2).C(),
m_keyboard->GetKey(sc2) ? "up" : "down", event.key.repeat);
*/
}
default:
if (ScanCodeIsValid(sc))
{
m_keyboard->SetKey(sc, event.type == SDL_KEYDOWN);
if (event.type == SDL_KEYDOWN
&& !m_keyboard->GetKey(SDLOL_RCtrl)
&& !m_keyboard->GetKey(SDLOL_LCtrl)
&& !m_keyboard->GetKey(SDLOL_RAlt)
&& !m_keyboard->GetKey(SDLOL_LAlt))
{
String str = ScanCodeToText(sc);
str.CaseChange(m_keyboard->GetKey(SDLOL_CapsLockStatus)
^ (m_keyboard->GetKey(SDLOL_RShift)
|| m_keyboard->GetKey(SDLOL_LShift)));
m_keyboard->AddText(str);
}
/* DEBUG STUFF
Log::Info(Line("Repeat: 0x%02x : %s/%s/%s/%i"),
(int)m_keyboard, ScanCodeToText(sc).C(), ScanCodeToName(sc).C(),
event.type == SDL_KEYDOWN ? "up" : "down", event.key.repeat);
*/
}
/* DEBUG STUFF
else
Log::Error("unknown keypress (sym 0x%02x, scancode %0d)\n",
event.key.keysym.sym, event.key.keysym.scancode);
*/
}
break;

# if USE_OLD_SDL
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
# if USE_OLD_SDL
if (event.button.button != SDL_BUTTON_WHEELUP && event.button.button != SDL_BUTTON_WHEELDOWN)
m_mouse->SetKey(event.button.button - 1, event.type == SDL_MOUSEBUTTONDOWN);
else
m_mouse->SetAxis(4, (event.button.button != SDL_BUTTON_WHEELUP) ? (1) : (-1));
# endif
// TODO: mouse wheel as axis
break;
# else
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
m_mouse->SetKey(event.button.button - 1, event.type == SDL_MOUSEBUTTONDOWN);
break;
case SDL_MOUSEWHEEL:
m_mouse->SetAxis(4, (float)event.button.y);
break;
case SDL_WINDOWEVENT:
{
switch (event.window.event)
{
case SDL_WINDOWEVENT_ENTER:
case SDL_WINDOWEVENT_FOCUS_GAINED:
m_mouse->SetKey(3, true);
break;
case SDL_WINDOWEVENT_LEAVE:
case SDL_WINDOWEVENT_FOCUS_LOST:
m_mouse->SetKey(3, false);
break;
}
break;
}
# endif

# if !SDL_FORCE_POLL_JOYSTICK
case SDL_JOYAXISMOTION:
@@ -292,9 +406,7 @@ void SdlInputData::Tick(float seconds)
# if !EMSCRIPTEN && USE_OLD_SDL
m_mouse->SetKey(3, !!(SDL_GetAppState() & SDL_APPMOUSEFOCUS));
# else
// Emscripten doesn't seem to handle SDL_APPMOUSEFOCUS
// FIXME: SDL2 doesn't have SDL_APPMOUSEFOCUS either
m_mouse->SetKey(3, true);
//Handled in PollEvent
# endif

if (m_mousecapture)


+ 21
- 1
src/sys/file.cpp View File

@@ -197,7 +197,7 @@ class FileData
#if __ANDROID__
return 0;
#elif HAVE_STDIO_H
return m_stat.st_mtime;
return (long int)m_stat.st_mtime;
#else
return 0;
#endif
@@ -358,8 +358,10 @@ class DirectoryData
filter.Replace('/', '\\', true);
WIN32_FIND_DATA FindFileData;
m_handle = FindFirstFile(filter.C(), &FindFileData);
stat(directory.C(), &m_stat);
#elif HAVE_STDIO_H
m_dd = opendir(directory.C());
stat(directory.C(), &m_stat);
#endif
}

@@ -440,6 +442,17 @@ class DirectoryData
#endif
}

long int GetModificationTime()
{
#if __ANDROID__
return 0;
#elif HAVE_STDIO_H
return (long int)m_stat.st_mtime;
#else
return 0;
#endif
}

#if __ANDROID__
/* FIXME: not implemented */
#elif defined(_WIN32)
@@ -450,6 +463,7 @@ class DirectoryData
#endif
std::atomic<int> m_refcount;
StreamType m_type;
struct stat m_stat;
};

//-- DIRECTORY --
@@ -559,6 +573,12 @@ String Directory::GetName()
return m_name;
}

//--
long int Directory::GetModificationTime()
{
return m_data->GetModificationTime();
}

//--
String Directory::GetCurrent()
{


+ 3
- 3
src/sys/thread.cpp View File

@@ -54,7 +54,7 @@ bool BaseThreadManager::Stop()
return false;

//Stop all threads
StopThreads(m_threads.count());
StopThreads((int)m_threads.count());

return true;
}
@@ -173,9 +173,9 @@ void BaseThreadManager::TickGame(float seconds)

//Resize thread count if needed
if (m_threads.count() > m_jobqueue.count() && m_threads.count() > m_thread_min)
StopThreads(m_threads.Count() - m_thread_min);
StopThreads((int)(m_threads.Count() - m_thread_min));
else if (m_threads.count() < m_jobqueue.count())
AddThreads(lol::min(m_jobqueue.count(), (ptrdiff_t)m_thread_count) - m_threads.count());
AddThreads((int)(lol::min(m_jobqueue.count(), (ptrdiff_t)m_thread_count) - m_threads.count()));
}

} /* namespace lol */

Loading…
Cancel
Save