2011-02-09 12 views
5

Chcę zaimplementować przeglądarkę Timeseries, która pozwala użytkownikowi na powiększanie i płynne przesuwanie.Użyj indeksu jako współrzędnej w OpenGL

Zrobiłem wcześniej tryb natychmiastowy opengl, ale teraz jest on przestarzały na rzecz VBO. Wszystkie przykłady VBO mogę znaleźć przechowywać współrzędne XYZ każdego punktu.

Podejrzewam, że muszę przechowywać wszystkie moje dane w pamięci VRAM, aby uzyskać szybkość klatek na sekundę podczas patelni, którą można nazwać "gładką", ale mam tylko dane Y (zmienną zależną). X jest niezależną zmienną, którą można obliczyć z indeksu, a Z jest stała. Jeśli mam przechowywać X i Z, to moje wymagania dotyczące pamięci (zarówno wielkość bufora, jak i transfer bloku CPU-> GPU) są potrojone. I mam dziesiątek milionów punktów danych, przez które użytkownik może przesuwać, więc użycie pamięci nie będzie banalne.

Czy jest jakaś technika do rysowania macierzy wierzchołków 1-D, gdzie indeks jest używany jako druga współrzędna, lub przechowywania tablicy 1-D (prawdopodobnie w strukturze?) I korzystania z programu cieniującego w celu wygenerowania XYZ? Mam wrażenie, że i tak potrzebuję prostego shadera w ramach nowego modelu rurociągu bez stałej cechy, aby zaimplementować skalowanie i tłumaczenie, więc gdybym mógł połączyć generację współrzędnych X i Z oraz skalowanie/tłumaczenie Y, które byłyby ideał.

Czy to możliwe? Czy znasz jakiś przykładowy kod, który to robi? Czy możesz przynajmniej podać mi pseudokod, mówiąc, do czego służy funkcja GL w jakiej kolejności?

Dzięki!

EDIT: Aby upewnić się, że jest to oczywiste, tutaj jest równoważny kod w trybie natychmiastowym, a kod vertex array:

// 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); 

nuta że v[] jest dwukrotnie większy od y[].

Odpowiedz

4

To jest w porządku dla OpenGL.

Obiekty bufora wierzchołków (VBO) mogą przechowywać dowolne informacje w jednym z obsługiwanych formatów GL. Można wypełnić VBO z tylko jednego współrzędnych:

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

A potem związać właściwego formatu atrybutu wierzchołek za remis:

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

Aby go użyć musisz prosty program cieniowania .Wierzchołek shader może wyglądać następująco:

#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); 
} 

Przed połączeniem programu cieniującego, należy powiązać to at_coord_Y indeksowi atrybutu będziesz używać (= 0 w kodzie):

glBindAttribLocation(program_id,0,"at_coord_Y"); 

Alternatywnie, można zwrócić się do programu po połączeniu do indeksu, do którego ten atrybut został przypisany automatycznie, a następnie użyć go:

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

powodzenia!

+0

Dzięki. Chyba nie jestem pewien, jak OpenGL wie, że chcę, aby 'coord_X' oznaczał indeks wierzchołka. –

+0

@Ben Voigt: Tęskniłem za tym początkowo, przepraszam :) Odpowiedź jest już naprawiona (przy użyciu gl_VertexID). – kvark

+0

Dzięki, teraz masz dużo więcej sensu. I mógłbym użyć 'glDrawArrays' do renderowania tego en-masse? Pytam, ponieważ [strona podręcznika dla 'glDrawArrays'] (http://www.opengl.org/sdk/docs/man/xhtml/glDrawArrays.xml) mówi:" Jeśli funkcja GL_VERTEX_ARRAY nie jest włączona, nie są generowane żadne prymitywy geometryczne. " Czy to nie ma zastosowania w świecie OpenGL 3, w którym wierzchołki są generowane przez moduł cieniujący? –

0

Czy można zapisać 10 milionów współrzędnych XY w pamięci VRAM?

Chciałbym zasugerować obliczenie tych współrzędnych na procesorze i przekazanie ich do potoku cieniującego jako jednolitych (ponieważ współrzędne są ustalone na panoramowanym obrazie).

Zachowaj to proste.

+0

Kiedy obracam, muszę usunąć niektóre segmenty linii z ekranu, które przesunęły się poza ekranem, dodać niektóre, które zostały ujawnione, a resztę skompensować przez stałą. Dodanie stałej do kilku tysięcy współrzędnych jest szybkie w CPU, ale muszę ponownie przesłać wszystkie dane do GPU i muszę to zrobić na każdej klatce, podczas gdy odbywa się panoramowanie. Ok, nawet przy 60 FPS to nie będzie tak duży kawał przepustowości PCIe, ale po co go marnować? Procesor graficzny może wykonywać obliczenia matematyczne równie łatwo, jeśli po prostu wyślę nowy najbardziej wysunięty indeks i nowe tłumaczenie, i może to zrobić równolegle. –

+0

Przepraszam, ale nie rozumiem twojego podejścia. Przesuwanie obrazu powinno być zaimplementowane poprzez przetłumaczenie teksturowanego kwadratu (większego niż rzutnia). Tekstura jest (prawdopodobnie) rezydentna, a jedyne dane to przesunięcie X/Y dla tłumaczenia teksturowanego kwadratu. Do wyświetlania wielu obrazów można użyć wielu quadów. – Luca

Powiązane problemy