the title basically.
You can reserve more than you need when creating a mesh
mesh = new Mesh(false, 100, 0, new VertexAttribute(Usage.Position, 3, "a_position"));
But there is no method for adding a vertex. You can get the FloatBuffer and add to that, but I get strange results. I also tried the mesh.setVertices with offset but that does not work either.
I debugged with drawing points. Works until I try adding a vertex by any means (even if I tweak offsets to account for 3 floats in one vertex)
Copied code segment:
mesh.setVertices(new float[] {
-0.5f, -0.5f, 0,
0.5f, -0.5f, 0/*,
-0.5f,0.5f,0.f*/});//works if I uncoment this
mesh.setVertices(new float[]{-0.5f,0.5f,0.f}, 6, 3);//but comment this out
I also tried
squareMesh.setVertices(new float[]{-0.5f,0.5f,0.f}, 2, 3);
Thanks :)
Adding is a bad idea because the underlying buffers must be recreated and that takes up a lot of time. Instead, one should allocate meshes in bulk and only render what is currently used.
For example mesh.render(GL10.GL_TRIANGLES,0,num_triangles);
As for updating the buffer:
FloatBuffer fbuftmp = mesh.getVerticesBuffer();
BufferUtils.copy(buf,fbuftmp,fbuftmp.capacity(),0);
Where buf is an float array.
Use BufferUtils.copy for reason explained here
Related
I have a problem with Andengine Box2d Extension.
I have 2 rectangles: base and fuelStation.
fuelStation is a child of base. When I'm rotating base with setTransform method, fuelStation sprite is rotating too, but body remains in the same position.
base = new Rectangle(CAMERA_WIDTH / 2, CAMERA_HEIGHT / 2 - 200, 200, 200, vbom);
fuelStation = new Rectangle(base.getWidth() / 2, 0, 500, 10, vbom);
this.attachChild(base);
base.attachChild(fuelStation);
final FixtureDef objectFixtureDef1 = PhysicsFactory.createFixtureDef(1, 0.0f, 0.5f);
final FixtureDef objectFixtureDef2 = PhysicsFactory.createFixtureDef(1, 0.0f, 0.5f);
baseBody = PhysicsFactory.createBoxBody(physicsWorld, base, BodyType.StaticBody, objectFixtureDef1);
baseBody.setUserData("base");
fuelStationBody = PhysicsFactory.createBoxBody(physicsWorld, fuelStation, BodyType.KinematicBody, objectFixtureDef2);
fuelStationBody.setUserData("station");
physicsWorld.registerPhysicsConnector(new PhysicsConnector(base, baseBody, true, true));
// physicsWorld.registerPhysicsConnector(new PhysicsConnector(fuelStation, fuelStationBody,
// true, true));
When I remove comment from the last line - sprite position changes but still not working properly (body stands still).
How to connect properly these 2 bodies?
You have to keep in mind that all the transformations that you do to the entities (sprites) will only affect the "visual" content, in other words, will never affect the physic bodies. If you want to affect the entities and the bodies you will only achieve that by applying forces to the physic bodies and, because they are connected with a PhysicsConnector, those transformations will affect both the physic body and the the sprite ("visual body").
So, having the fuelStating as a child of base will affect nothing. To affect two bodies you need a "connection" between them and you can achieve that by creating a joint that will connect the two bodies: http://www.iforce2d.net/b2dtut/joints-overview
Hope it helps.
I am trying to translate a set of points in one coordinate system to another coordinate system for my Android OpenGL project.
Assume matrix is a float array of 16 elements.
Assume points is a reference to an array of float arrays each with 4 elements. (points = new float[8][4])
I set the matrix to an identity matrix, I then translate it and multiply by the rotation of the gameobject. I then try to translate each of the 8 vertices into the new matrices coordinates system, but none of the points are changing.
Matrix.setIdentityM(matrix, 0);
Matrix.translateM(matrix, 0, go.getPosition().getX(), go.getPosition().getY(), go.getPosition().getZ());
Matrix.multiplyMM(matrix, 0, matrix, 0, go.getRotationArray(), 0);
//Matrix.rotateM(matrix, 0, 30f, 1.5f, -5f, 0f); testing debug purpose
for(int i=0;i<8;i++)
{
Matrix.multiplyMV(points[i], 0, matrix, 0, points[i], 0);
}
I am basically trying to do what Android's 2D canvas and Matrix 'mapPoints' does.
When you have a vector, your last element of the 4 long vector must be 1 and not 0! So non of the translation data was being multiplied correctly. (Well it was being done correctly, just not how I wanted it.) So when android.opengl.Matrix asks for a vector of four long and the first three elements represent your x,y,z, make sure the fourth element is set to 1!
I'm learning Open GL ES and would like to get a more intuitive interface with 3D objects than the one suggested by google in the TouchRotateActivity sample.
In order to do that, I would like to multiply my Modelview matrix by the ModelView matrix in the previous state.
But I encounter the following problem : getFloatv function returns 0 values in my float array, and I don't understand why (my ModelView matrix is not empty : if it was, I wouldn't get my cube on the screen).
Could someone help me to figure out what the problem is? Here are the changes in the code .
private float[] previous;
public CubeRenderer() {
mCube = new Cube();
previous = new float[16];
}
public void onDrawFrame(GL10 gl) {
GL11 gl11 = (GL11) gl;
gl11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
gl11.glMatrixMode(GL11.GL_MODELVIEW);
gl11.glLoadIdentity();
gl11.glTranslatef(0, 0, -3.0f);
gl11.glRotatef(mAngleX, 0, 1, 0);
gl11.glRotatef(mAngleY, 1, 0, 0);
gl11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
gl11.glEnableClientState(GL11.GL_COLOR_ARRAY);
/*if(!previous.equals(new float[16]))
gl11.glMultMatrixf(previous, 0);*/
gl11.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, previous, 0);
Log.d("taille matrice",Integer.toString(previous.length));
for(int i=0; i<previous.length;i++)
Log.d(Integer.toString(i),Float.toString(previous[i]));
mCube.draw(gl11);
}
Thank you in advance.
Depending on your device you might be using the PixelFlinger software GL renderer, which unfortunately does not implement glGetFloat, at least as of version 1.2. Checking the logcat output should reveal messages to this effect if this is the case.
The solution is to handle the matrices yourself so there's no need to retrieve them from OpenGL in the first place. Like so.
I don't program in Java, so for all I know, your problem could be in the way the memory is being passed to glGetFloatv. In any case, I found this page floating around out there, maybe it will help you.
I've been doing some simple shaders and Im encountering an error that happens randomly, when I start rendering my scene, sometimes the mesh is rendered with extra vectors, and if I kill the activity and then I open the same activity it renders sometimes without the extra vectors.
My guesses are that the memory on the GPU is not completely wiped out when I kill the activity. Whats more weird is that these extra polygons are rendered sometimes using my shader logic and other times they render as if they were filled with random squares.
Im going all crazy I've reviewed all the code, from where I read the obj, to where I set the vertex attributes, if you have been seen this before please let me know. BTW I'm using a motorola milestone with android 2.1.
This is the code related where I create a simple triangle and set the attributes of the vertices:
//This is where I create the mesh
mMesh = new Mesh();
mMesh.setVertices(new float[]{-0.5f, 0f, 0.5f,
0.5f, 0f, -0.5f,
-0.5f, 0f, -0.5f});
ArrayList<VertexAttribute> attributes = new ArrayList<VertexAttribute>();
attributes.add(new VertexAttribute(Usage.Position, 3, ProgramShader.POSITION_ATTRIBUTE));
VertexAttributes vertexAttributes = new VertexAttributes(attributes.toArray(new VertexAttribute[attributes.size()]));
mMesh.setVertexAttributes(vertexAttributes);
...
...
.......
//This is where I send the mesh to opengl
for(VertexAttribute attr :mVertexAttributes.getAttributes().values()){
mVertexBuffer.position(attr.offset);
int handler = shader.getHandler(attr.alias);
if(handler != -1){
try{
GLES20.glVertexAttribPointer(handler, attr.numComponents, GLES20.GL_FLOAT, false, mVertexAttributes.vertexSize, mVertexBuffer);
GLES20.glEnableVertexAttribArray(handler);
}catch (RuntimeException e) {
Log.d("CG", attr.alias);
throw e;
}
}
}
//(length = 3 for a triangle)
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, length);
Here are some screenshots for you to see the issue:
Screenshots
Also here is a link to a video I took when I run the app on the phone.
Video
So... I found the problem it was a really dumb thing I was doing,
//on this line I was sending length, where length was
//the length of the vertices for the triangle it was "9" (x,y,z for each vertex)
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, length);
//I had to divide that by the number of components for each vertex
//so when the vertex only has position attributes (x,y,z) is divided by 3
//when you have more i.e. normals it will be divided by 6 (x,y,z, normalX, normalY, normalZ)
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, length/mVertexAttributes.vertexNumComponents);
I hope this helps others.
How to load a Mesh (3dmax) in Android OpenGL into a ByteBuffer ?
example:
float triangleCoords[] = {
-0.5f, -0.25f , 0, // 0,
0.5f, -0.25f , 0, // 1,
0.0f, 0.559016994f, 0 // 2,
};
ByteBuffer vbb = ByteBuffer.allocateDirect(triangleCoords.length * _4_FLOAT_LENGTH);
vbb.order(ByteOrder.nativeOrder());
triangleVB = vbb.asFloatBuffer();
triangleVB.put(triangleCoords);
triangleVB.position(0);
how to load a mesh like an array or Coords or ineed a library for this job
It basically boils down to loading the data from the file into your data structures (like the vertex array from your code snippet) and providing these to OpenGL for rendering (in your case glDrawArrays, for example). This is generally the same procedure, no matter if working with Android, Windows, Plan9, OpenGL or Direct3D. Only the implementation details matter, therefore this question is a bit broad.
You can look at this description of the 3DS file format (hinted in your question), which also has links to tutorials for loading these files. Although the 3DS format is a quite easy to read binary format, for a start you might also look into the Wavefront OBJ format, a simple ASCII file format that nearly every modeling software can export to (but this should also hold for 3DS). Loading these formats into a bunch of simple vertex arrays should boil down to some few lines of code.
These should get you started. If you encounter any specific problems implementing these mesh loading functionalities on your particular platform, feel free to ask a more specific question.