OpenGL a GLSL / Shader

0

Ktoś może dysponuje jakimś podstawowym tutorialem co można zrobić za pomocą GLSL w OpenGL ?

1

To samo co za pomocą HLSL, a czasem nawet więcej (niestandardowe rozszerzenia). Weź bylejaki tutorial o shaderach i poczytaj.

0

Trochę jestem przysypany nową wiedzą z zakresu OpenGL
wiec ciężko mi to wszystko ogarnąć.

Jezeli rysuje np.

  glBegin(GL_QUAD_STRIP);
      glTexCoord2f(0,0);
         glVertex2f(100,100); 
      glTexCoord2f(1,0);
        glVertex2f(800,100);
      glTexCoord2f(0,1);
         glVertex2f(100,800); 
      glTexCoord2f(1,1);
        glVertex2f(800,800);
   glEnd();

To co program GLSL jest w stanie zrobić ?
Jaki zakres działania ma program GLSL czy to jest tylko dla konkretnych wierzchołków czy też dla wszystkich ?

1

Program w GLSL działa, aż go nie wyłączysz. Włączasz go glUseProgram(idProgramu), wyłączasz za pomocą glUseProgram(idInnegoProgramu) lub glUseProgram(0) - to ostatnie "wyłącza" programowalny potok.

Są różne typy shaderów, dla OpenGL 2, masz dostępne Vertex Shadery, wywoływane dla każdego wierzchołka i Fragment Shadery, dla każdego piksela na ekranie. W najnowszych wersjach OpenGL są dostępne jeszcze Geometry Shadery (do generowania geometrii, np instancjonowania czy stencil shadows) - poziom DirectX 10, Tesselation Control Shaders i Tesselation Evaluation Shaders - poziom DirectX 11.

Ja na uczelni uczyłem się najpierw stałego potoku i pomagałem sobie tutorialami NeHe. Jednak łączenie stałego potoku z programowalnym jest wg mnie irytujące, a w ogóle jest przestarzałe i należy się przesiąść na w pełni programowalny potok (bo ten stały i tak jest emulowany na poziomie sterowników za pomocą shaderów).

Tu jest trochę ciekawych rzeczy:
http://www.songho.ca/opengl/index.html

A gdybym teraz się uczył OpenGLa to chyba bym po prostu ściągnął specyfikację najnowszej wersji i całą przeczytał.
http://www.opengl.org/registry/

Poszukaj też w Google "GPU Gems".

0

Tak pójść na perę wykładów by się zdało :)
Ale podsunąłeś mi pomysł aby poszukać materiałów dla studentów.

Pytanie czy w ogolę potrzebuje GLSL ? Bo może można to zrobić łatwiej ?
Muszę wyświetlić teksturę tylko w takich miejscach gdzie druga tekstura pod spodem ma wartości <od do="do"> albo powyżej lub poniżej pewnej wartosci.

Przykład:
**Tekstura1 **wymiary 4x4
**Tekstura2 **wymiary 8x8

Obie są wyświetlone na ekranie powiedzmy w prostokącie (współrzędne na ekranie komputera)
(0,0) (100,0)
(0,200) (100,200)

Obie tektury są wygładzane za pomocą opcji GL_LINEAR

Jak teraz wyświetlić **Textura2 **tylko w takich pikselach gdzie interpolowana wartość rozciągniętej **Tekstura1 **ma powyżej pewnej wartości.
Albo jest z jakiegoś przedziału.

Czy jasno nakreśliłem o co mi chodzi ?

0

Żaden sensowny pomysł (z wykluczeniem GLSLa) nie przychodzi mi do głowy. No chyba, że te wartości <od do="do"> są stałe w czasie działania programu, to wtedy możesz sobie na CPU obliczyć maskę przezroczystości.

0
Wibowit napisał(a)

Żaden sensowny pomysł (z wykluczeniem GLSLa) nie przychodzi mi do głowy. No chyba, że te wartości <od do="do"> są stałe w czasie działania programu, to wtedy możesz sobie na CPU obliczyć maskę przezroczystości.

Przez maskę rozumiesz teksturę z kanałem alpha ? Ale to ma być maska o wymiarach tekstury czy obrazu wynikowego ?
Jak tekstury to po powiększeniu będą kwadraty

A jak to zrobić w GLSL , Byś wiedział ?

0

