158 строки
3.3 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // Lol Engine is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #include <lol/engine-internal.h>
  13. #include <cstring>
  14. #include <cstdlib>
  15. namespace lol
  16. {
  17. /*
  18. * Mesh class
  19. */
  20. Mesh::Mesh()
  21. {
  22. }
  23. Mesh::~Mesh()
  24. {
  25. }
  26. void Mesh::Render(Scene& scene, mat4 const &matrix)
  27. {
  28. //if (scene.HasPrimitiveRenderer(this) < m_submeshes.count())
  29. {
  30. for (int i = 0; i < m_submeshes.count(); ++i)
  31. scene.AddPrimitiveRenderer(this, new PrimitiveMesh(m_submeshes[i], matrix));
  32. }
  33. }
  34. void Mesh::Render()
  35. {
  36. for (int i = 0; i < m_submeshes.count(); ++i)
  37. m_submeshes[i]->Render();
  38. }
  39. void Mesh::SetMaterial(Shader *shader)
  40. {
  41. for (int i = 0; i < m_submeshes.count(); ++i)
  42. m_submeshes[i]->SetShader(shader);
  43. }
  44. /*
  45. * SubMesh class
  46. */
  47. SubMesh::SubMesh(Shader *shader, VertexDeclaration *vdecl)
  48. : m_mesh_prim(MeshPrimitive::Triangles),
  49. m_shader(shader),
  50. m_vdecl(vdecl)
  51. {
  52. Ticker::Ref(m_shader);
  53. }
  54. SubMesh::~SubMesh()
  55. {
  56. Ticker::Unref(m_shader);
  57. // TODO: cleanup
  58. }
  59. void SubMesh::SetMeshPrimitive(MeshPrimitive mesh_primitive)
  60. {
  61. m_mesh_prim = mesh_primitive;
  62. }
  63. void SubMesh::SetShader(Shader *shader)
  64. {
  65. Ticker::Unref(m_shader);
  66. m_shader = shader;
  67. Ticker::Ref(m_shader);
  68. }
  69. Shader *SubMesh::GetShader()
  70. {
  71. return m_shader;
  72. }
  73. void SubMesh::SetVertexDeclaration(VertexDeclaration *vdecl)
  74. {
  75. m_vdecl = vdecl;
  76. }
  77. void SubMesh::SetVertexBuffer(int index, VertexBuffer* vbo)
  78. {
  79. while (index >= m_vbos.count())
  80. m_vbos.push(nullptr);
  81. m_vbos[index] = vbo;
  82. }
  83. void SubMesh::SetIndexBuffer(IndexBuffer* ibo)
  84. {
  85. m_ibo = ibo;
  86. }
  87. void SubMesh::AddTexture(const char* name, Texture* texture)
  88. {
  89. m_textures.push(String(name), texture);
  90. }
  91. void SubMesh::Render()
  92. {
  93. int vertex_count = 0;
  94. for (int i = 0; i < m_vbos.count(); ++i)
  95. {
  96. ShaderAttrib attribs[12];
  97. if (m_vbos[i] == nullptr)
  98. {
  99. msg::error("trying to render a mesh with a null VBO\n");
  100. continue;
  101. }
  102. int usages[VertexUsage::MAX] = { 0 };
  103. VertexStreamBase stream = m_vdecl->GetStream(i);
  104. for (int j = 0; j < stream.GetStreamCount(); ++j)
  105. {
  106. VertexUsage usage = stream.GetUsage(j);
  107. int usage_index = usage.ToScalar();
  108. attribs[j] = m_shader->GetAttribLocation(usage, usages[usage_index]++);
  109. }
  110. vertex_count += m_vbos[i]->GetSize() / m_vdecl->GetStream(i).GetSize();
  111. m_vdecl->SetStream(m_vbos[i], attribs);
  112. }
  113. UNUSED(vertex_count);
  114. for (int i = 0; i < m_textures.count(); ++i)
  115. {
  116. // TODO: might be good to cache this
  117. ShaderUniform u_tex = m_shader->GetUniformLocation(m_textures[i].m1.C());
  118. m_shader->SetUniform(u_tex, m_textures[i].m2->GetTextureUniform(), i);
  119. }
  120. m_ibo->Bind();
  121. m_vdecl->Bind();
  122. m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, m_ibo->GetSize() / sizeof(uint16_t));
  123. m_vdecl->Unbind();
  124. m_ibo->Unbind();
  125. }
  126. } /* namespace lol */