Rotating the rectangle - OpenGL ES - java

In a middle of developing my game I created a function to rotate a 2d triangle.
But the problem is that when I rotate an object, the rotation is very weird.
If the object's center is at the origin (the (0,0) point) of the axis then it rotates fine, but if I move the object then it rotates in a very weird way that it shouldn't be rotating in.
as you can see here is the code of the function.
public void rotate(float angle){
float x1 = x, y1 = y;
float x2 = x + width, y2 = y;
float x3 = x + width, y3 = y + height;
float x4 = x, y4 = y + height;
// Vertices in object space:
float[] vector1 = {x1, y1, 0f, 1f};
float[] vector2 = {x2, y2, 0f, 1f};
float[] vector3 = {x3, y3, 0f, 1f};
float[] vector4 = {x4, y4, 0f, 1f};
// Vertices in world space:
float[] vector1r = new float[4];
float[] vector2r = new float[4];
float[] vector3r = new float[4];
float[] vector4r = new float[4];
// Calculate the vertices in world space:
Matrix.multiplyMV(vector1r, 0, modelMatrix, 0, vector1, 0);
Matrix.multiplyMV(vector2r, 0, modelMatrix, 0, vector2, 0);
Matrix.multiplyMV(vector3r, 0, modelMatrix, 0, vector3, 0);
Matrix.multiplyMV(vector4r, 0, modelMatrix, 0, vector4, 0);
// Get the middle of the rectangle:
float[] vecMid = {(vector1r[0] + vector3r[0]) / 2,
(vector1r[1] + vector3r[1]) / 2, 0f, 1f};
move(vecMid[0], vecMid[1]); // Move to the origin
Matrix.rotateM(modelMatrix, 0, angle, 0, 0, 1f); // Rotate the object
move(-vecMid[0], -vecMid[1]); // Move back to place
if(LoggerConfig.ON)
Log.d("Middle Vertex", vecMid[0] + ", " + vecMid[1]);
}
The move method:
public void move(float x, float y){
Matrix.translateM(modelMatrix, 0, x, y, 0);
}
Can someone tell me what the problem is?
EDIT: I did some modifications to the code and added the move method.

Related

How to fix weird object stretching while rotating in OpenGL in x or y axis?

When I am using rotate matrix to rotate my square in openGL and when I want to rotate it around X or Y axis the whole object dissapears and stretches.Z axis is working fine. What could the problem be?
I have tried loading uniformMatrix4f before DrawArrays and it is not working.Still the same problem. Translation is working fine and scaling.
Render method
public void render(Player model, Cube cube_model, StaticShader shader) {
GL30.glBindVertexArray(model.vaoID);
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
shader.loadModelMatrix(Maths.createModelMatrix(new Vector3f(move_X,-Display.getHeight(),0f), 0f,0f,tilt_Y,1f));
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 3);
GL20.glDisableVertexAttribArray(1);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
GL30.glBindVertexArray(cube_model.vaoID);
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
shader.loadModelMatrix(Maths.createModelMatrix(new Vector3f(0f,Display.getHeight() - 200f,0f), 0f,increaseRotation,0f,0.5f));
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 6);
increaseRotation += 1f;
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL30.glBindVertexArray(0);
}
Matrix math:
public static Matrix4f createModelMatrix(Vector3f t, float rx, float ry, float rz, float s) {
Matrix4f modelMatrix = new Matrix4f();
modelMatrix.setIdentity();
Matrix4f.translate(t, modelMatrix, modelMatrix);
Matrix4f.rotate((float) Math.toRadians(rx), new Vector3f(1,0,0), modelMatrix, modelMatrix);
Matrix4f.rotate((float) Math.toRadians(ry), new Vector3f(0,1,0), modelMatrix, modelMatrix);
Matrix4f.rotate((float) Math.toRadians(rz), new Vector3f(0,0,1), modelMatrix, modelMatrix);
Matrix4f.scale(new Vector3f(s,s,s), modelMatrix, modelMatrix);
return modelMatrix;
}
Projection matrix setup:
public StaticShader(String vertexShaderFileName, String fragmentShaderFileName) {
super(vertexShaderFileName, fragmentShaderFileName);
enableProgram();
loadProjectionMatrix(Maths.createOrthoMatrix(-Display.getWidth(), Display.getWidth(), -Display.getHeight(), Display.getHeight(), 0.1f, 1000));
disableProgram();
}
Cube vertices:
private static final float vertices[] = {
-Display.getWidth() / 5, 0.0f, 0.0f, 1.0f,1.0f,1.0f,1.0f,
Display.getWidth() / 5, 0.0f, 0.0f, 0.0f,1.0f,1.0f,1.0f,
-Display.getWidth() / 5, Display.getHeight() / 5, 0.0f, 1.0f,1.0f,1.0f,1.0f,
Display.getWidth() / 5, 0.0f, 0.0f, 1.0f,1.0f,1.0f,1.0f,
Display.getWidth() / 5, Display.getHeight() /5, 0.0f, 0.0f,1.0f,1.0f,1.0f,
-Display.getWidth() / 5, Display.getHeight() / 5, 0.0f, 1.0f,1.0f,1.0f,1.0f
};
I am expecting the cube to rotate in place in Y axis normally but it is actually rotating and dissapears then a line of it appears stretched in middle and dissapears.
I want to rotate it around X or Y axis the whole object disapears and stretches.Z axis is working fine.
Of course.
Your object is a 2 dimensional object. It is just a plane with in the 2 dimensions x and y. The x and y axis are parallel to the viewport. The z axis points out of the viewport.
If you do a rotation around the z axis (in the xy plane), the object keeps its size and rotates.
But if you do a rotation around the x axis, then object seems to be stretched along y and disappears at an angle of 90° respectively 270° degrees.
if you do a rotation around the y axis, then object seems to be stretched along x.
The rotation around the x and y axis looks "flat", because of the Orthographic projection. Actually you've no projection matrix, so the scene is projected in parallel (orthographic).
If you want to "see" a 3 dimensional rotation, then you've to use a Perspective projection

