Cairo only render to specific color component - cairo

I am using Cairo and would like to render one color component at a time. For example, if I render a set of blue rectangles and then render a set of red rectangles, I want where they overlap to be purple rather than red.
Using set_source_rgb(ctx, 0.0, 1.0, 0.0) doesn't work, because it will overwrite the other channels with zeros. Using transparency doesn't work either, as it equally effects all channels. I would like a way to only render to one channel.
Is that possible? Thank you.

Use CAIRO_OPERATOR_ADD instead of CAIRO_OPERATOR_OVER (the default):
#include <cairo.h>
int main() {
cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 20, 20);
cairo_t *cr = cairo_create(s);
cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
/* Render blue */
cairo_set_source_rgb(cr, 0, 0, 1);
cairo_rectangle(cr, 0, 0, 15, 15);
cairo_fill(cr);
/* Render red */
cairo_set_source_rgb(cr, 1, 0, 0);
cairo_rectangle(cr, 5, 5, 15, 15);
cairo_fill(cr);
cairo_surface_write_to_png(s, "out.png");
cairo_destroy(cr);
cairo_surface_destroy(s);
return 0;
}

Related

Batching OpenGL sprites

i have been learning OpenGL and have been able to create a successful 2d drawing system using triangle strips. I wrote a particle generator to test batching the geometry and everything works well, i'm able to render 30k+ vertices at 60 fps on an iPhone 5. I use degenerative triangles to connect the particles and draw them at once. What i am trying to accomplish is batch rendering without using degenerative triangles as that would reduce the amount of data being sent to the GPU by 1/3 the amount which would be huge.
I am attempting to use glDrawElements with triangles to draw 2 sprites with the following code
//the vertices for the square (2d)
GLfloat square[] = {
50, 50, //bottom left
100, 50, //bottom right
50, 100, //top left
100, 100, //top right
150, 200, //bottom left
200, 150, //bottom right
150, 200, //top left
200, 200 //top right
};
//texture coords
GLfloat tex[] = {
0,0,
1,0,
0,1,
1,1,
0,0,
1,0,
0,1,
1,1
};
GLubyte indices[] =
{
0,2,3,
0,3,1,
0,2,3,
0,3,1
};
//actual drawing code
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, square);
glVertexAttribPointer(ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, tex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, image);
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, indices);
This code draws the first image without issue, but the second image is distorted. I have been looking online but have been unable to figure out how to make this work correctly.
First of all, you're currently using the same indices for both quads, so the second image shouldn't even be visible at all.
Other than that your vertex data for the second quad is messed, you have the point (150, 200) two times, the first one should probably be (150, 150).

Incorrect colors implementation OpenGL ES2 - IOS

I have very simple OpenGL ES example similar to Hehe's example : http://nehe.gamedev.net/tutorial/ios_lesson_02__first_triangle/50001/
As shown above triangle filled with three colors - red, blue, green.
Instead in my app i always get triangle almost completely filled with black color, only small area around top vertex filled with green and small area around right bottom filled with red ... and there is no blue at all.
The first question is : why do the colors not interpolate in the middle of my triangle and why does blue color is not visible at all?
Any changes in my colors array affect nothing, e.g. when i try to make triangle white the colors do not change anyway ... in the meantime if i change Z coordinate in positions array then i can see the blue color.
The second question is : why any changes in colors do nothing and changes in positions change the color instead?
Seems like somewhere here i made one stupid mistake but i can't catch it.
This is Vertex / Color arrays :
const float colors[] = { // this does not work, triangle still black-green-red
1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0
};
const float positions[] = { // if i change 3rd index to 1.0 then i will see blue color
-0.5, -0.5, 0.0, 1.0,
0.0, 0.5, 0.0, 1.0,
0.5, -0.5, 0.0, 1.0
};
This is VBO :
- (BOOL)setupVBO
{
BOOL success = YES;
glGenBuffers(1, &_positionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _positionBuffer);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(positions) * sizeof(float),
&positions[0],
GL_STATIC_DRAW);
glGenBuffers(1, &_colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _colorBuffer);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(colors) * sizeof(float),
&colors[0],
GL_STATIC_DRAW);
return success;
}
Render :
- (void)render:(CADisplayLink*)displayLink
{
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, _positionBuffer);
glVertexAttribPointer(_positionSlot, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, _colorRenderBuffer);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays(GL_TRIANGLES, 0, 3);
[_glContext presentRenderbuffer:GL_RENDERBUFFER];
}
Thanks for any advice ...
Ok, i found where was the issue :)
As far as i am beginner in Open GL i just copypasted the code from example and renamed some variables ... and did not catch that i renamed ColorBuffer (VBO color, i.e. actual color data of drawing object) variable to ColorRenderBuffer variable (place in memory where GL processes actual color data)
Stupid mistake and i hope nobody will do the same :)

