Jump to content

[OpenGL] Efekt połyskujących krawędzi


Brainer

Recommended Posts

Witam.

 

Chciałbym napisać sobie (w oparciu o mój silnik ^^) mały programik, który wyświetla naszą planetę, gwiazdy i w ogóle kosmos. :) Tak więc skodziłem już sobie podstawy (kosmiczne niebo, planeta Ziemia), ale chciałbym dowiedzieć się, w jaki sposób mogę osiągnąć efekt przedstawiony na tym rysunku (chodzi o otoczkę wokół planety).

 

Myślałem coś o algorytmach wykrywania krawędzi - z tego, co słyszałem, jest kilka dostępnych. Ale może jest inny sposób? Bardzo prosiłbym o wyjaśnienie problemu.

 

Pozdrawiam. :)

Link to comment
Share on other sites

Pomysł dobry, tylko nie wiem, jak takowy shader napisać. :( Poza tym, renderowanie dwóch kul może wpłynąć na wydajność, zwłaszcza, że ta atmosfera musi mieć tyle samo ścianek co pierwsza kula.

 

Inny pomysł, który mi podsunięto, to rysowanie kwadratu z teksturą połysku. Koleś podesłał kod:

procedure TForm1.Timer1Timer(Sender: TObject);
const A_rad = 1.33;
var mat: TMatrix;
begin
 nxClear(true,true);

 glLoadIdentity;
 glTranslatef(0,0,-4);
 glRotatef(GetTickCount*0.02,0,1,0);

 // Planet
 glEnable(GL_DEPTH_TEST);
 tex.SetTex(-1);
 glColor3f(0.2,0.2,0.2);
 gluSphere(sphere,1,30,30);
 glDisable(GL_DEPTH_TEST);

 // Atmosphere effect
 glDisable(GL_LIGHTING);
 tex.SetTex(0);
 AddBlend(true);
 glColor3f(0.4,0.6,1);
 glGetfloatv(GL_MODELVIEW_MATRIX,@mat);
 MatrixInvert(mat);
 mat[3,0]:=0;
 mat[3,1]:=0;
 mat[3,2]:=0;
 glMultMatrixf(@mat);
 RectT(A_rad,-A_rad,-A_rad,A_rad);
 AddBlend(false);
 glEnable(GL_LIGHTING);

 nxFlip;
end; 

Ale coś to kurdę nie chce działać. :-/ Nie mam pojęcia czemu, nic się nie wyświetla, a w jego przypadku wszystko cacy - tutaj screen.

 

W czym może być problem? :unsure:

Link to comment
Share on other sites

Witam!

Nie wyswietla sie obiekt czy scena znika ?

na moje brakuje glPushMatrix przed rysowaniem tego obiektu i glPopMatrix po narysowaniu :)

 

 

Też bym polecił zainteresować się bilboardami ale tutaj widzę jakieś błędy przez co do końca nie rozumiem co autor kodu miał na myśli czyszcząc 3 wartości macierzy odpowiedzialne w dodatku za przesunięcie zamiast rotację ... nieważne:D

ja bym ten kod od macierzy podmienił na taki:

 

KOD

mat[0,0]:=1; mat[0,1]:=0; mat[0,2]:=0;

mat[1,0]:=0; mat[1,1]:=1; mat[1,2]:=0;

mat[2,0]:=0; mat[2,1]:=0; mat[2,2]:=1;

 

i powinno latać

Pozdrawiam i powodzenia :)

 

ekhm jeszcze coś : gdzie w swoim kodzie masz funkcje rysującą kwadrat bo nie widzę buhehehe xD

www.spider.dathox.com :)

Link to comment
Share on other sites

Mam jeszcze jeden mały problemik (przepraszam, że dwa posty pod sobą). Otóż wygląda na to, że coś w tym kodzie jest nie tak, bo cały ten połysk wydaje się tak jakby nie obejmować całej planety, tylko część. To jest widoczne zwłaszcza, gdy poruszy się kamerę. Tutaj daję screen do tego, może wtedy będzie jaśniej widać, o co chodzi.

 