Opengl framebuffer rendering looks wierd

The Original Problem:
I'm making a 2d game in OpenGL that uses tiles to draw a map. At the moment, each tile is drawn individually on a quad. The code for the tile rendering is:
#Override
public void render() {
if (parentTileSet.getTexture() == null)
return;
float alpha = parentLayer.getOpacity();
if (alpha < 0)
alpha = 0;
glColor4f(1.0f, 1.0f, 1.0f, alpha); //Set alpha to parent layer's alpha
parentTileSet.getTexture().bind(); //Bind texture
float bx = parentTileSet.getTileWidth() / 2; //Half the width
float by = parentTileSet.getTileHeight() / 2; //Half the height
float x = getX(), y = getY();
float z = 0f;
glPushMatrix(); //Save the current view matrix
glTranslatef(x, y, 0f); //Translate to the tile's position
glRotatef(rotate, 0f, 0f, 1f); //Rotate the tile if it has a rotation
if ((flipType & 1) > 0) //Are we flipping horizontally?
glScalef(-1f, 1f, 1f);
if ((flipType & 2) > 0) //Are we flipping vertically?
glScalef(1f, -1f, 1f);
//Draw the tile
glBegin(GL_QUADS);
glTexCoord2f(tex_cords.bottom_left.x, tex_cords.bottom_left.y); //bottom left
glVertex3f(-bx, -by, z);
glTexCoord2f(tex_cords.bottom_right.x, tex_cords.bottom_right.y); //bottom right
glVertex3f(bx, -by, z);
glTexCoord2f(tex_cords.top_right.x, tex_cords.top_right.y); //top right
glVertex3f(bx, by, z);
glTexCoord2f(tex_cords.top_left.x, tex_cords.top_left.y); //top left
glVertex3f(-bx, by, z);
glEnd();
glPopMatrix(); //Reload the view matrix to original state
parentTileSet.getTexture().unbind(); //Unbind the texture
}
And the result looks like the following:
http://i.stack.imgur.com/maIXk.jpg
Which is good. However, the FPS could be better, and this especially becomes an issue when the maps become more detailed. (The FPS drops to about 20).
My Ideal Solution:
Since the tiles will never change position or animate, if I render all the tiles to a texture once, and just draw that texture, then performance will increase!
So, I made a framebuffer using the following class:
public class Framebuffer implements Drawable {
private int fID, tID;
protected int width, height;
public Framebuffer(int width, int height) {
this.width = width;
this.height = height;
}
public void generate() {
fID = glGenFramebuffers();
tID = glGenTextures();
glBindFramebuffer(GL_FRAMEBUFFER, fID);
glBindTexture(GL_TEXTURE_2D, tID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_INT, (ByteBuffer) null);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tID, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
throw new RuntimeException("Framebuffer configuration error.");
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
public void begin() {
glPushMatrix();
glPushAttrib(GL_VIEWPORT_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, fID);
glViewport(0, 0, width, height);
}
public void end() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glPopMatrix();
glPopAttrib();
}
#Override
public void render() {
float x = 0f;
float y = 0f;
float z = 0f;
float bx = (this.width)/2f;
float by = (this.height)/2f;
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, tID);
glBegin(GL_QUADS);
glTexCoord2f(0f, 0f); //bottom left
glVertex3f(x - bx, y - by, z);
glTexCoord2f(1f, 0f); //bottom right
glVertex3f(x + bx, y - by, z);
glTexCoord2f(1f, 1f); //top right
glVertex3f(x + bx, y + by, z);
glTexCoord2f(0f, 1f); //top left
glVertex3f(x - bx, y + by, z);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();
}
And then use the following code to generate the framebuffer, and render the tiles to the texture:
System.out.println("Attempting to generate frame buffer..");
try {
Framebuffer frame = new Framebuffer(tiledData.getPixelWidth(), tiledData.getPixelHeight());
frame.generate();
frame.begin();
glScalef(0.5f, 0.5f, 1f); //The game is scaled up by 2, so I'm just unscalling here.
Iterator<Drawable> drawableIterator = getSortedDrawables();
while (drawableIterator.hasNext()) {
Drawable d = drawableIterator.next();
if (d instanceof TileObject) {
TileObject t = (TileObject)d;
if (t.isGroundLayer() && !t.isParallaxLayer() && !t.isAnimated()) {
t.render(); //This render method is the one from above
drawableIterator.remove();
}
}
}
frame.end();
System.out.println("Success!");
addDrawable(frame);
} catch (RuntimeException e) {
System.out.println("Framebuffers are not supported!");
}
However, the output is this:
http://puu.sh/8Eemy.jpg
Which is not what I expected to happen. I tried scaling it, moving it, and all sorts of things but I can never get it exactly right.
My Question
What am I doing wrong? Is there another way to go about this? Am I missing something?
UPDATE
Thanks to the comments, I've got it to render correctly!
I changed the framebuffer class to be the following:
private int fID, tID;
protected int width, height;
public Framebuffer(int width, int height) {
this.width = width;
this.height = height;
}
public void generate() {
fID = glGenFramebuffers();
tID = glGenTextures();
glBindFramebuffer(GL_FRAMEBUFFER, fID);
glBindTexture(GL_TEXTURE_2D, tID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_INT, (ByteBuffer) null);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tID, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
throw new RuntimeException("Framebuffer configuration error.");
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
public void begin() {
glBindFramebuffer(GL_FRAMEBUFFER, fID);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, width, 0, height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}
public void end() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
}
#Override
public void render() {
float x = this.width / 2f;
float y = this.height / 2f;
float z = 0f;
float bx = (this.width)/2f;
float by = (this.height)/2f;
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, tID);
glBegin(GL_QUADS);
glTexCoord2f(0f, 0f); //bottom left
glVertex3f(x - bx, y - by, z);
glTexCoord2f(1f, 0f); //bottom right
glVertex3f(x + bx, y - by, z);
glTexCoord2f(1f, 1f); //top right
glVertex3f(x + bx, y + by, z);
glTexCoord2f(0f, 1f); //top left
glVertex3f(x - bx, y + by, z);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();
}
The points of interest here is the begin() and end() method, where I setup a new projection matrix and save the old one, then restore it in the end() method.

