I've just started learning OpenGL for Android and I'm having a weird problem when drawing lines. All i want to do is to draw a line based on a finger motion. Now as soon as I start swiping I always get a line folowing my motion from the origin(0,0).
here a picture:
http://imageshack.us/photo/my-images/137/screenshot2012061312174.jpg/
The arrow symbols my finger motion and the line starting in the origin (red circle) is the mentioned line folowing my entire motion.
Don't get bothered with the Coords array I know this isn't best practice but I debuged the entire programm and couldn't finde any bugs involving this array.
I probably should mention that the ArrayList points contains all my generated points.
I'm trying to figure this out for quit a while now but I'm really stuck any suggestion could be helpfull
This is my entire render class.
public class HelloOpenGLES20Renderer implements GLSurfaceView.Renderer {
private FloatBuffer triangleVB;
private int mProgram;
private int maPositionHandle;
public ArrayList<PointWrapper> points;
private int muMVPMatrixHandle;
private float[] mMVPMatrix = new float[16];
private float[] mMMatrix = new float[16];
private float[] mVMatrix = new float[16];
private float[] mProjMatrix = new float[16];
private int[] viewport = new int[4];
private ArrayList<Float> coordinates;
float[] Coords = new float[100000];
boolean first;
private int counter;
private PointWrapper last;
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 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;
}
public HelloOpenGLES20Renderer() {
points = new ArrayList<PointWrapper>();
first = true;
this.counter = 0;
last = new PointWrapper();
coordinates = new ArrayList<Float>();
}
private float[] convertCoordinates(PointWrapper f) {
float[] vector = new float[4];
GLU.gluUnProject(f.point.x, f.point.y, 0.0f, mVMatrix, 0, mProjMatrix,
0, viewport, 0, vector, 0);
return vector;
}
private void initShapes() {
ArrayList<PointWrapper> points2 = new ArrayList<PointWrapper>(points);
float[] vector;
if (!points2.isEmpty()) {
if(points2.size()%2==1){
points2.remove(points2.size()-1);
}
for (int i = counter/2; i < points2.size(); i++) {
vector = convertCoordinates(points2.get(i));
Coords[counter] = vector[0] / vector[3];
Coords[counter+1] = -1 * (vector[1] / vector[3]);
counter= counter+2;
}
}
// initialize vertex Buffer for triangle
ByteBuffer vbb = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
Coords.length * 4);
vbb.order(ByteOrder.nativeOrder());// use the device hardware's native
// byte order
triangleVB = vbb.asFloatBuffer(); // create a floating point buffer from
// the ByteBuffer
triangleVB.put(Coords); // add the coordinates to the
// FloatBuffer
triangleVB.position(0); // set the buffer to read the first coordinate
}
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
// Set the background frame color
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
// initialize the triangle vertex array
// initShapes();
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);
initShapes();
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// Prepare the triangle data
GLES20.glVertexAttribPointer(maPositionHandle, 2, GLES20.GL_FLOAT,
false, 0, triangleVB);
GLES20.glEnableVertexAttribArray(maPositionHandle);
// Apply a ModelView Projection transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glLineWidth(5f);
GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, counter);
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
viewport[0] = 0;
viewport[1] = 0;
viewport[2] = width;
viewport[3] = 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);
}
}
my thanks in advance
You have intialized Coords to hold 100000 floats and it initializes them to 0. In this loop the last iteration has 'counter' with the number of floats you have set in your array.
What you pass to glDrawArrays should be the number of VERTICES to draw. so in this case half of 'counter'.
Your for-loop is adding 'counter'/2 extra amount of (0,0) vertices at the end of your array. the quickest fix would be to pass 'counter'/ 2 to glDrawArrays but I'd suggest a clearer approach.
and then