// // Lol Engine // // Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net> // // Lol Engine is free software. It comes without any warranty, to // the extent permitted by applicable law. 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 the WTFPL Task Force. // See http://www.wtfpl.net/ for more details. // #include <lol/engine-internal.h> #include <cstring> #include <cstdlib> namespace lol { /* * Mesh class */ Mesh::Mesh() { } Mesh::~Mesh() { } void Mesh::Render(Scene& scene, mat4 const &matrix) { //if (scene.HasPrimitiveRenderer(this) < m_submeshes.count()) { for (int i = 0; i < m_submeshes.count(); ++i) scene.AddPrimitiveRenderer(this, new PrimitiveMesh(m_submeshes[i], matrix)); } } void Mesh::Render() { for (int i = 0; i < m_submeshes.count(); ++i) m_submeshes[i]->Render(); } void Mesh::SetMaterial(Shader *shader) { for (int i = 0; i < m_submeshes.count(); ++i) m_submeshes[i]->SetShader(shader); } /* * SubMesh class */ SubMesh::SubMesh(Shader *shader, VertexDeclaration *vdecl) : m_mesh_prim(MeshPrimitive::Triangles), m_shader(shader), m_vdecl(vdecl) { Ticker::Ref(m_shader); } SubMesh::~SubMesh() { Ticker::Unref(m_shader); // TODO: cleanup } void SubMesh::SetMeshPrimitive(MeshPrimitive mesh_primitive) { m_mesh_prim = mesh_primitive; } void SubMesh::SetShader(Shader *shader) { Ticker::Unref(m_shader); m_shader = shader; Ticker::Ref(m_shader); } Shader *SubMesh::GetShader() { return m_shader; } void SubMesh::SetVertexDeclaration(VertexDeclaration *vdecl) { m_vdecl = vdecl; } void SubMesh::SetVertexBuffer(int index, VertexBuffer* vbo) { while (index >= m_vbos.count()) m_vbos.push(nullptr); m_vbos[index] = vbo; } void SubMesh::SetIndexBuffer(IndexBuffer* ibo) { m_ibo = ibo; } void SubMesh::AddTexture(const char* name, Texture* texture) { m_textures.push(String(name), texture); } void SubMesh::Render() { int vertex_count = 0; for (int i = 0; i < m_vbos.count(); ++i) { ShaderAttrib attribs[12]; if (m_vbos[i] == nullptr) { msg::error("trying to render a mesh with a null VBO\n"); continue; } int usages[VertexUsage::MAX] = { 0 }; VertexStreamBase stream = m_vdecl->GetStream(i); for (int j = 0; j < stream.GetStreamCount(); ++j) { VertexUsage usage = stream.GetUsage(j); int usage_index = usage.ToScalar(); attribs[j] = m_shader->GetAttribLocation(usage, usages[usage_index]++); } vertex_count += m_vbos[i]->GetSize() / m_vdecl->GetStream(i).GetSize(); m_vdecl->SetStream(m_vbos[i], attribs); } UNUSED(vertex_count); for (int i = 0; i < m_textures.count(); ++i) { // TODO: might be good to cache this ShaderUniform u_tex = m_shader->GetUniformLocation(m_textures[i].m1.C()); m_shader->SetUniform(u_tex, m_textures[i].m2->GetTextureUniform(), i); } m_ibo->Bind(); m_vdecl->Bind(); m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, m_ibo->GetSize() / sizeof(uint16_t)); m_vdecl->Unbind(); m_ibo->Unbind(); } } /* namespace lol */