Android OpenGL ES: How do you choose a 2D object?

I was looking for introductory 2D selection in OpenGL ES in Stack Overflow. I mainly see questions about 3D.

I am developing a 2D level editor on Android 4.0.3 using OpenGL ES. The level editor has a 2D, yellow, square object located in the center of the screen. All I wanted to do was determine if the object was affected by the user.

enter image description here

There is no tile overlap in the level editor. Instead, they are placed side by side, like two adjacent pixels in a bitmap in MS Paint. My goal is to individually define a touch event for each square object in the level editor.

The object is created using a simple vertex array and uses GL_TRIANGLES to draw 2 flat right-angled triangles. There is no manipulation and no loading from a file or anything else. The only thing I know is that if the user touches any of the yellow triangles, then both yellow triangles must be selected.

Can someone tell us how I need it? Thanks in advance.

EDIT:

This is the draw() function:

 public void draw(GL10 gl) { gl.glPushMatrix(); gl.glTranslatef(-(deltaX - translateX), (deltaY - translateY), 1f); gl.glColor4f(1f, 1f, 0f, 1f); //TODO: Move ClientState and MatrixStack outside of draw(). gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 6); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glPopMatrix(); } 

EDIT 2:

I still lack information. Do you use a camera? or clicking on other matrices before rendering the model ?. For example, if you use a spelling camera, you can easily remove the project screen coordinates [x_screen, y_screen] like this (y is similar):

I do not use a camera, but I probably use spelling projection. Again, I do not know, because I just use the general OpenGL function. I click and pop up matrices because I plan to integrate many tiles (square 2D objects) with different translation matrices. No two tiles will have the same translation matrix M.

Is perspective projection the same as spelling projection when it comes to 2D? I do not see the difference between the two.

Here's the initial setup when creating a surface (a class extending GLSurfaceView and implementing GLSurfaceView.Renderer ):

 public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); } public void onSurfaceCreated(GL10 gl, EGLConfig arg1) { reset(); } public void onDrawFrame(GL10 gl) { clearScreen(gl); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrthof(0f, super.getWidth(), 0f, super.getHeight(), 1, -1); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); canvas.draw(gl); } private void clearScreen(GL10 gl) { gl.glClearColor(0.5f, 1f, 1f, 1f); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); } 
+4
source share
3 answers

The basic approach will be as follows:

  • Define a bounding box for each tangible object. It should just be a rectangle (x, y, width, height).
  • When you update a tile in the world, you update it (completely in world coordinates).
  • When the user touches the screen, you need to turn off the coordinate screen of the world coordinates
  • Make sure that the non-projected point overlaps with any bounding box.

Some tips for previous items. [Edited]

  • 1 and 2. You will need to track where you are your tiles. Save their position and size. A rectangle is a convenient structure. In your example, this can be calculated like this. And you have to double-check it when the models change. Lets call it Rectangle r:

     rx = yourTile.position.x -(deltaX - translateX) ry = yourTile.position.y -(deltaY - translateY) r.width= yourTile.width //as there is no model scaling r.height = yourTile.height// 
  • 3 - if you use a spelling camera, you can easily delete the project coordinates [x_screen, y_screen] similar to this (y similarly):

     x_model = ((x_screen/GL_viewport_width) -0.5 )*camera.WIDTH + Camera.position.x 
  • 4 - For each of your rectangles, check [x_model; y_model] inside.

[2nd Edit] . By the way, you are updating your matrices, you might think that you are using a camera with postition surfaceView.width () / 2, surfaceView.height () / 2. You map 1 pixel on the screen to 1 units in the world, so you don't need to design anything. You can replace these values ​​in my formula and get x_screen = x_model - (you need to flip the Y component of the touch event because Y grows down in Java and up in GL).

Final words. If the user touches the point [x, y], check that [x, screenHeight-y] * hits some of your rectangles, and you are done. Do some debugging, write down touching points, and see how much they are expected. Create rectangles and see if they match what you see on the screen, and then check to see if the dot is inside the rectangle.

I must tell you that you should not set the screen size for the screen, because your application will be very different on different devices. This is a topic in itself, so I will not go further, but consider the definition of your model in terms of world units - regardless of screen size. It becomes so off-topic, but I hope you got a good idea of ​​what you need to know!

* Turning over, I told you. PS: stick to spelling projection (perspective will be more difficult to use).

+2
source

Please let me post the second answer to your question. This is a completely higher level / philosophical. It may be a stupid, useless answer, but I hope this helps someone new in computer graphics to change their mind to β€œgraphic mode”.

You cannot select a triangle on the screen. This square is not 2 triangles. This square is just a bunch of yellow pixels. OpenGL takes several vertices, connects them, processes them and colors some pixels on the screen. At one stage of the graphics pipeline, even geometric information is lost, and you only have isolated pixels. This is similar to a letter printed by a printer on paper. Usually you do not process information from paper (well, perhaps a barcode reader: D)

If you need to continue processing your drawings, you need to model them and process them yourself with auxiliary data structures. So I suggested creating a rectangle to model your fragments. You create your imaginary "world" of objects, and then visualize them on the screen. The touch-event user does not belong to the same world, so you need to "translate" the screen coordinates into your world coordinates. Then you change something in your world (maybe the user drags his finger and you need to move the object), and again say OpenGL to display your world on the screen.

You should work with your model, not the view. Meshes are more than that, so you should not mix them with model information, it is good practice to separate both things. (please expert correct me, I'm quite a graphics fan)

+1
source

Have you checked libgdx ?

Makes life a lot easier with OpenGL ES.

0
source

All Articles