Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : OpenGL (JOGL) 3.x



Dark
09.10.2013, 18:56
Hey lang nicht mehr hier gewesen,

ich habe folgendes Problem, ich versuche derzeit VBO's zu verstehen, und leider ist dieser teil relativ doof in meinem Buch beschrieben.

Wenn ich nun Folgenden Code in einem NEWT Window (Ka ob das wichtig ist) ausführe:



final int SIZE_OF_FLOAT = 4;
final int SIZE_OF_INT = 4;
int numOfNames = 4;


int vertexBufferSizeInBytes = SIZE_OF_FLOAT * 3 * 3;
int faceListBufferSizeInBytes = SIZE_OF_INT * 3 * 3;



ByteBuffer bb = ByteBuffer.allocateDirect(vertexBufferSizeInBytes) ;
bb.order(ByteOrder.nativeOrder());
vertices = bb.asFloatBuffer();



bb = ByteBuffer.allocateDirect(vertexBufferSizeInBytes) ;
bb.order(ByteOrder.nativeOrder());
normals = bb.asFloatBuffer();



bb = ByteBuffer.allocateDirect(faceListBufferSizeInByte s);
bb.order(ByteOrder.nativeOrder());
faceList = bb.asIntBuffer();



bb = ByteBuffer.allocateDirect(vertexBufferSizeInBytes) ;
bb.order(ByteOrder.nativeOrder());
colors = bb.asFloatBuffer();



bb = ByteBuffer.allocateDirect(numOfNames * SIZE_OF_INT);
bb.order(ByteOrder.nativeOrder());
nameBuffer = bb.asIntBuffer();


GL2 gl2 = gl.getGL2();


vertices.put(0f); vertices.put(0f); vertices.put(0f);
vertices.put(1f); vertices.put(0f); vertices.put(0f);
vertices.put(0f); vertices.put(1f); vertices.put(0f);

normals.put(0f); normals.put(0f); normals.put(1f);
normals.put(0f); normals.put(0f); normals.put(1f);
normals.put(0f); normals.put(0f); normals.put(1f);

colors.put((float)Math.random()); colors.put((float)Math.random()); colors.put((float)Math.random());
colors.put((float)Math.random()); colors.put((float)Math.random()); colors.put((float)Math.random());
colors.put((float)Math.random()); colors.put((float)Math.random()); colors.put((float)Math.random());

faceList.put(0); faceList.put(1); faceList.put(2);


vertices.flip();
normals.flip();
faceList.flip();
colors.flip();

/*vertices.rewind();
normals.rewind();
faceList.rewind();*/

gl2.glGenBuffers(numOfNames, nameBuffer);

bufferNameVertices = nameBuffer.get();
bufferNameNormals = nameBuffer.get();
bufferNameColors = nameBuffer.get();
bufferNameFaceList = nameBuffer.get();



gl2.glBindBuffer(gl2.GL_ARRAY_BUFFER, bufferNameVertices);
gl2.glBufferData(gl2.GL_ARRAY_BUFFER, vertexBufferSizeInBytes, vertices,gl2.GL_STATIC_DRAW);


gl2.glBindBuffer(gl2.GL_ARRAY_BUFFER, bufferNameNormals);
gl2.glBufferData(gl2.GL_ARRAY_BUFFER, vertexBufferSizeInBytes, normals,gl2.GL_STATIC_DRAW);


gl2.glBindBuffer(gl2.GL_ARRAY_BUFFER, bufferNameColors);
gl2.glBufferData(gl2.GL_ARRAY_BUFFER, vertexBufferSizeInBytes, colors,gl2.GL_STATIC_DRAW);



gl2.glBindBuffer(gl2.GL_ARRAY_BUFFER, 0);


gl2.glBindBuffer(gl2.GL_ELEMENT_ARRAY_BUFFER, bufferNameFaceList);
gl2.glBufferData(gl2.GL_ELEMENT_ARRAY_BUFFER, faceListBufferSizeInBytes, faceList,GL2.GL_STATIC_DRAW);

gl2.glBindBuffer(gl2.GL_ELEMENT_ARRAY_BUFFER, 0);


