Skip to content

Commit

Permalink
ECS: re-implement mesh rendering in database entries (#2140)
Browse files Browse the repository at this point in the history
* Use MeshRenderSystem::render3D as a starting point

- Total duplication of the code there.  Will extract soon, if appropriate

* Store greatest vertex distance from mesh center

* Scale models to fit within database render view

* Extract a few common behaviors as a test

* Remove logging and commented code

* Add reminder comments for inverted matrix

* Remove unused commented code

The same projection is happening already a few lines above

* Group remaining behavior into functions

These functions are somewhat arbitrary, but might be a
good starting point for a final form.  Providing these
functions from rendering.h is still only temporary.

* Use overload instead of attempted 'optional'

My reflexes were for optional arguments, but an overload seems more
correct.

* Adjust where we scale and translate

This seems to give a better result for a large variety of different original
model scales.  E.g. average vertex from 'center' of Atlantis is 30-40 whereas
an MP52 is 1ish.

* Offset model distance by near-z clip boundary

* Clean up duplicate commented code

* Pass entity instead of mesh to render view

This isn't necessary to render the mesh, but it will be useful
when trying to look up beam emitter and engine emitters to
render in debug mode

* Don't flip the matrix twice

* drop out of `onDraw` if we can't load the mesh

* Ensure no change to GL settings from previous

When copying behavior from viewport3D we adopted some behavior
from it that doesn't seem necessary for this view

* Rename 'mesh' to 'mrc'

* Replace ensureLoaded with 'getters'

* Clarify comment

* Return to original conditional style

* Fix spacing

* Simplify logic with glm:vec3
  • Loading branch information
kzsh authored Aug 22, 2024
1 parent 046329d commit fa060c9
Show file tree
Hide file tree
Showing 10 changed files with 262 additions and 144 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ set(MAIN_SOURCES
src/components/radar.h
src/components/hull.h
src/components/rendering.h
src/components/rendering.cpp
src/components/docking.h
src/components/coolant.h
src/components/shipsystem.h
Expand Down
32 changes: 32 additions & 0 deletions src/components/rendering.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "mesh.h"
#include "textureManager.h"
#include "rendering.h"

Mesh* MeshRenderComponent::getMesh()
{
if (!mesh.ptr && !mesh.name.empty())
mesh.ptr = Mesh::getMesh(mesh.name);
return mesh.ptr;
}

sp::Texture* MeshRenderComponent::getTexture()
{
if (!texture.ptr && !texture.name.empty())
texture.ptr = textureManager.getTexture(texture.name);
return texture.ptr;
}

sp::Texture* MeshRenderComponent::getSpecularTexture()
{
if (!specular_texture.ptr && !specular_texture.name.empty())
specular_texture.ptr = textureManager.getTexture(specular_texture.name);
return specular_texture.ptr;
}

sp::Texture* MeshRenderComponent::getIlluminationTexture()
{
if (!illumination_texture.ptr && !illumination_texture.name.empty())
illumination_texture.ptr = textureManager.getTexture(illumination_texture.name);
return illumination_texture.ptr;
}

7 changes: 6 additions & 1 deletion src/components/rendering.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
#include <memory>

#include "io/dataBuffer.h"

#include "graphics/texture.h"
#include "mesh.h"
#include "shaderRegistry.h"
Expand All @@ -26,6 +26,11 @@ class MeshRenderComponent
TextureRef illumination_texture;
glm::vec3 mesh_offset{};
float scale = 1.0;

Mesh* getMesh();
sp::Texture* getTexture();
sp::Texture* getSpecularTexture();
sp::Texture* getIlluminationTexture();
};

class EngineEmitter
Expand Down
45 changes: 34 additions & 11 deletions src/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,15 @@ Mesh::Mesh(std::vector<MeshVertex>&& unindexed_vertices)
glBindBuffer(GL_ARRAY_BUFFER, vbo_ibo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(MeshVertex) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, GL_NONE);

if (!indices.empty())
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_ibo[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_count * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_NONE);
}

greatest_distance_from_center = greatestDistanceFromCenter(vertices);
}
}