LWJGL Get mouse coordinates on given plane

So far, i have the code to get the mouse's position in the world, however i need to get it on a given plane (z=0), how can i go about doing this? Here is my picking code :
static public Vector3f getMousePositionIn3dCoords(int mouseX, int mouseY) {
viewport.clear();
modelview.clear();
projection.clear();
winZ.clear();;
position.clear();
float winX, winY;
GL11.glGetFloat( GL11.GL_MODELVIEW_MATRIX, modelview );
GL11.glGetFloat( GL11.GL_PROJECTION_MATRIX, projection );
GL11.glGetInteger( GL11.GL_VIEWPORT, viewport );
winX = (float)mouseX;
winY = (float)mouseY;
GL11.glReadPixels(mouseX, mouseY, 1, 1, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, winZ);
float zz = winZ.get();
GLU.gluUnProject(winX, winY, zz, modelview, projection, viewport, position);
Vector3f v = new Vector3f(position.get(0),position.get(1),position.get(2));
return v ;
}
I've solved it, for anyone interested, here is my modified code for getting the x and y in the world when z=0 :
static public Vector3f getMouseOnPlaneZ(int mouseX, int mouseY)
{
viewport.clear();
modelview.clear();
projection.clear();
winZ.clear();;
position.clear();
float winX, winY;
GL11.glGetFloat( GL11.GL_MODELVIEW_MATRIX, modelview );
GL11.glGetFloat( GL11.GL_PROJECTION_MATRIX, projection );
GL11.glGetInteger( GL11.GL_VIEWPORT, viewport );
winX = (float)mouseX;
winY = (float)mouseY;
GLU.gluUnProject(winX, winY, 0.0f, modelview, projection, viewport, position);
GLU.gluUnProject(winX, winY, 1.0f, modelview, projection, viewport, position1);
float zeropoint, zeroperc;
double posXt, posYt, posZt;
posXt = position.get(0) - position1.get(0);
posYt = position.get(1) - position1.get(1);
posZt = position.get(2) - position1.get(2);
if ((position.get(2) < 0.0 && position1.get(2) < 0.0) || (position.get(2) > 0.0 && position1.get(2) > 0.0))
return null;
zeropoint = 0.0f - (float)position.get(2);
//Find the percentage that this point is between them
zeroperc = (zeropoint / (float)posZt);
Vector3f v = new Vector3f((float)position.get(0) + (float)(posXt * zeroperc),(float)position.get(1) + (float)(posYt * zeroperc),(float)position.get(2) + (float)(posZt * zeroperc));
return v ;
}

