How can I draw a single triangle from a Vertex Buffer Object and set its color? - iphone

I have created a Vertex Buffer Object containing only vertices for triangles, for drawing with the GL_TRIANGLES option. My VBO has no color information because I change the color every frame.
Now I'm trying to draw individual triangles in a loop after setting the default vertex color like this in every iteration:
glColor4f(red, green, blue, 1);
But I'm not sure how to perform the actual drawing.
Must I use glDrawArrays if I want to pick one or two triangles out of the VBO to draw them with a specific color, or must I use glDrawElements?
Is there a more efficient way to set the color for each triangle in the VBO and then draw it? Or is it fine to call glColor44 and glDrawArrays in a loop for every frame?

First of all, I would rather suggest to ignore the slightly higher memory cost and just store a color with each vertex inside the VBO and therefore just duplicate the triangle's color for each of the triangle's vertices (you cannot set per-triangle colors). This will most probably be much more efficient than drawing single triangles in a loop. Keep in mind that the advantage of VBOs is not only their possible GPU storage, but also the fact that you don't need driver calls for each and every triangle or even vertex. So just duplicate your per-triangle colors into per-vertex colors and draw everything with a single call to glDrawArrays (glDrawElements won't buy you much if you need to duplicate almost every vertex anyway, which makes indices just useless).
Said that, you can of course draw individual triangles with glDrawArrays, that's what the first and count parameters are for. So if you have a VBO containing the 9 vertices of 3 triangles, just call
glDrawArrays(GL_TRIANGLES, 3, 3);
to draw only the 2nd triangle. That easy. And likewise can you use the count and offset parameters of glDrawElements to select a particular part of the index array to draw.

Related

How to have a generator class in shader glsl with amplify shader editor

