Hi everybody !
I am writing an application on Android.
In this application, I want to display on the screen a set of rectangular tiles, that act as “big pixels”.
I have around 200x150 = 30000 tiles. But it could be higher !
Each tile has two attributes: a color and a visibility flag.
Tiles do not move, but they can, at any moment:
- change color,
- appear or disappear.
Here is how I have implemented these tiles …
Each tile is composed by two triangles.
Each triangle is a set of three vertex.
Each vertex is composed by:
- a coordinate x, y (2 floats)
- an rgb color (3 floats),
- a visibility flag (1 float)
In the vertex shader, if the visibility flag has a certain value, I move the vertex very far. So it is not shown. I hope the fragment shader is not called.
If it has the correct value, I set the vertex coordinates and color.
In the application, after setting the buffers, I only do:
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, mNbVertices);
And it works well and fast !!!
I was asking myself if I can improve this design, as I find that there is a lot of redundancy.
The position part of some vertex, could be common to four tiles, which can mean 8 triangles …
Do you have any tips for improving this design ?
First of all, if you want “big pixels”, why don’t you use “big pixels” by switching to a lower resolution?
Second, your memory usage could be improved by using an indexed rendering, i.e. you have
a vertex buffer with a vertex for each corner of a “big pixel” and an index buffer specifying the vertex indices to use for assembling triangles.
Thanks for your reply !
First, these tiles cover only a part of my screen to simulate an old computer screen. And this screen can move/rotate in 3d space. And I do not how to change the resolution of an android device.
Second, indexed rendering would by okay as it shares vertex, but what about the color ? In fact I would like to share only the positions part of vertex, and not the color or visiblity state (each pixel has its own color).
Considering your use case, why don’t you simply use a textured rectangle? You draw stuff locally in memory and update portions of
the texture that change. You use nearest-neighbour sampling for the texture to get your desired I-can-see-the-pixels blockyness and
only need to draw two triangles.
That is what I have done first. It works very well on some tablets (Nexus 7), and lags on a “new galaxy tab 10”. With profiling I detect the the texture update is the main consumer. Problem of power 2 texture sizes ? Video driver ? That is why I move to rendering triangles.