Merge pull request #83906 from clayjohn/GL-vertex-padding
Add padding to normal attribute in Compatibility renderer to match the RD renderers
This commit is contained in:
commit
2dafd06114
2 changed files with 22 additions and 3 deletions
|
@ -217,8 +217,23 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
|
|||
if (new_surface.vertex_data.size()) {
|
||||
glGenBuffers(1, &s->vertex_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer);
|
||||
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, new_surface.vertex_data.size(), new_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer");
|
||||
s->vertex_buffer_size = new_surface.vertex_data.size();
|
||||
// If we have an uncompressed surface that contains normals, but not tangents, we need to differentiate the array
|
||||
// from a compressed array in the shader. To do so, we allow the the normal to read 4 components out of the buffer
|
||||
// But only give it 2 components per normal. So essentially, each vertex reads the next normal in normal.zw.
|
||||
// This allows us to avoid adding a shader permutation, and avoid passing dummy tangents. Since the stride is kept small
|
||||
// this should still be a net win for bandwidth.
|
||||
// If we do this, then the last normal will read past the end of the array. So we need to pad the array with dummy data.
|
||||
if (!(new_surface.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && (new_surface.format & RS::ARRAY_FORMAT_NORMAL) && !(new_surface.format & RS::ARRAY_FORMAT_TANGENT)) {
|
||||
// Unfortunately, we need to copy the buffer, which is fine as doing a resize triggers a CoW anyway.
|
||||
Vector<uint8_t> new_vertex_data;
|
||||
new_vertex_data.resize_zeroed(new_surface.vertex_data.size() + sizeof(uint16_t) * 2);
|
||||
memcpy(new_vertex_data.ptrw(), new_surface.vertex_data.ptr(), new_surface.vertex_data.size());
|
||||
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, new_vertex_data.size(), new_vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer");
|
||||
s->vertex_buffer_size = new_vertex_data.size();
|
||||
} else {
|
||||
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, new_surface.vertex_data.size(), new_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer");
|
||||
s->vertex_buffer_size = new_surface.vertex_data.size();
|
||||
}
|
||||
}
|
||||
|
||||
if (new_surface.attribute_data.size()) {
|
||||
|
@ -461,6 +476,11 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
|
|||
sd.format = s.format;
|
||||
if (s.vertex_buffer != 0) {
|
||||
sd.vertex_data = Utilities::buffer_get_data(GL_ARRAY_BUFFER, s.vertex_buffer, s.vertex_buffer_size);
|
||||
|
||||
// When using an uncompressed buffer with normals, but without tangents, we have to trim the padding.
|
||||
if (!(s.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && (s.format & RS::ARRAY_FORMAT_NORMAL) && !(s.format & RS::ARRAY_FORMAT_TANGENT)) {
|
||||
sd.vertex_data.resize(sd.vertex_data.size() - sizeof(uint16_t) * 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (s.attribute_buffer != 0) {
|
||||
|
|
|
@ -591,7 +591,6 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const {
|
|||
sd.vertex_data = RD::get_singleton()->buffer_get_data(s.vertex_buffer);
|
||||
// When using an uncompressed buffer with normals, but without tangents, we have to trim the padding.
|
||||
if (!(s.format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && (s.format & RS::ARRAY_FORMAT_NORMAL) && !(s.format & RS::ARRAY_FORMAT_TANGENT)) {
|
||||
Vector<uint8_t> new_vertex_data;
|
||||
sd.vertex_data.resize(sd.vertex_data.size() - sizeof(uint16_t) * 2);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue