Добрый день,
Проблема в том, что код, написанный на Win7 (C #, VS2010), который отображает мозаичную сетку OpenGL, по-разному отображается в Mac OS X (C #, MonoDevelop). Каждая плитка в данный момент отображается отдельно, а смещение x / y фактически сохраняется в информации о вершине. Плитка построена так:
private void BuildTile()
{
Vector3[] vertices = new Vector3[4];
Vector2[] uvs = new Vector2[] { new Vector2(0, 1), new Vector2(0, 0), new Vector2(1, 1), new Vector2(1, 0) };
int[] indices = new int[] { 1, 0, 2, 1, 2, 3 };
// build vertex list based on position
vertices[0] = new Vector3(Location.X, Location.Y + 1, 0);
vertices[1] = new Vector3(Location.X, Location.Y, 0);
vertices[2] = new Vector3(Location.X + 1, Location.Y + 1, 0);
vertices[3] = new Vector3(Location.X + 1, Location.Y, 0);
VBO<Vector3> vertex = new VBO<Vector3>(vertices, BufferTarget.ArrayBuffer, BufferUsageHint.StaticRead);
VBO<Vector2> uv = new VBO<Vector2>(uvs, BufferTarget.ArrayBuffer, BufferUsageHint.StaticRead);
VBO<int> element = new VBO<int>(indices, BufferTarget.ElementArrayBuffer, BufferUsageHint.StaticRead);
VAO = new VAO(ShaderProgram, vertex, uv, element);
}
Поскольку Mac OS X не поддерживает OpenGL 3, объект VAO связывает атрибуты каждый раз, когда происходит вызов отрисовки.
public void BindAttributes()
{
if (vertex == null) throw new Exception("Error binding attributes. No vertices were supplied.");
if (element == null) throw new Exception("Error binding attributes. No element array was supplied.");
uint array = 0;
Gl.EnableVertexAttribArray(array);
Gl.BindAttribLocation(Program.ProgramID, array, "in_position");
Gl.BindBuffer(vertex.BufferTarget, vertex.vboID);
Gl.VertexAttribPointer(array++, vertex.Size, vertex.PointerType, true, 12, new IntPtr(0));
Gl.EnableVertexAttribArray(array);
Gl.BindAttribLocation(Program.ProgramID, array, "in_uv");
Gl.BindBuffer(uv.BufferTarget, uv.vboID);
Gl.VertexAttribPointer(array++, uv.Size, uv.PointerType, true, 8, new IntPtr(0));
Gl.BindBuffer(BufferTarget.ElementArrayBuffer, element.vboID);
}
Шейдер довольно прямой. Вершинный шейдер:
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
attribute vec3 in_position;
attribute vec2 in_uv;
varying vec2 uv;
void main(void)
{
uv = in_uv;
gl_Position = projection_matrix * modelview_matrix * vec4(in_position, 1);
}
Фрагмент шейдера:
uniform sampler2D active_texture;
varying vec2 uv;
void main(void)
{
gl_FragColor = texture2D(active_texture, uv);
}
Проблема в том, что версия Mac OS X перекрывает все плитки. Все 100 плиток будут уложены друг на друга в положении первой плитки. Однако на Win7 плитки будут распределены в сетке 10x10, как и ожидалось. У кого-нибудь есть идеи, почему это может происходить? Я посмотрел на данные вершин, и они хранят смещения как в Mac OS X, так и в Win7, и идентификаторы VBO уникальны, и правильные VBO привязываются. Я предполагаю, что должна быть проблема с моим методом для привязки атрибутов, но я не вижу проблемы. Есть ли некоторая забавная разница между тем, как OpenGL 2 и 3 обрабатывают атрибуты вершин?
Спасибо, и дайте мне знать, если вам нужен мой код, чтобы помочь мне найти проблему.
Примечание: я могу сохранить смещение вершин в шейдере (как униформу) и обновить его для каждой плитки. Это работает! Итак, я склонен полагать, что только первый VBO привязан, и просто воспроизводится 100 раз.