Simple OpenGL 2d test - nothing displaying

Apprentice
Posts: 7
Joined: 2009.01
Post: #1
Hi all,

I'm sure there is something simple I'm missing here, but I can't seem to spot it. I'm just trying a simple program to draw a triangle to the screen, but the display just shows black. When I put some simple debug in the drawView method, I can verify that 'drawView' is getting called, but I don't see anything drawn to the screen in the iPhone simulator.

Here's the code I'm using.

First, I'm basing the project off of the GLGravity example. In AppController, the 'setupView' method looks like this:

Code:
glEnable2D();    
//clear the view with black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    
rtri = 0.0f;

glEnable2D is just a 'c' function, as such
Code:
int vPort[4];
    
glGetIntegerv(GL_VIEWPORT, vPort);
    
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
    
glOrthof(0, vPort[2], 0, vPort[3], -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

And finally, here's the 'drawView' method
Code:
const GLfloat triVertices[] = {
    0.0f, 0.0f, 0.0f,
    2.0f, 0.0f, 0.0f,
    1.0f, 1.0f, 0.0f
};
const GLubyte triColors[] = {
    255, 0, 0, 255,
    0,255,0, 255,
    0, 0, 255, 255
};
    
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();    // Reset The Current Modelview Matrix
//glRotatef(rtri, 0.0f, 0.0f, 1.0f);
//glTranslatef(0.0f,2.0f, 0.0f);
    
glVertexPointer(3, GL_FLOAT, 0, triVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, triColors);
glEnableClientState(GL_COLOR_ARRAY);
    
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
    
//increment rotation angle
//rtri += 1.0f;
//    if(rtri > 360.0f)
//        rtri -= 360.0f;

Does anyone see anything obvious? My first thought is maybe with the glOrthof method, but I'm not sure....
Quote this message in a reply
Moderator
Posts: 3,577
Joined: 2003.06
Post: #2
On a glance, I don't see anything obvious except that your vertices are just a couple pixels away from each other and your projection matrix is presumably set to the size of your screen in glOrtho, which is many pixels. IOW, what you're drawing may be a tiny triangle on a big screen. Try making your vertices more spread out or use glScalef(100.0f, 100.0f, 1.0f), or something like that.

.. and I presume glEnable2D is a typo
Quote this message in a reply
Apprentice
Posts: 7
Joined: 2009.01
Post: #3
Hmm...interesting. First, what did you mean by 'glEnable2d' being a typo? Because all of the things in the 'code' blocks in my original post are copied directly from the code.

But one thing I did notice was that there was a gl error being generated I hadn't noticed before.

I tracked it down, and something isn't right with the glOrthof call, because I'm getting an openGL '501' error after that line.

I think the real problem is that the vPort array isn't being set correctly for some reason. After the call to glGetIntegerv(GL_VIEWPORT, vPort), vPort[2] and [3] are both zero. That doesn't seem right....

My glEnable2D() method is in a separate .c file, but that shouldn't matter....

Any ideas?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #4
Let's try an experiment, and follow my recent debugging tips in the OpenGL FAQ thread.

First, check for errors. API arguments looks good to me, so let's assume there aren't any.

Next, inspect the state. AnotherJake's conclusion is reasonable-- this is likely a problem with your vertex transformation. So, what's the state that could interact and cause the problem?

Here, you need to understand how transformations work, which is explained in great detail in the documentation, and examples given in the wiki. To summarize:
  • Each vertex position you submit is treated as a 4-component XYZW vector, defined in Object space, which is measured in whatever arbitrary units you want to use.
  • It is multiplied by the concatenated ModelView and Projection matrices to transform from Object space to Clip space.
  • After clipping, the resulting vertex positions are scaled and biased by the Viewport, to produce final window positions.
That's a very generalized transformation system, designed for 3D graphics. For a 2D game, here's how you'd typically use this system:
  • You set up an orthographic projection, covering the whole screen. For example from [0,0] to [320,480].
  • You set up the Viewport, covering the whole screen again.
  • You specify vertex positions, using screen pixels as the coordinate system. For example a square from [10,10] to [20,20].
  • The positions get squished down to [-1, 1] during transformation, for clipping purposes.
  • After clipping, they get multiplied by the Viewport scale to produce (in the special case of orthographic projection) the same values you fed in-- [10, 10] to [20, 20].
If you compare these steps with the code you posted, there are two problems. Your input vertex positions are very small, like AnotherJake said. And you never called glViewport, so if you check the state, it's probably zero (unless some other code snippet you didn't post has already set it.) Like the documentation says, the viewport is initially zero, but is set to the width/height of the first window the context is attached to. This is a window system convention, and on the iPhone, there are never any windows, only FBOs. So it's up to you to set the viewport.