gl2.glEnableClientState(GL2.GL_VERTEX_ARRAY);
gl2.glEnableClientState(GL2.GL_NORMAL_ARRAY);
gl2.glEnableClientState(GL2.GL_COLOR_ARRAY);


gl2.glBindBuffer(GL2.GL_ARRAY_BUFFER, bufferNameVertices);
gl2.glVertexPointer(3 , GL2.GL_FLOAT, 0, 0);

gl2.glBindBuffer(GL2.GL_ARRAY_BUFFER, bufferNameNormals);
gl2.glVertexPointer(3 , GL2.GL_FLOAT, 0, 0);

gl2.glBindBuffer(GL2.GL_ARRAY_BUFFER, bufferNameColors);
gl2.glVertexPointer(3 , GL2.GL_FLOAT, 0, 0);



gl2.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, bufferNameFaceList);






gl2.glDrawElements(GL2.GL_TRIANGLES,3,GL2.GL_UNSIG NED_INT,0L);



gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);

gl2.glDisableClientState(GL2.GL_VERTEX_ARRAY);
gl2.glDisableClientState(GL2.GL_NORMAL_ARRAY);
gl2.glDisableClientState(GL2.GL_COLOR_ARRAY);



Eigtl sollte dieser Code ein Einfaches Dreieck mit Face Zeichnen, jedoch wird von JAVA ein "Fatal Error" Ausgelöst und die VM schmiert ab.

Ich hab jetzt schon mehrfach drübergeschaut, bin aber bestimmt schon betriebsblind. Evtl kennt sich ja einer Genug mit GL aus so das er mir helfen kann.

Danke schonmal.

A.I.
09.10.2013, 20:15
Dein Code scheint ein ziemlicher Overkill zu sein, nur um ein Dreieck zu zeichnen.

Ein VBO (http://www.opengl.org/wiki/Buffer_Object) ist nichts anderes als ein (Treiber-kontrollierter) Zeiger auf einen Speicherbereich in der Grafikkarte.
Um die Vertices zu finden, braucht er einen gebundenen (also aktiven) ARRAY_BUFFER. Den bindest du aber wieder auf 0 und weil an dieser Stelle kein VBO vorhanden ist, weiß er ja nicht, was gezeichnet werden soll. ELEMENT_ARRAY_BUFFER hilft da wenig, da er nur die Speicherposition Vertices beinhaltet, aber nicht ihren Inhalt.
Außerdem braucht modernes OpenGL immer einen Vertex- und Fragment Shader, um die Vertices in die richtige Position zu bringen und die vom Rasterizer erzeugten Fragmente eine richtige Farbe zu zuweisen.

http://open.gl/media/img/c2_pipeline.png

Hier ist ein nettes Tutorial, dass es vielleicht besser erklärt: http://open.gl/
Es ist zwar auf C++ ausgelegt, aber die GLCalls sind alle gleich.

Dark
09.10.2013, 21:41
Omg es ist grade irgenwie zu spät und ich habe deinen Post nur halb gelesen, du hast ja geschrieben wo mein fehler ist sry.


Ansich sehr nette erklärung danke und ja eigtl ist es natürlich nicht gedacht nur EIN Dreieck zu zeichnen, das ist ein Beispiel aus meinem Buch ich lerne OpenGL grade, und versuche einfach mal nachzuvollziehn wie das geht, nur geht es hier nicht und ich verstehe einfach nicht wieso. Ich nehme mal an das ich irgentwie die Buffer größen falsch bestimmt habe aber ich weiß echt nicht wo und warum werde mir dein tut aber mal ansehen danke.

Grüne Gurken
10.10.2013, 14:03
Wenn du sowieso unter Java arbeitest nutz doch einfach die Lightweight Java Gaming Libary: http://lwjgl.org/index.php

Dark
10.10.2013, 18:35
Habe ich schpm des Öftern nachgedacht (und früher auch schon mit gearbeitet, aber auch dort mit der alten GL2 version (also glBegin/glEnd)), aber ich wollte Gl jetzt mal richtig und auch für später lernen,der umstieg auf LWJGL dürfte ja dann sowieso ein Klacks sein, aber danke für die anregung. Das Tut von A.I. ist echt genial, habe nur noch nicht die zeit gefunden mich da einzuarbeiten. Bin nur ein wenig entäuscht von dem buch was ich habe, denn bis auf dieses Kapitel ist der rest echt klasse. Würde ja

Dark
20.10.2013, 17:08
So habe das Tut mal durchgearbeitet und danach den Code in JAVA versucht zu replizieren. Das Problem, es wird nichts gezeichnet und es ist nach wie vor etwas komisch.

Hoffe das ist jetzt nicht zu viel aber ich habe einfach mal geschrieben wie ich das ganze verstehe, wär cool wenn mir einer sagen kann ob ich den die ansätze von den BUFFERN verstanden habe.

in dem Tutorial habe ich Drei buffer:

Vertex Array Object

Buffer_VAO = ByteBuffer.allocateDirect(SIZE_OF_INT * 1).order(ByteOrder.nativeOrder()).asIntBuffer();
gl3.glGenVertexArrays(1, Buffer_VAO);
VAO = Buffer_VAO.get();

gl3.glBindVertexArray(VAO);

Wobei der VAO ja die shader enthält, bzw. ihnen speicher auf der Grafikkarte bereithält.

Vertex Buffer Object und Element Buffer Object:


Buffers = ByteBuffer.allocateDirect(SIZE_OF_INT * bufferNumber).order(ByteOrder.nativeOrder()).asInt Buffer();
gl3.glGenBuffers(bufferNumber, Buffers);

VBO = Buffers.get();

VBO_Buffer = ByteBuffer.allocateDirect(SIZE_OF_FLOAT * VERTICE_SIZE * vertices.length).order(ByteOrder.nativeOrder()).as FloatBuffer();
VBO_Buffer.put(this.vertices);
VBO_Buffer.rewind();

gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, VBO);
gl3.glBufferData(GL3.GL_ARRAY_BUFFER, SIZE_OF_FLOAT * vertices.length, VBO_Buffer, GL3.GL_STATIC_DRAW);


EBO = Buffers.get();
EBO_Buffer = ByteBuffer.allocateDirect(SIZE_OF_FLOAT * VERTICE_SIZE * elements.length).order(ByteOrder.nativeOrder()).as FloatBuffer();
EBO_Buffer.rewind();

gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, EBO);
gl3.glBufferData(GL3.GL_ARRAY_BUFFER, SIZE_OF_FLOAT * elements.length, EBO_Buffer, GL3.GL_STATIC_DRAW);

VBO enthält die vertex daten, im beispiel ein Array mit 4 vertices und 6 einträgen pro vertice (x,y,z,color,color,color)
EBO gibt an wie ein element zusammengesetzt wird, also die ersten 3 einträge sind das 0,1,2 vertice => dreieck, die zweiten 2,3,0.



Dann kommen die Shader:


vertexShader = gl3.glCreateShader(GL3.GL_VERTEX_SHADER);
gl3.glShaderSource(vertexShader, 1, vertexSource, null);
gl3.glCompileShader(vertexShader);

jetzt nur der eine der Code ist ja gleich, die werden auch ohne fehler compiled und so weiter.


Dann wird ein neues programm erstellt und die shader gebunden,

shaderProgram = gl3.glCreateProgram();
gl3.glAttachShader(shaderProgram, vertexShader);
gl3.glAttachShader(shaderProgram, fragmentShader);
gl3.glBindFragDataLocation(shaderProgram, 0, "outColor");
gl3.glLinkProgram(shaderProgram);
gl3.glUseProgram(shaderProgram);

dann wird noch gesagt wo die shader die werte finden


posAttrib = gl3.glGetAttribLocation(shaderProgram, "position");
gl3.glEnableVertexAttribArray(posAttrib);
gl3.glVertexAttribPointer(posAttrib, 3, GL.GL_FLOAT, false, 5 * this.SIZE_OF_FLOAT, 0);

was ich nun nicht verstehe in dem tutorial wird nun nicht gesagt wie diese in den VAO kommen und dieser wird auch nicht an die Karte geschickt.



So dann kommt der Draw

gl3.glDrawElements(GL3.GL_TRIANGLES, 12, GL3.GL_UNSIGNED_INT,???);