glRotate changes coordinates so that the rectangle draws on a rotated plane

I am running into an issue here. I set up a square projectile with a velocity x an y, and draw the actual square to the location, by setting the vertex positions there like so.
Code:
vertices.put(new float[] { x1, y1, 1, 1, 1, 1, 0.0f, 1.0f,
x2, y2, 1, 1, 1, 1, 1.0f, 1.0f,
x3, y3, 1, 1, 1, 1, 1.0f, 0.0f,
x4, y4, 1, 1, 1, 1, 0.0f, 0.0f });
// x y r g b A u|s v|t
where all the x's are locations of corners that i pass in.
I then move this rectangle (l2rArrow) along the x & y axis, and have the screen follow it:
boolean hasTranslated = false;
if (!l2rArrow.isFired) { // if the arrow has not yet been fired we render it thus
gl.glPushMatrix(); //save our state
gl.glTranslatef(l2rArrow.GetToOriginX, l2rArrow.GetToOriginY, 0f); // translate to origin 0,0,0
gl.glRotatef(LBow.getAngle(), 0f, 0f, 1f); //rotate
gl.glTranslatef(-l2rArrow.GetToOriginX, -l2rArrow.GetToOriginY, 0f); // translate to where we want to draw it
texture.bind(gl, Texture.TEXTURE_L2RARROW);
mRect = new MeshRect(l2rArrow.getMyRect());
mRect.Draw(GL10.GL_TRIANGLES, gl);
gl.glPopMatrix(); //return to saved state
} else { // the arrow has been fired so we need to render it like this and have the "camera" follow it
hasTranslated = true;
gl.glPushMatrix();
gl.glLoadIdentity();
float camX = (float) ((l2rArrow.startX - l2rArrow.PosX));
float camY = (float) ((l2rArrow.startY - l2rArrow.PosY));
if (camY > 0) { camY = 0;}
if (camX < -4800) { camX = -4800;}
gl.glTranslatef(camX, camY,0f);
l2rArrow.Update(deltaTime);
texture.bind(gl, Texture.TEXTURE_L2RARROW);
mRect = new MeshRect(l2rArrow.getMyRect());
mRect.Draw(GL10.GL_TRIANGLES, gl);
if (l2rArrow.hasCollided) {
//run collision code for detecting a hit and ending turn
}
}
this works as well. When the projectile is fired we will follow it perfectly. Now though I want the arrow head to point at the angle the arrow is traveling. So I need to rotate the arrow to in mid flight. I tried translating this arrow back to 0,0 rotating it, and the putting it back but when i put the arrow back it draws on the coordinates of a rotated plane.
} else {
hasTranslated = true;
gl.glPushMatrix();
gl.glLoadIdentity();
float camX = (float) ((l2rArrow.startX - l2rArrow.PosX));
float camY = (float) ((l2rArrow.startY - l2rArrow.PosY));
if (camY > 0) { camY = 0;}
if (camX < -4800) { camX = -4800;}
gl.glTranslatef(camX, camY,0f);
gl.glPushMatrix();
gl.glTranslatef(l2rArrow.GetToOriginX, l2rArrow.GetToOriginY, 0f); // translate to origin 0,0,0
gl.glRotatef((float) l2rArrow.getAngle(), 0f, 0f, 1f); //rotate
gl.glTranslatef(-l2rArrow.GetToOriginX, -l2rArrow.GetToOriginY, 0f);
l2rArrow.Update(deltaTime);
texture.bind(gl, Texture.TEXTURE_L2RARROW);
mRect = new MeshRect(l2rArrow.getMyRect());
mRect.Draw(GL10.GL_TRIANGLES, gl);
gl.glPopMatrix();
if (l2rArrow.hasCollided) {
//run collision code for detecting a hit and ending turn
}
}
I understand this. How do I rotate the arrow, and then move it back into position on a non-rotated plane?
The arrow rests when it comes to Y=0, and as of right now Y=0 runs at the angle of the rotation.
After much research and deliberation I decided to switch the way I place objects in my world.
I now use what seems to be the Normal method which is to glTranslate them into place.
Everything now works perfectly.
Apparently the way I was doing it before was getting screwed up because drawing the vertex directly into the space you want it (not drawing it at the origin and then translating it) can get pretty messy.

