GL_POINT not rendering when center is off screen - iphone

I'm making an iPhone game that involves the use of GL_POINT to render a point. However, when the center of the point is off screen, I still want to draw whatever portion of the point that is still onscreen. Here is my code that I'm using to render the point.
-(void)render {
if (!fill || !outline || !active || dead)
return;
NSLog(#"rendering");
glPushMatrix();
glLoadIdentity();
glMultMatrixf(matrix);
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_SMOOTH);
glEnable(GL_POINT_SMOOTH);
glPointSize(scale.x*2);
[outline render];
glPointSize(2*(scale.x-kLineWidth));
[fill render];
glPopMatrix();
}
note that it logs "rendering" when it should be rendering, so this method is getting called properly.
and the [outline render] and [fill render] methods look like this
-(void)render {
// load arrays into the engine
glVertexPointer(vertexSize, GL_FLOAT, 0, vertexes);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(colorSize, GL_FLOAT, 0, colors);
glEnableClientState(GL_COLOR_ARRAY);
//render
glDrawArrays(renderStyle, 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
and I'm using a "panning" effect using this code
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-kScreenWidth/2.0 + xPan, kScreenWidth/2.0 + xPan, -kScreenHeight/2.0 + yPan, kScreenHeight/2.0 + yPan, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
but when the point's center is not on the screen (after panning with glOrthof), the whole point is not drawn. How can I have the point still render even when the center is not on the screen?

I don't believe there is anything you can do for an easy fix. Primitives are clipped before rasterization, so if that point lies outside the view frustum, it's not going to be rasterized, even if the rasterization would create fragments that do lie inside the view frustum.
Either switch to real quads with GL_TRIANGLES/GL_QUADS, or if you really don't want to do that, you can render your points to an offscreen buffer with size slightly larger than the viewport, and then blit the center of that image back onto the main frame.

Related

Stretched Drawing in OpenGL ES - iOS

I'm trying to draw a simple circle using OpenGL ES. The problem is that the circle is stretched vertically. It looks more like an ellipse than a circle. Could someone point out where the things are going wrong?
I played around with glViewPort to fix this but was not successful. As someone else suggested here on Stackoverflow, I also tried loading a different matrix instead of the identity matrix and that doesn't work too...
Here's the code of drawFrame:
- (void)drawFrame
{
[(EAGLView *)self.view setFramebuffer];
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GLfloat vertices[720];
for (int i = 0; i < 720; i += 2)
{
vertices[i] = (cos(degreesToRadians(i)) * 1);
vertices[i+1] = (sin(degreesToRadians(i)) * 1);
}
glVertexPointer(2, GL_FLOAT, 0, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glDrawArrays(GL_TRIANGLE_FAN, 0, 360);
[(EAGLView *)self.view presentFramebuffer];
}
The code you are showing will draw a perfect circle in world co-ordinates. What you need to consider is how those world co-ordinates transform into window co-ordinates i.e. pixels.
If the glViewport is set to always match the window then it's the aspect ratio of the window that will determine what you see using the code sample you have shown. If the window is square it will work i.e. you will see a perfect circle. If the window is taller than it is wide then the circle will be stretched vertically.
To preserve the perfect circle you can use a projection matrix that gives you a viewing volume of the same aspect ratio as the viewport/window. I noticed that before your first edit you had a call to glOrthof in there. Set the aspect ratio to match there and that will do the job for you. If you want a perspective projection instead of an orthographic projection then use glFrustum.

Want to add color to a rectangle which i draw using openGL function

I have to know how to add color to the rectangle drawn with the below method (which i took from a sample here).. Its by setting the openGL color to some color. But i dont know how to do it. Some help would be appreciated.
-(void) ccDrawFilledRect
{
HelloWorld *gs = [(swipeAppDelegate*)[[UIApplication sharedApplication] delegate] gameScene];
CGPoint poli[]= {gs.StartPoint,CGPointMake(gs.StartPoint.x,gs.EndPoint.y),gs.EndPoint,CGPointMake(gs.EndPoint.x,gs.StartPoint.y)};
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, poli);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
NSLog(#"openGL rectangles drawn !!");
// restore default state
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
}
NeHe has a lot of easy OpenGL tutorials. This one is on adding color http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=03 . Make your you have colors and color buffers enabled.
Have you tried putting glColor3d(1, 0, 0) before glVertexPointer?

Drawing individual pixels with iphone sdk

I've been trying to figure out how to make a powder toy style game on the iPhone. My problem is how to draw pixels to the screen. From what I've read, OpenGL is better for games as it is faster/hardware accelerated, but there is no method to draw pixels directly to the screen. Apparently drawing pixels to an off-screen frame buffer is the way to go, but how do I then pass this to OpenGL? Do I use a texture?
(this is assuming I have no previous knowledge of iPhone graphics programming).
Thanks!
Usually in OpenGL you draw primitives and polygons. If you need to draw a bitmap, then you need to apply texture for your polygon.
Check out cocos2d-iphone engine for 2D games based on OpenGL.
If you still need to draw a pixel, here is a method from cocos2d to draw a line:
void ccDrawLine( CGPoint origin, CGPoint destination )
{
CGPoint vertices[2];
vertices[0] = origin;
vertices[1] = destination;
// 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_LINES, 0, 2);
// restore default state
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
}

glBindTexture Problem with OpenGL ES on iPhone

I'm new to OpenGL, and am having a curious problem with my textures - looking for a nudge in the right direction.
I have an app which uses a Render to texture technique for accomplishing a certain effect - it's working marvelously. I draw to an offscreen buffer every time I need to, and am able to use this as a texture in my render loop.
This texture is only updated when necessary - it's drawn to the screen as is most frames.
I have some toolbars which are also drawn using OpenGL, on top of this surface using a texture atlas, and using blending.
I have recently begun trying to incorporate a particle system into the app, but whenever I try to render my particle system graphics, I "lose" my texture that I've rendered in the first step - ie it's contents disappear.
I have traced this to the call to glBindTexture that binds the texture of the particles.
EDIT: I can reproduce this in my simple toolbar drawing routine, code below. This is a crude routine that animates toolbar graphics on and off screen.
When I uncomment the first two lines in drawToolBar(), my rendered in memory texture disappears, ie the drawarrays call in my render loop renders nothing to the screen. Through testing, I have determined that the glBidTexture call is what triggers this. (For example, I can render colored quads over my texture, just not textured ones)
However, everything is fine if I allow drawToolbar() to run as below - the only difference is that the eventual call to drawTools() is wrapped in glPush/Pop, and is translated.
Note that the toolbar rendering always works - there is some unintended side effect, consequence, or bug issue going on here, which causes my background texture to disappear.
Any ideas are welcome - this is driving me nuts.
The code:
void drawTools()
{
//*Texture Coordinate Stuff Snipped*//
glBindTexture(GL_TEXTURE_2D, _buttontexture);
glEnable(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer (2, GL_FLOAT, 0,bottomToolQuads);
glTexCoordPointer(2, GL_FLOAT, 0,texc);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);
glDisable(GL_TEXTURE_2D);
}
void drawToolBar()
{
//drawTools();
//return;
if(_toolbarState ==0)
{
drawTools();
}
else if(_toolbarState == 2)//hiding
{
_toolbarVisiblePct -= TOOLINC;
if(_toolbarVisiblePct <= 0.0)
{
_toolbarState = 1;
_toolbarVisiblePct = 0.0;
}
else
{
glPushMatrix();
glTranslatef(0.0, -(1-_toolbarVisiblePct) * 50, 0);
drawTools();
glPopMatrix();
}
}
else if(_toolbarState == 3) //showing
{
_toolbarVisiblePct += TOOLINC;
if(_toolbarVisiblePct >= 1.0)
{
_toolbarState = 0;
_toolbarVisiblePct = 1.0;
drawTools();
}
else
{
glPushMatrix();
glTranslatef(0.0, -(1-_toolbarVisiblePct) * 50, 0);
drawTools();
glPopMatrix();
}
}
}
Looks like you're disabling texture rendering at the end of the drawTools method. OpenGL is a state machine, if you disable a state it will stay disabled until you enable it again.

Animating a texture across a surface in OpenGL

I'm working with the iPhone OpenGLES implementation and I wish to endlessly scroll a texture across a simple surface (two triangles making up a rectangle). This should be straightforward, but it's not something I've done before and I must be missing something. I can rotate the texture fine, but translate does not work at all. Do I have a minor implementation issue or am I doing something fundamentally wrong?
// move texture
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
// increment offset - no reset for demo purposes
wallOffset += 1.0;
// move the texture - this does not work
glTranslatef(wallOffset,wallOffset,0.0);
// rotate the texture - this does work
//glRotatef(wallOffset, 1.0, 0.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glBindTexture(GL_TEXTURE_2D, WallTexture.name);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
// simple drawing code
glNormalPointer(GL_FLOAT, 0, normals);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// push matrix back
glMatrixMode(GL_TEXTURE);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
You're incrementing your texture offset by 1.0f; but textures coordinates are considered in the range [0, 1], so you're not actually changing the texture coordinates (assuming you've enabled some sort of wrapping).
Try changing that increment (try .01f, or maybe something depending on the framerate) and see if it works. If not, then it may have something to do with the texture parameters you've got enabled.