2013-04-05 15 views
5

Edit - Dodano więcej koduKorzystanie z macierzy. Obracać w OpenGL ES 2.0

uwzględniając wiele problemów próbujących prawidłowo obracać mój quad przy użyciu OpenGL ES 2.0.

Zawsze wydaje się obracać wokół środka współrzędnych ekranu. Próbuję go obrócić wokół własnego centrum (dla 2d, więc tylko z osi Z).

Eksperymentowałem z Matrix.translate, jak pokazano poniżej. Jednak zmiana pozycji x lub y po prostu rysuje kwadraturę w innym miejscu na ekranie, ale kiedy się obraca, znowu obraca się wokół środka ekranu. Czy ktoś mógłby wyjaśnić, jak zmusić go do obracania się wokół własnej osi z (jak koło)?

Dzięki, tutaj są odpowiednie linie kodu - jeśli potrzebujesz więcej, proszę zapytaj, a ja opublikuję. (Uwaga: przyjrzałem się wielu podobnym pytaniom na temat SO i szerszego internetu, ale jak dotąd nie udało mi się znaleźć odpowiedzi).

Dzięki.

//Set rotation 
Matrix.setRotateM(mRotationMatrix, 0, -angle, 0, 0, 1.0f); 

//Testing translation 
Matrix.translateM(mRotationMatrix, 0, -.5f, .5f, 0f); 

// Combine the rotation matrix with the projection and camera view 
Matrix.multiplyMM(mvpMatrix, 0, mRotationMatrix, 0, mvpMatrix, 0); 

Moi Shadery (zadeklarowane na poziomie klasy)

private final String vertexShaderCode = 
"uniform mat4 uMVPMatrix;" + 

"attribute vec4 vPosition;" + 
"void main() {" + 
" gl_Position = uMVPMatrix * vPosition;" + 
"}"; 

private final String fragmentShaderCode = 
"precision mediump float;" + 
"uniform vec4 vColor;" + 
"void main() {" + 
" gl_FragColor = vColor;" + 
"}"; 

Od onSurfaceChanged

float ratio = (float) width/height; 
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7); 

In My metody onDrawFrame

// Set the camera position (View matrix) 
Matrix.setLookAtM(mVMatrix, 0, 0, 0, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 

//Calculate the projection and view transformation 
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0); 

Odpowiedz

0

Obrót zwykle występuje wokół początku, więc chcesz obrócić swój quad przed przetłumaczeniem. Jeśli obrócisz się po tłumaczeniu, to quad zostanie najpierw przeniesiony z miejsca pochodzenia, a następnie obrócony wokół punktu początkowego.

Nie wiedząc, jak zaimplementowano funkcję Matrix, nie możemy doradzić, czy używasz ich poprawnie. Wszystko, co pokazałeś nam w interfejsie funkcji.

Ale ogólnie, obróć przed tłumaczeniem.

+0

Hi @Sebby Johanns. Dzięki za komentarz, czy w tej chwili nie rotuję przed tłumaczeniem? Byłbym wdzięczny, gdybyś mógł wyjaśnić bardziej szczegółowo - dodałem jeszcze trochę kodu - czy to wystarczy? Proszę doradzić, jeśli potrzebujesz więcej (i której części potrzebujesz) - wielkie dzięki! – Zippy

+0

Jeśli tłumaczenie ma na celu przesunięcie środka obrotu, a nie przesunięcie kwadratu, to tłumaczenie, obrót, tłumaczenie z powrotem. – mbeckish

+0

@ Ciekawe podziękowania za komentarz, słyszałem, jak ludzie mówią "przenosić i tłumaczyć", ale jeszcze nie rozumiem tego całkowicie, myślę, że chcesz przetłumaczyć x i y, a następnie ponownie przetłumaczyć z przeciwnymi wartościami (powiedzmy 1,1, a potem -1, -1) - czy mógłbyś edytować, żeby pokazać przykład? Próbowałem tego, ale nic nie dostałem. Dzięki! – Zippy

3

Oto przewodnik. Powiedzmy, że narysowałeś imbryk ... modelMatrix byłby początkiem tożsamości. Kształt skupia się na początku tak:

