Closed GoogleCodeExporter closed 9 years ago
There's something strange with code you copy/pasted, because it looks to me
that you're using ozz::sample::Renderer::Mesh, but you're talking about
ozz::sample::SkinnedMesh. I might be a bit confused with all the changes going
on, could you clarify what mesh type you're using?
Anyway, I don't see the issue in that code. I reproduced it in skin sample and
got no issue either, as you can see on the attached screen shot.
You can find below the code I tested. It's very close to what you sent except
the mesh type.
#define NEXT(_type, _current, _stride) \
reinterpret_cast<_type>(reinterpret_cast<uintptr_t>(_current) + _stride)
{
int x = 0; int y = 0;
int vertCount = 100 * 100;
ozz::sample::Renderer::Mesh* renderMesh
= new ozz::sample::Renderer::Mesh(vertCount, vertCount);
// Fill up position buffer
ozz::sample::Renderer::Mesh::Positions posBuffer = renderMesh->positions();
float* out_position = posBuffer.data.begin;
// .. And colour buffer
ozz::sample::Renderer::Mesh::Colors colBuffer = renderMesh->colors();
ozz::sample::Renderer::Mesh::Color* out_color = colBuffer.data.begin;
// .. And normal buffer
ozz::sample::Renderer::Mesh::Normals normBuffer = renderMesh->normals();
float* out_normal = normBuffer.data.begin;
for (y = 0; y < 100; y += 1) {
for (x = 0; x < 100; x += 1) {
// Positions
out_position[0] = x;
out_position[1] = 0.f;
out_position[2] = y;
// Colors
out_color->red = 255;
out_color->green = 0;
out_color->blue = 0;
out_color->alpha = 255; // 1.f;
// Normals
//out_normal[0] = 0.f;
//out_normal[1] = 1.f;
//out_normal[2] = 0.f;
// Increment ptrs
out_position = NEXT(float*, out_position, posBuffer.stride);
out_color = NEXT(ozz::sample::Renderer::Mesh::Color*, out_color, colBuffer.stride);
out_normal = NEXT(float*, out_normal, normBuffer.stride);
}
}
// .. And indices buffer
ozz::sample::Renderer::Mesh::Indices indiBuffer = renderMesh->indices();
uint16_t* out_indices = indiBuffer.data.begin;
for (int i = 0; i < vertCount; i++) {
out_indices[0] = i;
out_indices = NEXT(uint16_t*, out_indices, indiBuffer.stride);
}
_renderer->DrawMesh(ozz::math::Float4x4::identity(), *renderMesh);
Also I'd like to mention that ozz::sample::Renderer::Mesh will be removed in a
next release. I'll either expose dynamic vertex buffers from the
sample::Renderer interface, or use ozz::sample::SkinnedMesh (renamed to
ozz::sample::Mesh). The idea behind that is to make skinning sample closer to a
real world case. Hope it's not going to be too much of an issue.
Original comment by guillaum...@gmail.com
on 22 Jan 2015 at 9:27
Attachments:
Sorry, you're correct I am using ozz::sample::Renderer::Mesh (slightly renamed
a few things for my own benefit - I was getting confused).
I notice in the code sample above you're implementing my code sample with 100 x
100 verts - that was something I hadn't tried.
With 100 x 100 verts the code seems to work fine, but I'm dealing with larger
values. Anything above ~300 stops working, and the values I have been using are
1024x1024. I have attached images to demonstrate this.
If you see the 400x400.png, I'm sure you will have already guessed this, but I
am putting values of 400 width and 400 height into the code - the outcome
should be square but it's actually a rectangle.
Original comment by ThomasBu...@gmail.com
on 23 Jan 2015 at 8:44
Attachments:
Aha! Slowly tracking the issue down!
It appears that when the item is being rendered the value returned from
ozz::Range::Size() appears to be wrong.
The following code taken from the ozz shader class is returning a drastically
wrong value:
const GLsizei index_vbo_size = static_cast<GLsizei>(indices_buffer.data.Size());
Original comment by ThomasBu...@gmail.com
on 23 Jan 2015 at 8:57
indices_buffer.data.Size() returns the difference between the begin/end
pointers. So for 400x400, buffer size will be 400*400*2 (because indices are
uint16_t -> 2 bytes), which is 320000 bytes. What do you see in index_vbo_size?
Anyway the important thing there is that indices are uint16_t, which have a
maximum value of 65535.
200x200 = 40000 < 65535 -> ok
400x400 = 160000 > 65535 -> overflow !!!
I'd say that for a 400x400 grid, you actually have a 400x164 points rendered.
Hope it helps,
Guillaume
Original comment by guillaum...@gmail.com
on 23 Jan 2015 at 9:18
Wow- Can't believe I hadn't noticed that.
Might be worth considering bumping that up to a uint32_t? - Limiting mesh's to
an indicies count of 65k seems a bit restrictive, even if most models come in
way under that count.
As always, thanks for the help
Original comment by ThomasBu...@gmail.com
on 23 Jan 2015 at 11:32
Switching to uint32_t does not mean you can use the full 32bits range. There
are other limits that depend on your hardware/driver like the maximum index or
maximum vertex count. You can querry the 2 with
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, ...) and
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, ...).
So in case of overflow I would rather split meshes, or draw in multiple draw
calls.
Cheers,
Guillaume
Original comment by guillaum...@gmail.com
on 24 Jan 2015 at 10:41
Original comment by guillaum...@gmail.com
on 25 Jan 2015 at 9:53
Original issue reported on code.google.com by
ThomasBu...@gmail.com
on 22 Jan 2015 at 11:14