Corrupted image if variable is not static

I'm doing the following:
static GLfloat vertices[3][3] =
{
{0.0, 1.0, 0.0},
{1.0, 0.0, 0.0},
{-1.0, 0.0, 0.0}
};
glColor4ub(255, 0, 0, 255);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLES, 0, 9);
glDisableClientState(GL_VERTEX_ARRAY);
This works ok:
http://dl.dropbox.com/u/41764/posts/Screen%20shot%202010-03-28%20at%2020.04.56.png
However, if I remove static from vertices and therefore re-create the data on the stack on each rendering, I get the following:
http://dl.dropbox.com/u/41764/posts/Screen%20shot%202010-03-28%20at%2020.06.38.png
This happens both on the simulator and on the device.
Should I be keeping the variables around after I call glDrawArrays?
The reason you're seeing weird results is because you're not drawing what you think you are.
glDrawArrays(GL_TRIANGLES, 0, 9);
This means draw 9 vertices, hence 3 triangles. You only have 3 vertices declared in your array, so what the other 2 triangles will end up being is anybody's guess. You can see in the second picture that you indeed have more than 1 triangle... The data it ends up using is whatever else is on the stack at that time.
glDrawArrays does transfer on call, and I seriously doubt the iPhone would not be compliant on this. It's really basic GL, that (I believe) gets tested for conformance.
You are rendering uninitialized data in both cases. It just happens to look correct in the static case.
The third parameter to glDrawArrays is the number of vertices (which should be 3 in your case because you are trying to draw a single triangle).
You already told the GL that you are specifying 3 GLfloat per vertex (the first parameter of glVertexPointer). So the GL can figure out the total number of GLfloat to expect.
This should work:
GLfloat vertices[3][3] =
{
{0.0, 1.0, 0.0},
{1.0, 0.0, 0.0},
{-1.0, 0.0, 0.0}
};
glColor4ub(255, 0, 0, 255);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);

Why does this Drawing glitch happen with GL_TRIANGLE_STRIP in OpenGL ES 1.1

So I'm starting to work with openGL, been following the tutorials over at Jeff LaMarche's blog and I've run into a problem when trying to draw a square using the GL_TRIANGLE_STRIP mode with glDrawArrays.
It works, by that I mean that I can draw a square, but I get this weird drawing glitch. You can see it here:
Drawing glitch http://img10.imageshack.us/img10/1631/picture1io.png
I'm using the xcode template that's provided by Jeff, so I assume the setup is all proper. The code I'm using in the drawView function is as follows:
Square2D *square = malloc(sizeof(Square2D));
Square2DSet(square, -0.25, -0.25, -20.0, 0.5, 0.5);
glLoadIdentity();
glClearColor(0.7, 0.7, 0.7, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glColor4f(1.0, 0.0, 0.0, 1.0);
glVertexPointer(3, GL_FLOAT, 0, square);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 12);
glDisableClientState(GL_VERTEX_ARRAY);
if(square != NULL)
free(square);
here's the code for Square2d and Square2DSet:
typedef struct {
Vertex3D tl;
Vertex3D bl;
Vertex3D tr;
Vertex3D br;
} Square2D;
static inline void Square2DSet(Square2D *sq, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
{
sq->tl = Vertex3DMake(x, y, z);
sq->bl = Vertex3DMake(x, y + height, z);
sq->tr = Vertex3DMake(x + width, y, z);
sq->br = Vertex3DMake(x + width, y + height, z);
}
I'm sure I'm doing something wrong, just not sure what. Eventually the glitch will go away after the program has run for a little bit.
Any ideas?
Cheers
glDrawArrays(GL_TRIANGLE_STRIP, 0, 12);
is drawing 12 vertices. You want 4. Its asking how many indices, not how many values to look at. It will multiply the index by the number of values at each index.
The reason why its going crazy is because its drawing junk, then it disappears because I assume that junk gets filled with 0s or something and it just goes away.

OpenGL to OpenGL-ES - glRectf()

I am trying to learn OpenGL on the iPhone using the "Super Bible" but am having trouble porting from OpenGLto OpenGL ES. My understanding is that the glRectf() function is not available in the latter. What is the substitute approach? Any relevant conceptual information would be appreciated as well.
The substitute approach is to draw a triangle strip:
GLfloat texture[] =
{
0, 0,
0, 1,
1, 0,
1, 1
};
GLfloat model[] =
{
0, 0, // lower left
0, h, // upper left
w, 0, // lower right
w, h // upper right
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, model);
glTexCoordPointer(2, GL_FLOAT, 0, texture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
This draws a textured rectangle with width w and height h.
Rather than doing a rect, you just do two triangles.
This is really irrelevant though since GL-ES on the iPhone does not support immediate mode. You need to define all your vertices in an array and use one of the vertex array rendering functions to draw them rather than using the immediate mode functions.