Commit b98a791f authored by Shu's avatar Shu 🍠
Browse files

Interleaved buffer

parent dc7c70d8
......@@ -144,7 +144,7 @@ namespace contouring {
it = bfs.erase(it);
} else {
if(it->second != NULL) {
static_cast<buffer::LodShortIndexed*>(it->second)->setLevel((1+lod_quality-distRatio)*levelMax*(1+lod_strength));
static_cast<buffer::LodShortIndexed*>(it->second)->setLevel(std::clamp<size_t>((1+lod_quality-distRatio)*levelMax*(1+lod_strength), 0, levelMax));
buffer_count++;
}
++it;
......@@ -208,18 +208,14 @@ namespace contouring {
auto &data = out.first;
data.vertices.reserve(dmc_vertices.size());
data.materials.reserve(dmc_vertices.size());
data.normals.reserve(dmc_vertices.size());
for (const auto& v: dmc_vertices) {
data.vertices.emplace_back(v.x, v.y, v.z);
data.materials.emplace_back(v.w);
data.normals.emplace_back(0);
}
std::transform(dmc_vertices.begin(), dmc_vertices.end(), std::back_inserter(data.vertices), [](const dualmc::Vertex &v) {
return buffer::VertexData(glm::vec3(v.x, v.y, v.z), v.w, glm::vec3(0));
});
data.indices.reserve(dmc_tris.size() * 3);
for (const auto& t: dmc_tris) {
glm::vec3 edge1 = data.vertices[t.i1] - data.vertices[t.i0];
glm::vec3 edge2 = data.vertices[t.i2] - data.vertices[t.i0];
glm::vec3 edge1 = data.vertices[t.i1].Position - data.vertices[t.i0].Position;
glm::vec3 edge2 = data.vertices[t.i2].Position - data.vertices[t.i0].Position;
glm::vec3 normal = glm::normalize(glm::cross(edge1, edge2));
if(!reordering || glm::length2(edge1) > glm::length2(edge2)) {
......@@ -232,13 +228,13 @@ namespace contouring {
data.indices.push_back(t.i1);
}
data.normals[t.i0] += normal;
data.normals[t.i1] += normal;
data.normals[t.i2] += normal;
data.vertices[t.i0].Normal += normal;
data.vertices[t.i1].Normal += normal;
data.vertices[t.i2].Normal += normal;
}
for (auto &n : data.normals) {
n = glm::normalize(n);
for(auto& v: data.vertices) {
v.Normal = glm::normalize(v.Normal);
}
out.second = simplify_lod(data.indices, dmc_vertices, loadedLevels);
......
......@@ -4,14 +4,8 @@
inline void optimize_fetch(buffer::ShortIndexed::Data& out) {
ZoneScopedN("Optimize");
std::vector<unsigned int> remap(out.indices.size());
size_t vertex_count = meshopt_optimizeVertexFetchRemap(&remap[0], out.indices.data(), out.indices.size(), out.vertices.size());
meshopt_remapIndexBuffer(out.indices.data(), out.indices.data(), out.indices.size(), &remap[0]);
meshopt_remapVertexBuffer(out.vertices.data(), out.vertices.data(), vertex_count, sizeof(glm::vec3), &remap[0]);
out.vertices.resize(vertex_count);
meshopt_remapVertexBuffer(out.normals.data(), out.normals.data(), vertex_count, sizeof(glm::vec3), &remap[0]);
out.normals.resize(vertex_count);
meshopt_remapVertexBuffer(out.materials.data(), out.materials.data(), vertex_count, sizeof(GLushort), &remap[0]);
out.materials.resize(vertex_count);
size_t vertex_count = meshopt_optimizeVertexFetch(out.vertices.data(), out.indices.data(), out.indices.size(), out.vertices.data(), out.vertices.size(), sizeof(buffer::VertexData));
out.vertices.resize(vertex_count, buffer::VertexData(glm::vec3(0), 0, glm::vec3(0)));
}
inline void optimize_buffer(buffer::ShortIndexed::Data& out) {
......@@ -19,7 +13,7 @@ inline void optimize_buffer(buffer::ShortIndexed::Data& out) {
// reorder indices for overdraw, balancing overdraw and vertex cache efficiency
const float kThreshold = 1.01f; // allow up to 1% worse ACMR to get more reordering opportunities for overdraw
meshopt_optimizeOverdraw(out.indices.data(), out.indices.data(), out.indices.size(), &out.vertices.front()[0], out.vertices.size(), sizeof(glm::vec3), kThreshold);
meshopt_optimizeOverdraw(out.indices.data(), out.indices.data(), out.indices.size(), &out.vertices.front().Position[0], out.vertices.size(), sizeof(buffer::VertexData), kThreshold);
// optimize_fetch(out);
}
......
......@@ -5,18 +5,9 @@
using namespace buffer;
ShortIndexed::Data::Data(const std::vector<VertexData> &vs, const std::vector<GLushort> &indices): indices(indices) {
vertices.reserve(vs.size());
materials.reserve(vs.size());
normals.reserve(vs.size());
for (auto vertex : vs) {
vertices.push_back(vertex.Position);
materials.push_back(vertex.Material);
normals.push_back(vertex.Normal);
}
}
ShortIndexed::Data::Data(const std::vector<VertexData> &vs, const std::vector<GLushort> &indices): indices(indices), vertices(vs) { }
void ShortIndexed::Data::index(const std::vector<VertexData>& vs) {
indexVBO(vs, indices, vertices, materials, normals);
indexVBO(vs, indices, vertices);
}
ShortIndexed::ShortIndexed(GLenum shape, const std::vector<VertexData> &vertices): Abstract(shape) {
......@@ -30,33 +21,42 @@ ShortIndexed::ShortIndexed(GLenum shape, const ShortIndexed::Data &data): Abstra
}
ShortIndexed::~ShortIndexed() {
glDeleteBuffers(1, &NormalBufferID);
glDeleteBuffers(1, &MaterialBufferID);
glDeleteBuffers(1, &IndexBufferID);
}
void ShortIndexed::enableVertexAttrib() {
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID);
glVertexAttribPointer(
0, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
sizeof(VertexData), // stride
reinterpret_cast<void *>(offsetof(VertexData, Position)) // array buffer offset
);
}
void ShortIndexed::enableAllAttribs() {
enableVertexAttrib();
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, MaterialBufferID);
glVertexAttribIPointer(
1, // attribute
1, // size
GL_UNSIGNED_SHORT, // type
0, // stride
(void *)0 // array buffer offset
1, // attribute
1, // size
GL_UNSIGNED_SHORT, // type
sizeof(VertexData), // stride
reinterpret_cast<void *>(offsetof(VertexData, Material)) // array buffer offset
);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, NormalBufferID);
glVertexAttribPointer(
2, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void *)0 // array buffer offset
2, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
sizeof(VertexData), // stride
reinterpret_cast<void *>(offsetof(VertexData, Normal)) // array buffer offset
);
}
void ShortIndexed::disableAllAttribs() {
......@@ -88,31 +88,18 @@ uint ShortIndexed::draw(buffer::params params) {
return IndexSize;
}
#include <iostream>
void ShortIndexed::setData(const ShortIndexed::Data& data) {
glGenBuffers(1, &IndexBufferID);
glGenBuffers(1, &MaterialBufferID);
glGenBuffers(1, &NormalBufferID);
IndexSize = data.indices.size();
if(IndexSize != data.indices.size()) {
LOG_E("ShortBuffer overflow: " << data.indices.size());
}
setIndicies(IndexSize * sizeof(GLushort), &data.indices[0]);
setVertices(data.vertices.size() * sizeof(glm::vec3), &data.vertices[0]);
setMaterials(data.materials.size() * sizeof(GLushort), &data.materials[0]);
setNormals(data.normals.size() * sizeof(glm::vec3), &data.normals[0]);
setIndicies(IndexSize * sizeof(GLushort), data.indices.data());
setVertices(data.vertices.size() * sizeof(VertexData), data.vertices.data());
}
void ShortIndexed::setIndicies(const unsigned long size, const void *data) {
glBindBuffer(GL_ARRAY_BUFFER, IndexBufferID);
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
}
void ShortIndexed::setMaterials(const unsigned long size, const void *data) {
glBindBuffer(GL_ARRAY_BUFFER, MaterialBufferID);
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
}
void ShortIndexed::setNormals(const unsigned long size, const void *data) {
glBindBuffer(GL_ARRAY_BUFFER, NormalBufferID);
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
}
\ No newline at end of file
......@@ -14,9 +14,7 @@ namespace buffer {
/// Preindexed buffer data
struct Data {
std::vector<GLushort> indices;
std::vector<glm::vec3> vertices;
std::vector<GLushort> materials;
std::vector<glm::vec3> normals;
std::vector<VertexData> vertices;
Data() { }
Data(const std::vector<VertexData> &vertices, const std::vector<GLushort> &indices);
......@@ -29,8 +27,6 @@ namespace buffer {
void clear() {
indices.clear();
vertices.clear();
materials.clear();
normals.clear();
}
};
......@@ -42,6 +38,7 @@ namespace buffer {
uint draw(params params) override;
protected:
void enableVertexAttrib();
void enableAllAttribs();
void disableAllAttribs();
void enableIndex();
......@@ -49,14 +46,8 @@ namespace buffer {
private:
GLuint IndexBufferID;
GLuint MaterialBufferID;
GLuint NormalBufferID;
void setData(const ShortIndexed::Data &data);
void setIndicies(const unsigned long size, const void *data);
void setMaterials(const unsigned long size, const void *data);
void setNormals(const unsigned long size, const void *data);
};
}
......@@ -32,48 +32,11 @@ bool getSimilarVertexIndex_fast(
}
}
void indexVBO(
std::vector<glm::vec3> &in_vertices,
std::vector<GLushort> &in_materials,
std::vector<glm::vec3> &in_normals,
std::vector<unsigned int> &out_indices,
std::vector<glm::vec3> &out_vertices,
std::vector<GLushort> &out_materials,
std::vector<glm::vec3> &out_normals)
{
std::map<buffer::VertexData,unsigned int> VertexToOutIndex;
out_indices.reserve(in_vertices.size());
// For each input vertex
for (unsigned int i = 0; i < in_vertices.size(); i++) {
buffer::VertexData packed = {in_vertices[i], in_materials[i], in_normals[i]};
// Try to find a similar vertex in out_XXXX
unsigned int index;
bool found = getSimilarVertexIndex_fast( packed, VertexToOutIndex, index);
if ( found ){ // A similar vertex is already in the VBO, use it instead !
out_indices.push_back( index );
}else{ // If not, it needs to be added in the output data.
out_vertices.push_back( in_vertices[i]);
out_materials.push_back( in_materials[i]);
out_normals.push_back( in_normals[i]);
unsigned int newindex = (unsigned int)out_vertices.size() - 1;
out_indices.push_back( newindex );
VertexToOutIndex[ packed ] = newindex;
}
}
}
void indexVBO(
const std::vector<buffer::VertexData> &in_vertices,
std::vector<GLushort> &out_indices,
std::vector<glm::vec3> &out_vertices,
std::vector<GLushort> &out_materials,
std::vector<glm::vec3> &out_normals)
std::vector<buffer::VertexData> &out_vertices)
{
std::map<buffer::VertexData, GLushort> VertexToOutIndex;
......@@ -87,9 +50,7 @@ void indexVBO(
if ( found ){ // A similar vertex is already in the VBO, use it instead !
out_indices.push_back( index );
}else{ // If not, it needs to be added in the output data.
out_vertices.push_back( in_vertices[i].Position);
out_materials.push_back( in_vertices[i].Material);
out_normals.push_back( in_vertices[i].Normal);
out_vertices.push_back(in_vertices[i]);
GLushort newindex = (GLushort)out_vertices.size() - 1;
out_indices.push_back( newindex );
VertexToOutIndex[ in_vertices[i] ] = newindex;
......
......@@ -6,22 +6,10 @@
#include "VertexData.hpp"
#include <GL/glew.h>
void indexVBO(
std::vector<glm::vec3> &in_vertices,
std::vector<GLushort> &in_materials,
std::vector<glm::vec3> &in_normals,
std::vector<unsigned int> &out_indices,
std::vector<glm::vec3> &out_vertices,
std::vector<GLushort> &out_materials,
std::vector<glm::vec3> &out_normals);
void indexVBO(
const std::vector<buffer::VertexData> &in_vertices,
std::vector<GLushort> &out_indices,
std::vector<glm::vec3> &out_vertices,
std::vector<GLushort> &out_materials,
std::vector<glm::vec3> &out_normals);
std::vector<buffer::VertexData> &out_vertices);
#endif
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment