Drawing a filled square with Objective-C / Cocos2D - objective-c

I'm desperatly trying to draw a filled square with Cocos2D and I can't manage to find an example on how to do it :
Here is my draw method. I succeeded in drawing a square but I can't manage to fill it !
I've read that I need to use a OpenGL method called glDrawArrays with a parameter GL_TRIANGLE_FAN in order to draw a filled square and that's what I tried.
-(void) draw
{
// Disable textures - we want to draw with plaine colors
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position | kCCVertexAttribFlag_Color );
float l_fRedComponent = 0;
float l_fGreenComponent = 0;
float l_fBlueComponent = 0;
float l_fAlphaComponent = 0;
[mpColor getRed:&l_fRedComponent green:&l_fGreenComponent blue:&l_fBlueComponent alpha:&l_fAlphaComponent];
ccDrawColor4F(l_fRedComponent, l_fGreenComponent, l_fBlueComponent, l_fAlphaComponent);
glLineWidth(10);
CGPoint l_bottomLeft, l_bottomRight, l_topLeft, l_topRight;
l_bottomLeft.x = miPosX - miWidth / 2.0f;
l_bottomLeft.y = miPosY - miHeight / 2.0f;
l_bottomRight.x = miPosX + miWidth / 2.0f;
l_bottomRight.y = miPosY - miHeight / 2.0f;
l_topRight.x = miPosX + miWidth / 2.0f;
l_topRight.y = miPosY + miHeight / 2.0f;
l_topLeft.x = miPosX - miWidth / 2.0f;
l_topLeft.y = miPosY + miHeight / 2.0f;
CGPoint vertices[] = { l_bottomLeft, l_bottomRight, l_topRight, l_topLeft, l_bottomLeft };
int l_arraySize = sizeof(vertices) / sizeof(CGPoint) ;
// My old way of doing this, it draws a square, but not filled.
//ccDrawPoly( vertices, l_arraySize, NO);
// Deprecated method :(
//glVertexPointer(2, GL_FLOAT, 0, vertices);
// I've found something related to this method to replace the deprecated one, but can't understand this method !
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, l_arraySize);
}
I've found some examples with the old version of Cocos2D (1.0) but since it's been upgraded to version 2.0 "lately" all the examples I find give me compilation errors !
Could anyone enlight my path here please ?

I didn't know today is "Reinvent the Wheel" day. :)
ccDrawSolidRect(CGPoint origin, CGPoint destination, ccColor4F color);
If you were to go all crazy and wanted to draw filled polygons, there's also:
ccDrawSolidPoly(const CGPoint *poli, NSUInteger numberOfPoints, ccColor4F color);
The "solid" methods are new in Cocos2D 2.x.

You can simply create CCLayerColor instance with needed content size and use it as filled square. In other case you have to triangulate your polygon (it will have two triangles in case of square) and draw it using OpenGL.
---EDIT
Didn't test this code, find it with google, but it seems to work fine.
http://www.deluge.co/?q=cocos-2d-custom-filled-polygon

Related

How to draw a circle using VBO in ES2.0

I am trying to develop an ES 2.0 application in Linux environment. My target GPU is Fujitsu ruby MB86298 . To optimize the performance I have decided to use the VBO concept. I am very new to VBOs. I rendered basic primitives like triangle and quads using VBO where I have less no vertices . For rendering crown using a VBO, I computed all the vertices(more than 200). Now I am finding difficulty in sending this data of 200 vertices to the VBO.I cannot manually enter the all the vertex data and store in an array and pass it to VBO. Is there any way to send that vertex data of each for loop( used in computation of vertices of crown) to the VBO? Can any one share the code snippet of drawing an arc or circle in ES 2.0 using VBO's?
Here's some code fragments for rendering a circle. I haven't compiled or run this code, so there's a possibility of (hopefully minor) typos.
To prepare the VBO, which would be done once:
// Number of segments the circle is divided into.
const unsigned DIV_COUNT = 32;
// Will use a triangle fan rooted at the origin to draw the circle. So one additional
// point is needed for the origin, and another one because the first point is repeated
// as the last one to close the circle.
GLfloat* coordA = new GLfloat[(DIV_COUNT + 2) * 2];
// Origin.
unsigned coordIdx = 0;
coordA[coordIdx++] = 0.0f;
coordA[coordIdx++] = 0.0f;
// Calculate angle increment from point to point, and its cos/sin.
float angInc = 2.0f * M_PI / static_cast<float>(DIV_COUNT);
float cosInc = cos(angInc);
float sinInc = sin(angInc);
// Start with vector (1.0f, 0.0f), ...
coordA[coordIdx++] = 1.0f;
coordA[coordIdx++] = 0.0f;
// ... and then rotate it by angInc for each point.
float xc = 1.0f;
float yc = 0.0f;
for (unsigned iDiv = 1; iDiv < DIV_COUNT; ++iDiv) {
float xcNew = cosInc * xc - sinInc * yc;
yc = sinInc * xc + cosInc * yc;
xc = xcNew;
coordA[coordIdx++] = xc;
coordA[coordIdx++] = yc;
}
// Repeat first point as last point to close circle.
coordA[coordIdx++] = 1.0f;
coordA[coordIdx++] = 0.0f;
GLuint vboId = 0;
glGenBuffers(1, &circVboId);
glBindBuffer(GL_ARRAY_BUFFER, circVboId);
glBufferData(GL_ARRAY_BUFFER, (DIV_COUNT + 2) * 2 * sizeof(GLfloat), coordA, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
delete[] coordA;
Then to draw, with posLoc being the location of the vertex attribute for the position:
glBindBuffer(GL_ARRAY_BUFFER, circVboId);
glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posLoc);
glDrawArrays(GL_TRIANGLE_FAN, 0, DIV_COUNT + 2);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Trying to implement OpenGL brush

I'm trying to implement OpenGL brush for mac os. Using GLPaint as sample. Main trouble is that GLPaint is iOS application, and I need it on mac os. Somehow i almost edited it to work on MAC OS (well at least i think so), but it's still not running. I guess, the main issue is in 'EAGLContext' and 'NSOpenGLContext' or maybe 'OpenGL' and 'OpenGL ES' differences. When I try to use 'renderLineFromPoint:ToPoint:'
[self renderLineFromPoint:vieta toPoint:buvusVieta];
it shows me error at
`glBindFramebuffer(GL_FRAMEBUFFER, viewFramebufferis);
with error code
Thread 1: EXC_BAD_ACCSESS (code=1, adress=0x1508)
Whole 'renderLineFromPoint:toPoint:' code bellow
- (void) renderLineFromPoint:(CGPoint)pradzia toPoint:(CGPoint)pabaiga
{
static GLfloat* vertexBuffer = NULL;
static NSUInteger vertexMax = 64;
NSUInteger vertexCount = 0, count, i;
[context makeCurrentContext];
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebufferis);
//Convert from point to pixel
CGFloat scale = self.contentsScale;
pradzia.x *= scale;
pradzia.y *= scale;
pabaiga.x *= scale;
pabaiga.y *= scale;
//Vertex array buffer
if(vertexBuffer == NULL)
vertexBuffer = malloc(vertexMax * 2 * sizeof(GLfloat));
//Add points to buffer at X pixels
count = MAX(ceilf(sqrtf((pabaiga.x - pradzia.x) * (pabaiga.x - pradzia.x) + (pabaiga.y - pradzia.y) * (pabaiga.y - pradzia.y)) / kBrushPixelStep), 1);
for(i = 0; i < count; ++i) {
if (vertexCount == vertexMax) {
vertexMax = 2 * vertexMax;
vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat));
}
vertexBuffer[2 * vertexCount + 0] = pradzia.x + (pabaiga.x - pradzia.x) * ((GLfloat)i / (GLfloat)count);
vertexBuffer[2 * vertexCount + 1] = pradzia.y + (pabaiga.y - pradzia.y) * ((GLfloat)i / (GLfloat)count);
vertexCount += 1;
}
//Render vertex array
glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
glDrawArrays(GL_POINTS, 0, vertexCount);
//Show buffer
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbufferis);
[context presentRenderbuffer:GL_RENDERBUFFER];
}
Anyone could help me?
Or maybe someone could point me to similar sample code?
That would be very useful even if someone links me to tutorial where is explained such a thing as drawing in real time or etc. I have no problems with mouse events tracking and registering its points. I just need somehow to make OpenGL to draw line between two points or to draw for example circle at each registered point. Any ideas?
I think you accidentally enabled a breakpoint. Just delete the breakpoint or disable it.
I solved my problem. I just had to use
mouseDown
mouseDragged
mouseUp
functions to register mouse events, and then call function [self drawSomething]; in witch was written what to draw and use coordinates witch was given me by 'mouseDown' 'mouseDragged' 'mouseUp'.

Image processing in Obj-C

I want to do some scientific image processing on iOS in Obj-C or of course C, all I require to do this is to get a 3D array of the bit values of all the pixels' RGBA. UIImage doesn't seem to have a built in function. Do any of you know how to get the pixel values or more preferably a predefined library with those functions in there?
Thanks in advance, JEM
You'd normally either create a CGBitmapContext, telling it to use some memory you'd allocated yourself (so, you know where it is and how to access it) or let Core Graphics figure that out for you and call CGBitmapContextGetData if you're targeting only iOS 4/OS X 10.6 and later, then draw whatever you want to inspect to it.
E.g. (error checking and a few setup steps deliberately omitted for brevity; look for variables I use despite not defining and check the function documentation)
CGBitmapInfo bitmapInfo =
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
context =
CGBitmapContextCreate(
NULL,
width, height,
8,
width * 4,
rgbColourSpace,
bitmapInfo);
CGContextDrawImage(
context,
CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height),
[image CGImage]);
uint8_t *pixelPointer = CGBitmapContextGetData(context);
for(size_t y = 0; y < height; y++)
{
for(size_t x = 0u; x < width; x++)
{
if((bitmapInfo & kCGBitmapByteOrder32Little))
{
NSLog(#"rgba: %02x %02x %02x %02x",
pixelPointer[2], pixelPointer[1],
pixelPointer[0], pixelPointer[3]);
}
else
{
NSLog(#"rgba: %02x %02x %02x %02x",
pixelPointer[1], pixelPointer[2],
pixelPointer[3], pixelPointer[0]);
}
pixelPointer += 4;
}
}

How to draw circular bars?

I am devleoping a game with cocos2d-iphone.
I want to great a circular health bar. Think of Kingdom Hearts or something.
I am able to draw circles with ccDrawLine, but they are full circles. Basically, I need to be able to draw up to a certain circumference value to represent the health properly. However, I am not really sure about this. Any ideas?
I had a quick look at the code for ccDrawCircle. If I was approaching this, I'd probably start by modifying the way the for loop works (maybe by playing with coef or segs) so that it stops early.
void ccDrawCircle( CGPoint center, float r, float a, NSUInteger segs, BOOL drawLineToCenter)
{
int additionalSegment = 1;
if (drawLineToCenter)
additionalSegment++;
const float coef = 2.0f * (float)M_PI/segs;
GLfloat *vertices = calloc( sizeof(GLfloat)*2*(segs+2), 1);
if( ! vertices )
return;
for(NSUInteger i=0;i<=segs;i++)
{
float rads = i*coef;
GLfloat j = r * cosf(rads + a) + center.x;
GLfloat k = r * sinf(rads + a) + center.y;
vertices[i*2] = j * CC_CONTENT_SCALE_FACTOR();
vertices[i*2+1] =k * CC_CONTENT_SCALE_FACTOR();
}
vertices[(segs+1)*2] = center.x * CC_CONTENT_SCALE_FACTOR();
vertices[(segs+1)*2+1] = center.y * CC_CONTENT_SCALE_FACTOR();
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_TEXTURE_COORD_ARRAY, GL_COLOR_ARRAY
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) segs+additionalSegment);
// restore default state
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
free( vertices );
}
CGContextAddArc() will do the trick. An example explains everything.
CGContextAddArc(CGFloat centerX, CGFloat centerY, CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise);
I'm not quite sure about the order of the parameters, you'd better google it or let XCode do the work for you.

Draw Polygons with Triangle Fan in OpenGLES

I want to draw polygons with triangle fan. I get the polygons as a data structure with a count of the number of edges followed by an array of coordinates. I figured out that it should work something like this:
-(void) fillarea:(int16_t) count vertices:(int16_t*) pxyarray {
int valueCount = count*2;
GLfloat vertexBuffer[valueCount];
for (int i=0; i<valueCount; i++) {
vertexBuffer[i] = pxyarray[i];
}
glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
glDrawArrays(GL_TRIANGLE_FAN, 0, valueCount);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
It seems to work perfect with triangles, however as soon as I use polygons with more edges (squares, pentagons,...) they all draw another triangle to the origin at 0,0. Can someone explain to me what is happening here.
If it helps some examples for polygons I defined to be drawn with this method:
int16_t verticesTriangle[6] = {50,50,100,50,100,100};
[self fillarea:3 vertices:verticesTriangle];
int16_t verticesSquare[8] = {100,100,150,100,150,150,100,150};
[self fillarea:4 vertices:verticesSquare];
int16_t vertices5[10] = {150,50,175,25,200,50,200,100,150,100};
[self fillarea:5 vertices:vertices5];
int16_t vertices6[12] = {250,50,275,25,300,50,300,75,275,100,250,75};
[self fillarea:6 vertices:vertices6];
The answer to the problem is actually very simple. glDrawArrays wants to know the number of vertices not the number of values handed over to it. So instead of writing:
glDrawArrays(GL_TRIANGLE_FAN, 0, valueCount); // valueCount = 6 for a triangle
I need to write:
glDrawArrays(GL_TRIANGLE_FAN, 0, count); // count = 3 for a triangle
You got the wrong Type To Draw Squares and Rectangle you need to user GL_TRIANGLE_STRIP.
With GL_TRIANGLE_FAN the first Vertex is your center and all triangles will be generated with the center and the last inserted vertex and your actual vertex.