i want to create a shader that can cover a surface with "circles" from many random positions.
the circles keep growing until all surface covered with them.
here my first try with amplify shader editor.
the problem is i don't know how make this shader that create array of "point maker" with random positions.also i want to controll circles with
c# example:
point_maker = new point_maker[10];
point_maker[1].position = Vector2.one;
point_maker[1].scale = 1;
and etc ...
Heads-up: That's probably not the way to do what you're looking for, as every pixel in your shader would need to loop over all your input points, while each of those pixels will only be covered by one at most. It's a classic case of embracing the benefits of the parallel nature of shaders. (The keyword for me here is 'random', as in 'random looking').
There's 2 distinct problems here: generating circles, and masking them.
I would go onto generating a grid out of your input space (most likely your UV coordinates so I'll assume that from here), by taking the fractional part of the coords scaled by some value: UV (usually) go between 0 and 1, so if you want 100 circles you'd multiply the coord by 10. You now have a grid of 100 pieces of UVs, where you can do something similar to what you have to generate the circle (tip: dot product a vector on itself gives the square distance, which is much cheaper to compute).
You want some randomness, so you need to add some offset to the center of the circle. You need some sort of random number (there might be some in ASE I can't remember, or make one your own - there's plenty of that you look online) that is unique per cell of the grid. To do this you'd input the remainder of your frac() as value to your hash/random method. You also need to limit that offset depending on the radius of the circle so it doesn't touch the sides of the cell. You can overlay more than one layer of circles if you want more coverage as well.
Second step is to figure out if you want to display those circles at all, and for this you could make the drawing conditional to the distance from the center of the circle to an input coordinate you provide to the shader, by some threshold. (it doesn't have to be an 'if' condition per se, it could be clamping the value to the bg color or something)
I'm making a lot of assumptions on what you want to do here, and if you have stronger conditions on the point distribution you might be better off rendering quads to a render texture for example, but that's a whole other topic :)

Are shader passes drawn by object or by triangle in Unity?

In Unity, when we write a custom shader with multiple passes, are they executed:
For each triangle do:
For each pass do:
Draw the pass
Or:
For each Pass do:
For each triangle do:
Draw the pass
And if I have multiple materials in the mesh, are the faces drawn grouped by material?
Question 1
Second variant:
In Unity, when we write a custom shader with multiple passes, are they executed:
For each Pass do:
For each triangle do:
Draw the pass
Question 2
And if I have multiple materials in the mesh, are the faces drawn grouped by material?
Yes.
Explanation
Basically, all the rendering (in both OpenGL and Direct3D) is done following way:
Setup rendering parameters (shaders, matrices, buffers, textures, etc.);
Draw a group of primitives (this is called draw call);
Repeat these steps for all the graphics that needs to be rendered.
And the following heuristic rule is applicable: the less draw calls invoked in scene the better (for performance). Thus, in order to fulfill this rule (without reducing amount of primitives you draw) you want to have smaller number of draw calls with bigger number of primitives in each. Which in turn makes it obvious why Unity goes with second variant of your first question. And also explains why does Unity groups faces by material (because it minimizes draw calls number).

Open GL - ES 2.0 : Dynamically Changing the color

In most of the tutorials in opengl es they create a structure which holds the vertices of the geometry. This structure contains the position and color for each vertex. This vertex information is then sent to the vertex buffer and is then used to render the geometry on the screen. My question is if I want to draw 2 cubes on the screen do I need to create 2 different structures objects or can I get by just creating a single structure and then changing the color dynamically.
This is the definition of my structure
struct Vertex{
float Position[3];
float Color[4];
}
Yes you can use just one instance of the structure, draw it, than change the colors of it and draw it again with another world matrix. Though I don't think that would be very good for performance.
But the best thing to do would be to create two instances of that one structure each one containing different colors, then draw them in differents positions by multiplying a translation matrix to their world matrix.

Easiest way to visualize 10,000 shaded boxes in 3D

I have a simple task: I have 10,000 3D boxes, each with a x,y,z, width, height, depth, rotation, and color. I want to throw them into a 3D space, visualize it, and let the user fly through it using the mouse. Is there an easy way to put this together?
One easy way of doing this using recent (v 3.2) OpenGL would be:
make an array with 8 vertices (the corners of a cube), give them coordinates on the unit cube, that is from (-1,-1, -1) to (1, 1, 1)
create a vertex buffer object
use glBufferData to get your array into the vertex buffer
bind the vertex buffer
create, set up, and bind any textures that you may want to use (skip this if you don't use textures)
create a vertex shader which applies a transform matrix that is read from "some source" (see below) according to the value of gl_InstanceID
compile the shader, link the program, bind the program
set up the instance transform data (see below) for all cube instances
depending on what method you use to communicate the transform data, you may draw everything in one batch, or use several batches
call glDrawElementsInstanced N number of times with count set to as many elements as will fit into one batch
if you use several batches, update the transform data in between
the vertex shader applies the transform in addition to the normal MVP stuff
To communicate the per-cube transform data, you have several alternatives, among them are:
uniform buffer objects, you have a guaranteed minimum of 4096 values, respectively 256 4x4 matrices, but you can query the actual value
texture buffer objects, again you have a guaranteed minimum of 65536 values, respectively 4096 4x4 matrices (but usually something much larger, my elderly card can do 128,000,000 values, you should query the actual value)
manually set uniforms for each batch, this does not need any "buffer" stuff, but is most probably somewhat slower
Alternatively: Use pseudo-instancing which will work even on hardware that does not support instancing directly. It is not as elegant and very slightly slower, but it does the job.

OpenGL: optimizing render of quad particles

I'm rendering particles in a 2D game. Each particle is a quad (2 triangles). How can I make the drawing the fastest possible? All the particles has the same texture, I'm only changing it's positions.
Now I'm using a call to glVertexPointer and glDrawArrays for each particle. So I'm sending 4 vertices each time to the GPU.
Is there any other approach that could be faster?
I'm using OpenGL ES 1.1 (iPhone)
Thanks!
Every draw call you make (glDrawArrays) is expensive. Doing this once per particle is DEFINITELY way too often. All your particles can be drawn with a single draw call; just set up a big array of all the triangle verts and another big array with the texture coords, and call glVertexPointer/glDrawArrays once-- that's the power of glVertexPointer: arbitrary geometry of the same type in one call. :)
For what you're doing, you should also look into point sprites (GL_POINTS), which also function as tiny textured quads. They're 2D only, so you can't map your texture into the Z axis, but if your particles are just 2D quads of the same texture over and over, point sprites will likely do exactly what you want.
There's a way to do that all in one draw routine. I THINK it's by adding an extra vertex after each quad, which is the same as the previous vertex, but I could be wrong.
EDIT: After looking into it a bit, it looks like you need two in between; essentially one after, and one before. It does add up to quite a few extra vertexes, but I know from experience that it makes a HUGE positive difference on the iPhone to do it all in one draw operation (we were drawing text from a texture, so essentially the same thing).
EDIT2: Also note, I'm referring to using GL_TRIANGLE_STRIP - if you were using GL_TRIANGLES instead, you wouldn't need the extra vertices... except, then you'd be doing the same amount extra anyway, due to repeating 2 for each second triangle.