2014-12-19 15 views
6

Próbuję narysować czarną pojedynczą linię na GLKitView, używając Swift, ale to nie działa. Mogę wyczyścić ekran i mogę go wypełnić dowolnym kolorem, ale nie mogę niczego na nim narysować. I wiem, że to pytanie było zadawane wiele razy, ale nie mogłem znaleźć żadnej odpowiedzi na temat Swift. Co więcej, nie ma żadnych informacji o używaniu OpenGL ES z Swift, więc przyszedłem tutaj.Swift - Jak narysować linię w OpenGL ES?

Oto mój kod:

import GLKit 

class MyGLKit: GLKView { 
    override func drawRect(rect: CGRect) { 
     glClearColor(0.8, 0.8, 0.8, 1.0) 
     glClear(GLbitfield(GL_COLOR_BUFFER_BIT)) 

     glColor4f(0, 0, 0, 1) 

     var line: [GLfloat] = [-1, 0, 1, 0] 
     var len = line.count * sizeof(GLfloat) 

     // Create an handle for a buffer object array 
     var bufferObjectNameArray: GLuint = 0 

     // Have OpenGL generate a buffer name and store it in the buffer object array 
     glGenBuffers(1, &bufferObjectNameArray); 

     // Bind the buffer object array to the GL_ARRAY_BUFFER target buffer 
     glBindBuffer(GLbitfield(GL_ARRAY_BUFFER), bufferObjectNameArray); 

     // Send the line data over to the target buffer in GPU RAM 
     glBufferData(
     GLbitfield(GL_ARRAY_BUFFER), // the target buffer 
     len,       // the number of bytes to put into the buffer 
     line,       // a pointer to the data being copied 
     GLbitfield(GL_STATIC_DRAW)); // the usage pattern of the data 

     glVertexPointer(2, GLbitfield(GL_FLOAT), 0, line); 
     var programHandle: GLuint = glCreateProgram() 
     glLinkProgram(programHandle) 

     glDrawArrays(GLbitfield(GL_LINES), 0, 2); 
    } 
} 

Nie jestem pewien, co ten kod robi, bo OpenGL ES wydaje się szalenie, po zwykłej OpenGL. Trzeba napisać dużo kodu, aby narysować pojedynczą linię. Dlaczego to działa w ten sposób?

+0

Będziesz potrzebować wywołania "glVertexPointer()", które skomentowałeś. Ale używaj '0' jako ostatniego argumentu, ponieważ jest to przesunięcie do bufora, jeśli bufor jest powiązany. –

+1

@RetoKoradi Nie mogę użyć '0' jako ostatniego argumentu, ponieważ XCode mówi' Nie można wywołać 'init' z listą argumentów typu '(IntegerLiteralConvertible, $ T3, IntegerLiteralConvertible, IntegerLiteralConvertible) ''. Ostatni argument to _Specyfikuje wskaźnik do pierwszej współrzędnej pierwszego wierzchołka w tablicy. Musi więc być wskaźnikiem do pierwszego elementu tablicy. Ale jak to zrobić? –

+0

Zgadzam się z OP, OpenGL-ES z Swift jest "obłąkany". Chcę tylko narysować cholerną linię od punktu A do punktu B. Dlaczego, do cholery, potrzeba tego ponad 20 linii kodu? Dlaczego nie jest to prymitywne? +1 dla "obłąkanego" –

Odpowiedz

1

Nie używałem Swift, ale na podstawie kodu w OpenGL EXC_BAD_ACCESS when calling glDrawElements in Swift but not in Objective-C, połączenie glVertexPointer() powinna wyglądać następująco:

let bufferOffset: CConstVoidPointer = COpaquePointer(UnsafePointer<Int>(0)) 
glVertexPointer(2, GLbitfield(GL_FLOAT), 0, bufferOffset); 

wygląda też na to nie jesteś naprawdę buduje program shadera:

var programHandle: GLuint = glCreateProgram() 
glLinkProgram(programHandle) 

Jest kilka rzeczy, które muszą przejść tutaj, jeśli używasz zwykłego OpenGL. Musisz stworzyć obiekty shaderów, dać im kod napisany w GLSL, nawiązywać połączenia, aby skompilować shadery itp. Wierzę, że GLKit ma funkcjonalność do używania wstępnie upieczonych shaderów.

Co do tego, dlaczego OpenGL jest tak "szalony", to wykracza poza zakres tej witryny. I bardzo subiektywne. IMHO, głównym punktem, o którym należy pamiętać, jest to, że OpenGL nie został zaprojektowany jako wygodny interfejs API dla programistów. Został zaprojektowany w celu zapewnienia stosunkowo cienkiej ogólnej abstrakcji dostępu do sprzętu graficznego. A tendencja do porównywania API w rzeczywistości powoduje, że warstwa abstrakcji jest jeszcze cieńsza, aby zmniejszyć narzut (patrz np. DirectX 12).

Nic nie powstrzyma nikogo przed wprowadzeniem wygodniejszych interfejsów API wyższego poziomu poza OpenGL. Te interfejsy istnieją i ludzie ich używają.

+1

Mam błąd "Używanie niezadeklarowanego typu" CConstVoidPointer''. Kiedy zmieniłem typ na "UnsafePointer" zadziałało, ale wciąż nic nie jest rysowane. –

+0

Zapraszam do edytowania odpowiedzi, ale najprawdopodobniej twoja edycja zostanie odrzucona, ponieważ będzie musiała przejść przez kolejkę przeglądu edycji. Poza tym wygląda na to, że brakuje Ci do zbudowania programu cieniującego. Dodałem akapit na ten temat. Przepraszam, jeśli moja odpowiedź nie jest zbyt pomocna. Nie jestem pewien, czy powinienem go usunąć. Zwykle nie odpowiadam na pytania dotyczące niezrozumiałych tematów, w tym Swift. –

+1

Myślę, że masz rację. Tak trudno to sprawić! Również Nie ma to sensu, ponieważ nie potrzebuję grafiki 3D. Wszystko czego chcę - narysuj proste linie i okręgi. Prawdopodobnie możesz wymienić kilka "wygodniejszych interfejsów API wyższego poziomu na OpenGL_"? –