Expand All @@ -75,10 +77,10 @@ void Mesh::render(int32_t position_attrib, int32_t texcoords_attrib, int32_t nor

if (position_attrib != -1)
glVertexAttribPointer(position_attrib, 3, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), (void*)offsetof(MeshVertex, position));

if (normal_attrib != -1)
glVertexAttribPointer(normal_attrib, 3, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), (void*)offsetof(MeshVertex, normal));

if (texcoords_attrib != -1)
glVertexAttribPointer(texcoords_attrib, 2, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), (void*)offsetof(MeshVertex, uv));

Expand All @@ -89,12 +91,12 @@ void Mesh::render(int32_t position_attrib, int32_t texcoords_attrib, int32_t nor
glDrawElements(GL_TRIANGLES, face_count * 3, GL_UNSIGNED_SHORT, nullptr);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_NONE);
}

else
{
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(vertices.size()));
}

glBindBuffer(GL_ARRAY_BUFFER, GL_NONE);
}

Expand All @@ -114,7 +116,7 @@ glm::vec3 Mesh::randomPoint()
}
else
{

v0_index = static_cast<size_t>(irandom(0, static_cast<int>(vertices.size()) / 3 - 1)) * 3;
v1_index = v0_index + 1;
v2_index = v0_index + 2;
Expand All @@ -136,6 +138,27 @@ glm::vec3 Mesh::randomPoint()
return ret;
}

uint32_t Mesh::greatestDistanceFromCenter(std::vector<MeshVertex>& vertices)
{
if (vertices.empty()) {
return 0;
}

glm::vec3 sum{};
for(auto vertex : vertices) sum += glm::vec3{vertex.position[0], vertex.position[1], vertex.position[2]};
auto average = sum / float(vertices.size());

auto greatest_distance = 0.f;
for(auto vertex : vertices)
{
float distance = glm::distance(average, glm::vec3{vertex.position[0], vertex.position[1], vertex.position[2]});
if(distance > greatest_distance) {
greatest_distance = distance;
}
}
return greatest_distance;
}

struct IndexInfo
{
int v;
Expand Down Expand Up @@ -193,7 +216,7 @@ Mesh* Mesh::getMesh(const string& filename)
LOG(ERROR, "Bad normal line: ", line);
parsing_ok = false;
}

}else if (parts[0] == "vt")
{
if (parts.size() >= 3)
Expand All @@ -205,7 +228,7 @@ Mesh* Mesh::getMesh(const string& filename)
LOG(ERROR, "Bad vertex texcoord line: ", line);
parsing_ok = false;
}

}else if (parts[0] == "f")
{
if (parts.size() >= 4)
Expand Down Expand Up @@ -269,8 +292,8 @@ Mesh* Mesh::getMesh(const string& filename)
{
LOG(ERROR, "Failed to parse ", filename);
}


}else if (filename.endswith(".model"))
{
mesh_vertices.resize(readInt(stream));
Expand All @@ -285,6 +308,6 @@ Mesh* Mesh::getMesh(const string& filename)
meshMap[filename] = ret;
}


return ret;
}
5 changes: 5 additions & 0 deletions src/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@ class Mesh : sp::NonCopyable
gl::Buffers<2> vbo_ibo{ gl::Unitialized{} };
uint32_t face_count{};
public:
float greatest_distance_from_center{};
explicit Mesh(std::vector<MeshVertex>&& vertices);

void render(int32_t position_attrib, int32_t texcoords_attrib, int32_t normal_attrib);
glm::vec3 randomPoint();

// Calculate the center all vertices in this mesh, and return the distance
// of the point farthest from that center.
uint32_t greatestDistanceFromCenter(std::vector<MeshVertex>& vertices);

static Mesh* getMesh(const string& filename);
};

Expand Down
3 changes: 2 additions & 1 deletion src/screenComponents/databaseView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ void DatabaseViewComponent::display()

if (mrc)
{
//TODO: (new GuiRotatingModelView(visual, "DATABASE_MODEL_VIEW", selected_entry))->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);
(new GuiRotatingModelView(visual, "DATABASE_MODEL_VIEW", selected_entry))
->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);
if(database->image != "")
{
(new GuiImage(visual, "DATABASE_IMAGE", database->image))->setMargins(0)->setSize(32, 32);
Expand Down
Loading

0 comments on commit fa060c9

Please sign in to comment.