Использовать индекс в качестве координаты в OpenGL - PullRequest
5 голосов
/ 09 февраля 2011

Я хочу реализовать средство просмотра временных рядов, которое позволяет пользователю масштабировать и плавно перемещаться.

Ранее я уже работал в режиме непосредственного запуска opengl, но сейчас это не рекомендуется в пользу VBO.Все примеры VBO, которые я могу найти, хранят координаты XYZ каждой и каждой точки.

Я подозреваю, что мне нужно хранить все мои данные в VRAM, чтобы получить частоту кадров во время панорамирования, которую можно назвать "гладкой", но у меня есть только данные Y (зависимая переменная).X - независимая переменная, которая может быть рассчитана по индексу, а Z - постоянная.Если мне нужно сохранить X и Z, тогда мои требования к памяти (размер буфера и передача блока CPU-> GPU) утроятся.И у меня есть десятки миллионов точек данных, через которые пользователь может панорамировать, поэтому использование памяти будет нетривиальным.

Существует ли какой-либо метод для рисования 1-D вершинымассив, где индекс используется в качестве другой координаты, или для хранения одномерного массива (возможно, в текстуре?) и использования программы шейдера для генерации XYZ?У меня сложилось впечатление, что в любом случае мне нужен простой шейдер в рамках новой модели конвейера без фиксированных возможностей для реализации масштабирования и преобразования, поэтому, если бы я мог объединить генерацию координат X и Z и масштабирование / перевод Y, это было быидеально.

Возможно ли это вообще?Знаете ли вы какой-нибудь пример кода, который делает это?Или вы можете по крайней мере дать мне какой-нибудь псевдокод, говорящий о том, какие функции GL вызывать в каком порядке?

Спасибо!

РЕДАКТИРОВАТЬ: Чтобы убедиться, что это ясно, вот эквивалентный код непосредственного режима,и код массива вершин:

// immediate
glBegin(GL_LINE_STRIP);
for( int i = 0; i < N; ++i )
    glVertex2(i, y[i]);
glEnd();

// vertex array
struct { float x, y; } v[N];
for( int i = 0; i < N; ++i ) {
    v[i].x = i;
    v[i].y = y[i];
}
glVertexPointer(2, GL_FLOAT, 0, v);
glDrawArrays(GL_LINE_STRIP, 0, N);

обратите внимание, что v[] в два раза больше y[].

Ответы [ 2 ]

4 голосов
/ 10 февраля 2011

Это прекрасно для OpenGL.

Объекты Vertex Buffer (VBO) могут хранить любую информацию в любом формате, поддерживаемом GL.Вы можете заполнить VBO только одной координатой:

glGenBuffers( 1, &buf_id);
glBindBuffer( GL_ARRAY_BUFFER, buf_id );
glBufferData( GL_ARRAY_BUFFER, N*sizeof(float), data_ptr, GL_STATIC_DRAW );

, а затем привязать правильный формат атрибута вершины для рисования:

glBindBuffer( GL_ARRAY_BUFFER, buf_id );
glEnableVertexAttribArray(0);  // hard-coded here for the sake of example
glVertexAttribPointer(0, 1, GL_FLOAT, false, 0, NULL);

Для его использования вам понадобитсяпростая шейдерная программа.Вершинный шейдер может выглядеть следующим образом:

#version 130
in float at_coord_Y;

void main() {
    float coord_X = float(gl_VertexID);
    gl_Position = vec4(coord_X,at_coord_Y,0.0,1.0);
}

Перед тем, как связать шейдерную программу, вы должны связать его at_coord_Y с индексом атрибута, который вы будете использовать (= 0 в моем коде):

glBindAttribLocation(program_id,0,"at_coord_Y");

В качестве альтернативы, вы можете запросить у программы после привязки индекс, которому этот атрибут был автоматически назначен, и затем использовать его:

const int attrib_pos = glGetAttribLocation(program_id,"at_coord_Y");

Удачи!

0 голосов
/ 09 февраля 2011

Вы бы сохранили десять миллионов координат XY в VRAM?

Я бы посоветовал вычислить эти координаты на ЦП и передать их в конвейер шейдера в форме (поскольку координаты фиксируются на панорамированном изображении).

Не усложняйте.

...