W czym może być błąd? Próbowałem kodu z macierzami Spidera, ale wtedy w ogóle nie wyświetla się nic. Chyba, że źle coś robię, nie wiem. Poniżej daję kodzik jeszcze raz.

procedure TAtmosphere.DoRender;
var
 M: TMatrix;
begin
 if Assigned(FMatLib) then
 begin
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_LIGHTING);
   glEnable(GL_BLEND);

   if (FMatName <> '') then
     FMatLib.MaterialByName[FMatName].Apply()
   else
     FMatLib.Materials[FMatIdx].Apply();

   glBlendFunc(GL_SRC_ALPHA, GL_ONE);
   glColor3f(0.4, 0.6, 1.0);
   glGetFloatv(GL_MODELVIEW_MATRIX, @M);
   M := MatrixInvert(M);
   M[3, 0] := 0.0;
   M[3, 1] := 0.0;
   M[3, 2] := 0.0;
   glMultMatrixf(@M);
   RectT(FRadius, -FRadius, -FRadius, FRadius);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

   if (FMatName <> '') then
     FMatLib.MaterialByName[FMatName].UnApply()
   else
     FMatLib.Materials[FMatIdx].UnApply();

   glEnable(GL_LIGHTING);
   glEnable(GL_DEPTH_TEST);
   glDisable(GL_BLEND);
 end;
end;

Z góry dziękuję za pomoc.

Link to comment
Share on other sites

Głowy sobie nie dam uciąć ale jeśli ten połysk jest renderowany na kwadracie to on powinien być zawsze prostopadle do kamery inaczej cześć połysku wejdzie na planetę, i ot cala tajemnica.

"Bogowie to bugi ludzkich umysłów" Gifanonim ®

Link to comment
Share on other sites

Ponownie przepraszam za dwa posty pod sobą, ale udało mi się dojść do rozwiązania. :D Bardzo pomocnym okazał się ten artykuł. Gorąco zachęcam do lektury.

 

Poniżej kodzik i screen.

procedure TAtmosphere.DoRender;
var
 M: TMatrix;
 vPos, vLook, vUp, vRight: TAffineVector;
begin
 if Assigned(FMatLib) then
 begin
   glDisable(GL_DEPTH_TEST);
   glDisable(GL_LIGHTING);
   glEnable(GL_BLEND);

   if (FMatName <> '') then
     FMatLib.MaterialByName[FMatName].Apply()
   else
     FMatLib.Materials[FMatIdx].Apply();

   glBlendFunc(GL_SRC_ALPHA, GL_ONE);
   glColor3f(0.4, 0.6, 1.0);

   // tutaj liczymy macierz
   glGetFloatv(GL_MODELVIEW_MATRIX, @M);

   vPos := AffineVectorMake(M[3, 0], M[3, 1], M[3, 2]);
   vLook := AffineVectorMake(-vPos[0], -vPos[1], -vPos[2]);
   NormalizeVector(vLook);
   vUp := AffineVectorMake(0.0, 1.0, 0.0);
   vRight := VectorCrossProduct(vLook, vUp);
   vUp := VectorCrossProduct(vLook, vRight);

   CopyMemory(@M[0, 0], @vRight, SizeOf(Single) * 3);
   CopyMemory(@M[1, 0], @vUp, SizeOf(Single) * 3);
   CopyMemory(@M[2, 0], @vLook, SizeOf(Single) * 3);

   glLoadIdentity();
   glMultMatrixf(@M);
   // koniec liczenia macierzy     

   RectT(FRadius, -FRadius, -FRadius, FRadius);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

   if (FMatName <> '') then
     FMatLib.MaterialByName[FMatName].UnApply()
   else
     FMatLib.Materials[FMatIdx].UnApply();

   glEnable(GL_LIGHTING);
   glEnable(GL_DEPTH_TEST);
   glDisable(GL_BLEND);
 end;
end;

Screen

 

Pozdrawiam! :D

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...