pre rotate and translate

Sprawdź to, co masz przed kontynuowaniem ...

Gdy masz należy zastosować rotację do matrycy modelu kompilacji + run - dostaniesz obróconego kopię ...

rotated

Gdy masz ten można tłumaczyć:

rotated and translated

Wygląda na to, że wszystko, co musisz zrobić, sprawdza poprawność tożsamości macierzy obrotu. Matrix.setIdentityM (mRotationMatrix, 0); , w którym kształt znajduje się pośrodku. Jeśli nie, przenieś go na środek.

Gdy znajdzie się w środku, zastosuj obrót, np.

Matrix.setIdentityM(mRotationMatrix,0); 
    <as needed movement to center> 

    Matrix.rotate(mRotationMatrix, 0, -angle, 0, 0, 1.0f); 
    <any other translation you want> 

Wykonuj kroki, aby ułatwić sobie życie, aby zobaczyć, co się dzieje.

+0

Hi @paulczak - dziękuję za to. Chodzi o to, że gdy kształt znajduje się pośrodku, obraca się idealnie (ponieważ jego środek znajduje się pośrodku ekranu). Jeśli jednak przesuniemy kształt, aby powiedzieć lewy górny róg, nadal będzie on obracał się lub "krąży" wokół środka. Nie jestem pewien, jak to przetłumaczyć, aby pozostał w tym samym miejscu? Więc kiedy mówisz "kiedy już to umiesz przetłumaczyć" - myślę, że właśnie tam spadam, nie jestem pewien jak to zrobić? (Porządek kodu i jak obliczyć, gdzie powinien znajdować się ośrodek). – Zippy

+0

Czy resetujesz macierz rotacji (w której wykonywane są transformacje modelu) do tożsamości w każdym wywołaniu metody onDrawFrame()? – paulczak

+0

W rzeczywistości nie miałem Matrix.setIdentityM (mRotationMatrix, 0); tam w ogóle - ale dodałem ją teraz, zanim użyję setRotate. Tak, nazywa się to każdą ramką. (Z mojej metody rotateQuad(), która jest wywoływana z mojej metody onDrawFrame()), twoja pomoc jest doceniana, po prostu nie mogę zrozumieć, co robię źle! – Zippy

5

Napotkałem te same problemy (widziałem dziwne zniekształcenia i wszystko inne), moje rozwiązanie oparte na Android Training > Displaying Graphics with OpenGL ES > Adding Motion poniżej.

(Głowa do mojego szczegółowym stanowisku przez co w razie potrzeby. OpenGL ES Android Matrix Transformations)

  1. Ustaw mModelMatrix do macierzy jednostkowej

    Matrix.setIdentityM(mModelMatrix, 0); // initialize to identity matrix 
    
  2. Zastosuj tłumaczenie na mModelMatrix

    Matrix.translateM(mModelMatrix, 0, -0.5f, 0, 0); // translation to the left 
    
  3. je obracać w mRotationMatrix (kąty w stopniach)

    Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f); 
    
  4. Połączyć rotacji i translacji poprzez Matrix.multiplyMM

    mTempMatrix = mModelMatrix.clone(); 
    Matrix.multiplyMM(mModelMatrix, 0, mTempMatrix, 0, mRotationMatrix, 0); 
    
  5. Połączyć matrycy modelu z występem i widok z kamery

    mTempMatrix = mMVPMatrix.clone(); 
    Matrix.multiplyMM(mMVPMatrix, 0, mTempMatrix, 0, mModelMatrix, 0); 
    
+0

Wyróżnienie ruchu i obrotu (a później pomnożenie dwóch matryc) dało podstęp. Pamiętaj, że wymagana jest inicjalizacja macierzy rotacyjnej. –

0

zastosować operacje do tyłu:

1st- Matrix.translateM (mRotationMatrix, 0, -.5f, .5f, 0F);

2nd-Matrix.setRotateM (mRotationMatrix, 0, -angle, 0, 0, 1.0f);

To będzie obracać się wokół własnej centrum