WedX - журнал о программировании и компьютерных науках

Различия VBO между OS X и Win7?

Добрый день,

Проблема в том, что код, написанный на 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 раз.


Ответы:


1

Получается, что нельзя привязать расположение атрибута после линковки программы. Однако по какой-то причине мой компьютер с Win7 (с драйверами Radeon) решил разрешить это. Вот как вы должны на самом деле связать свои атрибуты.

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 loc = (uint)Gl.GetAttribLocation(Program.ProgramID, "in_position");
    Gl.EnableVertexAttribArray(loc);
    Gl.BindBuffer(vertex.BufferTarget, vertex.vboID);
    Gl.VertexAttribPointer(loc, vertex.Size, vertex.PointerType, true, 12, new IntPtr(0));


    loc = (uint)Gl.GetAttribLocation(Program.ProgramID, "in_uv");
    Gl.EnableVertexAttribArray(loc);
    Gl.BindBuffer(uv.BufferTarget, uv.vboID);
    Gl.VertexAttribPointer(loc, uv.Size, uv.PointerType, true, 8, new IntPtr(0));

    Gl.BindBuffer(BufferTarget.ElementArrayBuffer, element.vboID);
}
17.01.2011
  • Это не Windows 7, это драйвер IHV, который отвечает за реализацию OpenGL. 17.01.2011
  • Справедливо. Бывает так, что на компьютерах стоят видеокарты разных производителей. Спасибо 17.01.2011
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]