You can always do all of the math involved here manually to doublecheck the results you'll get-- you provided all of the input data (matrices, viewport, and vertex positions), so you can multiply it yourself for debugging.
Quote this message in a reply
Moderator
Posts: 3,577
Joined: 2003.06
Post: #5
SaxMan Wrote:My glEnable2D() method is in a separate .c file, but that shouldn't matter....

The gl prefix is reserved for the OpenGL API namespace. It's not technically "wrong" that you used it, but it is not proper coding practice, and forces us to "presume" you made a typo somehow. Without the gl prefix we can instantly identify that it is your own custom function, or at least not an OpenGL call. So it is highly recommended that you avoid using the "gl" prefix for your own functions. The only time it is acceptable is if you're actually writing a replacement for one not included in the API you're using (which might be necessary from time to time with OpenGL ES, but still unusual).
Quote this message in a reply
Apprentice
Posts: 7
Joined: 2009.01
Post: #6
Good point. I'll make sure to change that function name.

Now, as I'm tracing this bug, I'm running into a very strange problem. Part of the idea with my design is to separate as much (if not all) of the OpenGL calls to separate .c files, in order to make my openGL code as adaptable as possible, with the hope that it wouldn't be too much effort to take just the OpenGL .c files and move them between platforms and re-compile.

That being said, something strange seems to be happening to argument passing as I attempt to do this. Take this simple C function, for example:

Code:
void testWidthAndHeight(float width, float height)
{
    printf("width: %f, height %f", width, height);
}

And the following call from AppController.m (note: 'view' is an OpenGLCoreView which is passed in to setupView, where this code is located)

Code:
CGRect rect = view.bounds;
float width = rect.size.width;
float height = rect.size.height;
testWidthAndHeight(width, height);

If I put the 'testWidthAndHeight' method in the AppController.m file, everything works fine, and I see 320 and 480 printed to the debug console. If, however, all I do is move that function to a separate .c file (graphicsFW.c) I get the following output:

width: 0.000000, height 3.812500

Any idea why this is happening?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #7
Did you create a corresponding graphicsFW.h, to declare the function protoype, and include that header everywhere you use the function?

If you fail to declare the prototype, the compiler will default the argument types to int. There should be a compiler warning about this, too.
Quote this message in a reply
Apprentice
Posts: 7
Joined: 2009.01
Post: #8
Bah. That's what happens when I'm on a new platform - I forget some of the basics Smile

I had created the .h file, but forgotten the 'import' statement. The compiler wasn't giving me errors, but for some reason I was ignoring the 'implicit declaration' warnings.

Also, you guys were right about the size of the triangle. I adjusted the vertices and now everything shows up on the screen!

Thanks for the help....I'm sure I'll be back for more Wink
Quote this message in a reply
Member
Posts: 46
Joined: 2008.10
Post: #9
Heh... I was going to suggest making sure you flush / swap your buffer, which seemed to slip between the cracks sometimes when I was starting out. Guess you're taking care of everything already... Good luck!

"Who's John Galt?"
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Another beginner's question about displaying an animated object superlemonster 2 4,864 Jan 28, 2011 08:03 AM
Last Post: OptimisticMonkey
  Simple OpenGL ES problem soulstorm 3 4,239 May 14, 2009 03:53 PM
Last Post: AnotherJake
  OpenGL ES - Drawing a simple cube help. MattCairns 7 12,605 Oct 10, 2008 05:26 PM
Last Post: Frogblast
  Very simple OpenGL problem evangs 10 5,703 Dec 10, 2007 01:32 PM
Last Post: wyrmmage
  Displaying image with OpenGL and DevIL in C? leRiCl 13 9,376 Jan 23, 2007 01:25 PM
Last Post: djork