random lines when drawing gles20 circle in Android

I've just started learning OpenGL for Android and I'm having a weird problem when drawing a circle. some of its vertices stick to the left and top wall making lines go out from the circle a bit randomly. Every time I restart the app they have a different position.
My DrawScreen class where the circle is drawn:
public class DrawScreen implements GLSurfaceView.Renderer {
Ball ball;
public float mAngle;
private int mProgram;
private int maPositionHandle;
private final String vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix; \n" +
"attribute vec4 vPosition; \n" +
"void main(){ \n" +
// the matrix must be included as a modifier of gl_Position
" gl_Position = uMVPMatrix * vPosition; \n" +
"} \n";
private final String fragmentShaderCode =
"precision mediump float; \n" +
"void main(){ \n" +
" gl_FragColor = vec4 (0.63671875, 0.76953125, 0.22265625, 1.0); \n" +
"} \n";
private int muMVPMatrixHandle;
private float[] mMVPMatrix = new float[16];
private float[] mVMatrix = new float[16];
private float[] mProjMatrix = new float[16];
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
ball = new Ball();
// Set the background frame color
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
ball.initShapes(240, 360, 50);
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mProgram); // creates OpenGL program executables
// get handle to the vertex shader's vPosition member
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
}
public void onDrawFrame(GL10 unused) {
// Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// Prepare the circle data
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 0, ball.ballVB);
GLES20.glEnableVertexAttribArray(maPositionHandle);
// Apply a ModelView Projection transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
// Draw the circle
GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, 0, (int) (ball.getNumSeg() * 3));
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
// this projection matrix is applied to object coodinates
// in the onDrawFrame() method
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
}
private int loadShader(int type, String shaderCode){
// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
And my Ball class where the circle is created:
public class Ball {
public FloatBuffer ballVB;
private float cx, cy, r;
float numSegments = 360;
public void initShapes(float tx, float ty, float tr){
cx = (tx / 240.f) - 1.f;
cy = (ty / 360.f) - 1.f;
r = (tr / 240.f);
float ballCoords[] = new float[(int) (numSegments * 3)];
double theta = (2 * 3.1415926 / numSegments);
float c = (float) Math.cos(theta);//precalculate the sine and cosine
float s = (float) Math.sin(theta);
float t;
float x = r;//we start at angle = 0
float y = 0;
for(int i = 0; i < (numSegments * 3); i = i + 3 ) {
ballCoords[i] = (x + cx);
ballCoords[i + 1] = (y + cy);
ballCoords[i + 2] = (0);
//apply the rotation matrix
t = x;
x = c * x - s * y;
y = s * t + c * y;
}
// initialize vertex Buffer for triangle
ByteBuffer vbb = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
ballCoords.length * 4);
vbb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order
ballVB = vbb.asFloatBuffer(); // create a floating point buffer from the ByteBuffer
ballVB.put(ballCoords); // add the coordinates to the FloatBuffer
ballVB.position(0); // set the buffer to read the first coordinate
}
public float getNumSeg(){
return numSegments;
}
}
I've been scouring the internet for hours but haven't found anything. Hope you guys can help me.
GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, 0, (int) (ball.getNumSeg() * 3));
I'm suspicious of this, are segments referring to individual vertices?
The final argument to glDrawArrays is the number of vertices to draw, not the number of floats. You should probably remove the * 3 multiplier from glDrawArrays.
Your extra lines are probably from drawing garbage data because you're drawing 3 times as many vertices as you've actually allocated.

Categories