da hatte ich das Problem das ich nicht weiß was bei den ??? hinkommt, wenn ich 0 mache kommt ne "fatal ACCES Violation EXCEPTION", dann habe ich den EBO reingemacht, und es Passierte nichts.

Dark
11.03.2014, 18:59
Also ich bin mittlerweile soweit, dass ich einen VertexShader habe und diesem sowol eine eigene Matrix mitgeben kann (Model,Projection). Nun habe ich mir gedacht machst du einfach mal 3 Matrizen (testweise) Model , View , Projection

Shader auszug.

gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(in_Position * m, 1.0);

Nun berechne ich die LookAt Matrix und schiebe sie in die viewMatrix( = id * LookAt)

Die lookAt habe ich so wie hier berechnet :http://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml


Am ende steht dann:

glMultMatrixf(M);
glTranslated(-eyex, -eyey, -eyez);



Type = dense , numRows = 4 , numCols = 4
0,000 0,000 0,000 0,000
0,000 0,000 0,000 0,000
-0,000 -0,000 1,000 0,000
0,000 0,000 0,000 1,000

<=> glMultMatrixf(M);

Type = dense , numRows = 4 , numCols = 4
1,000 0,000 0,000 -0,000
0,000 1,000 0,000 -0,000
0,000 0,000 1,000 -2,000
0,000 0,000 0,000 1,000

<=> glTranslated(-eyex, -eyey, -eyez);

Type = dense , numRows = 4 , numCols = 4
1,000 0,000 0,000 0,000
0,000 1,000 0,000 0,000
0,000 0,000 0,000 0,000
0,000 0,000 0,000 0,000

das Multiplizierte ergebnis.[/CODE]

Wie jetzt jeder erkennen sollte, der Matritzen in der Schule hat, fällt bei einer Multiplikation mit einem Vektor alles bis auf, in vielen Literaturen heist es "w" eintrag, den w eintrag alles weg.


SimpleMatrix viewingMatr = SimpleMatrix.identity(4);

SimpleMatrix F = new SimpleMatrix(3, 1);
SimpleMatrix UP = new SimpleMatrix(1, 3);

F.setColumn(0, 0, centerX - eyeX, centerY - eyeY, centerZ - eyeZ);
UP.setRow(0, 0, upX, upY, upZ);

float norm_F = (float) Math.sqrt(
(centerX - eyeX) * (centerX - eyeX)
+ (centerY - eyeY) * (centerY - eyeY)
+ (centerZ - eyeZ) * (centerZ - eyeZ));

float norm_UP = (float) (Math.sqrt(
upX * upX
+ upY * upY
+ upZ * upZ));


F = F.scale(1.0 / norm_F);
UP = UP.scale(1 / norm_UP);

SimpleMatrix s = F.mult(UP);

SimpleMatrix u = s.scale(1 / s.normF()).mult(F);




viewingMatr.setRow(0, 0, s.get(0), s.get(1), s.get(2), 0);
viewingMatr.setRow(1, 0, u.get(0), u.get(1), u.get(2), 0);
viewingMatr.setRow(2, 0, -F.get(0), -F.get(1), -F.get(2), 0);



SimpleMatrix trans = SimpleMatrix.identity(4);
trans.setColumn(3, 0, -eyeX, -eyeY, -eyeZ, 1);

habe noch den code angehange der Methoden rumpf sieht so aus:

public static void lookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)

Ich hoffe von euch sieht einer den Fehler oder kann mir anders weiterhelfen, ich bin grade Betriebsblind glaube ich.

Dark
12.03.2014, 10:15
Ich glaube es hat sich erledigt, ich denke die meinen an der stelle s = f x UP ist ein Kreuzprodukt und nicht das normale Produkt

€r!k
12.03.2014, 13:31
Wenn du weitere Fragen über OpenGL hast, empfehle ich dir diese Seite: http://wiki.delphigl.com/index.php/OpenGL-Funktions%C3%BCbersicht
Das ist zwar alles in Delphi, aber die Funktionen sind die gleichen, ebenso alle Parameter etc.

Dark
14.03.2014, 23:33
Danke habe ich, zumindest um die Header nachzuschauen (oder hieß es Prototypes??) schon öfters benutzt, die NetBeans API Liefert ja leider nur den satz "Native Interface bla bla und den Methoden rumpf"