Kanał alpha też może być rozciągany/ wygładzany. Maska (kanał alpha) wystarczy jak będzie miała taki sam rozmiar jak źródłowa tekstura, przecież i tak OpenGL wszystko sobie rozciągnie.

W GLSL użyłbym najpierw multiteksturowania, zapodał obydwie tekstury do fragment shadera i zrobił w nim zwykłego ifa (i użył słowa kluczowego discard).

0

W weekend byłą zażarta walka ale sie udało wszystko.

Dużym problemem było to że nie znałem wszystkich funkcji OpenGL
a to co jest w OpenGL.pas to niestety trochę mało. Najlepiej używać
http://wiki.delphigl.com/index.php/dglOpenGL.pas/en

Jakimś dziwnym zbiegiem okoliczności wszystkie tutoriale dotyczące teksturowania używały funkcji
glTexCoord2f
a żeby w shader użyć dwóch tekstur należało zastosować **glMultiTexCoord2f **
;)

Rożnicą rozmiarów tekstur jest bez znaczenia bo dla każdego wierzchołka różne tekstury mogą mieć inne rozmiary i inne współrzędne w teksturze.

// moj vertex shader 
void main(void)
{
  gl_Position = ftransform();
  gl_TexCoord[0] = gl_MultiTexCoord0;
  gl_TexCoord[1] = gl_MultiTexCoord1;
}
// fragment shader 
uniform float kolor_min;
uniform float kolor_max;
uniform sampler2D Texture0;
uniform sampler2D Texture1;
void main (void)
{
  vec4  c0,c1;

  c0 = texture2D(Texture0, vec2(gl_TexCoord[0]));
  c1 = texture2D(Texture1, vec2(gl_TexCoord[1]));

  if(c0.r > kolor_max ) 
  {
    gl_FragColor = c0;
  }
  else
  {
    if(c1.g>kolor_min)
    {
      gl_FragColor = c0+c1;
    }
    else
    {
      gl_FragColor = c0;
    } 
  }
}

I to w sumie wszystko proste jak budowa cepa jak juz się wie jak to uruchomić.

Jak ktoś zainteresowany to mogę zapodać kompletny projekt w delphi

Jedyne czego na razie nie rozumiem co taki kawałek kodu po stronie delphi

Bo po załadowaniu programu przekazuje tekstury jako parametry do shader-a

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, a_tex0);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, a_tex1);

glUniform1iARB(glGetUniformLocationARB(g_program, 'Texture0'), 0);
glUniform1iARB(glGetUniformLocationARB(g_program, 'Texture1'), 1);

Ale po tym kawałku kodu miejsca w których używałem innych tekstur
używały do rysowania a_tex1 chociaż w kodzie było np.
glBindTexture(GL_TEXTURE_2D, a_tex4);

Dopiero wywołanie
glActiveTexture(GL_TEXTURE0);
Spowodowało że wszystko wróciło do normy.

To samo z aktualizacją tekstur
jeżeli chce zaktualizować a_tex0 to musi być
glActiveTexture(GL_TEXTURE0); przed modyfikacją tekstury

Jezeli chcę zaktualizować a_tex1
to musze wcześniej wywołać glActiveTexture(GL_TEXTURE1);

To mnie trochę zastanawia co w takim razie wybiera aktualną teksturę ?
glActiveTexture czy glBindTexture i czym to się różni ?

0

OpenGL to maszyna stanów, jak coś ustawisz to jest takie, aż tego nie zmienisz. Więc jak dasz ActiveTexture na Texture5 to potem wszystkie następne BindTexture będą dotyczyć Texture5, chyba że zmienisz ActiveTexture z powrotem na to co było.

Nie chce mi się dokładnie analizować twojego przypadku, ale zastanów się sam. Myślę, że do czegoś dojdziesz (np do tego, że maszyna stanów to chory pomysł).
;)

0

Na początku maszyna stanów rzeczywiście byłą upierdliwa i trochę sie dziwiłem, ale jak człowiek zakodował sobie że co włączyłem to muszę wyłączyć
(aby np. wszystkie linie w programie nie były kreskowane) to już z górki.
Czy to jest wada czy zaleto to w sumie za krótko jestem w temacie OpenGL aby się wypowiadać na pewno ciekawe doświadczenie

1 użytkowników online, w tym zalogowanych: 0, gości: 1