OpenGl, Cocoa, 2D image

Hey, I’m new to Xcode and OpenGl, but I have been doing a lot of research and have realized that OpenGl is perfect or possibly overkill for the rpg I am trying to create.

Though, I ran into a problem that is so painstakingly simple that it isn’t in any of the Opengl manuals I could find.

I need to know how to stick a 2D image onto the OpenGl canvas from the image resources.

Any ideas?

Thanks,
-Gandolf

In fact it is very easy, but there is no real distinction between 3d and 2d stuff, that is why it may be hard to search for this :slight_smile:

In summary :
Use glOrtho with appropriate coordinates ranges (choose ranges which are easy for you to work with, typically same as window pixel coordinates). Draw a textured quad with appropriate dimensions.
If your image is power of two (like 128*256) or if your hardware supports the extension GL_ARB_texture_non_power_of_two, the texture coordinates will simply be in the [0,0 1,1] range. Otherwise see this post here for more details : http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=241773#Post241773

This tutorial is quite detailed, it may help too :
http://gpwiki.org/index.php/OpenGL:Tutorials:Tutorial_Framework:Ortho_and_Alpha

Don’t hesitate to ask for details if some parts are unclear or seem too complex.

I’ve noticed that it didn’t say the name of the sprite image in the wiki tut.

Does it name each image by a resource number? Like 128-Infinite?

-Gandolf

To clear up your confusion :

  • texture “names” are in fact unique identifiers, typically each is a 32bits unsigned integer (range is 0 to 4.2billions). So it is more like an id than a name.
  • in the above tutorial, a pool of 128 different textures identifiers is generated :

GLuint Texture[128];
glGenTextures(128,Texture);
// now, Texture[i] contains the id for texture number i
// ...
// use it :
glBindTexture(GL_TEXTURE_2D,Texture[Spr[index].Tex]);

  • have a read at the official manual page : http://www.opengl.org/sdk/docs/man/xhtml/glGenTextures.xml
  • the glGenTexture stuff is optional in practice. I could safely skip it, and simply use glBindTexture(GL_TEXTURE_2D,1); for my first texture, glBindTexture(GL_TEXTURE_2D,2) for the second, etc.

As a tip, go to http//nehe.gamedev.net and you will find tutorials on a lot of things openGL related.

Thanks, I hope I will catch onto this. It’s like trying to grasp a frictionless object. I will eventually understand it.

-Gandolf

I’m doing way better now. I found this great tut that just stooped down to my low knowledge of OpenGl.

So far I have created a triangle, set it in the middle of the screen, and added some movement buttons. And I am trying to make the up button work. After it works, I will add texture.

So here is my problem, I’m trying to get the triangle to redraw further along the y axis when I press the up arrow. Here is the code:

#import "MyOpenGLView.h"
#include <OpenGL/gl.h>
 
@implementation MyOpenGLView
static void drawAnObject ()
{
    glColor3f(1.0f, 0.85f, 0.35f);
    glBegin(GL_TRIANGLES);
    {
        glVertex3f(  (movex+0.0),  (movey+0.6), 0.0);
        glVertex3f( (movex+0.2), (movey-0.3), 0.0);
        glVertex3f(  (movex-0.2), (movey-0.3) ,0.0);
    }
    glEnd();
}
-(void) drawRect: (NSRect) bounds
{
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    drawAnObject();
    glFlush();
}
- (IBAction)up:(id)sender
{
movey=movey+.2;
[button setStringValue:@"Pressed Up!"];
  [movextext setFloatValue: movex];
  [moveytext setFloatValue: movey];
// drawRect: (NSRect) bounds ;
drawAnObject ();
}
@end

It makes movey+.2, shows up in the text field, but doesn’t move the triangle. I’m trying to call “drawAnObject ();” to redraw it upwards, but it doesn’t work.

Could anyone help?

Thanks,
-Gandolf

you need to call glFlush too after the drawAnObject call of you want to refresh the screen.

Or call drawRect that do all the necessary job.

Thanks :). I will try that now.

-Gandolf

It works!:smiley:

Thanks.

Though, now I’m going to try to put a texture on my object and make it move by pressing a arrow key.
Anyone have any tips or guides?

-Gandolf

Look at this crufty old sample. Ignore all the ancient AGL and image loading code. Look at the GL part that draws the sprites.

Thanks.

I believe I got the drawing part down. I just need to add arrow key movement.

Anyone know how to detect if an arrow key is pressed?

-Gandolf

You’re using Cocoa, so go read about NSResponder and -sendEvent, -keyDown, -keyUp, -flagsChanged.

I’ve been reading and ran into some trouble. Xcode’s manual seems confusing and has no examples, but here is what I have so far.

I have to put this somewhere, do I put it in a NSWindow subclass?

keyEventWithType:location:modifierFlags:timestamp:windowNumber:context:characters:charactersIgnoringModifiers:isARepeat:keyCode:

Then I have to identify the key pressed with this?

- (unsigned short)keyCode

Could anyone help clear up my confusion?

-Gandolf

P.S.I found an example where you put this code into a NSApplication subclass and when you hit the esc key, it would quit the app. If I stick it in, do you think it would work for me?

- (void) sendEvent:(NSEvent*)event
{
    if(([event type] == NSKeyDown) && ([event keyCode] == 0x35))
            [NSApp terminate:nil];
 
    if(_renderer && (NSEventMaskFromType ([event type]) &
                 kRendererEventMask))
            [self renderWithEvent:event];
    else
    [       super sendEvent:event];
}

This is how I’m doing it in my NSOpenGLView derived class:


- (BOOL)acceptsFirstResponder // required if you want to get keydown event in NSViews.
{
    return YES;
}

- (void)keyDown:(NSEvent*)theEvent
{
    NSString *chars = [theEvent characters];
    unichar   uchar = [chars characterAtIndex:0];

    switch(uchar)
    {
    case 'A':
        NSLog(@"A pressed!");
        break;
    case 'a':
        NSLog(@"a pressed!");
        break;
    case NSUpArrowFunctionKey: // see NSEvent.h for other keys.
        NSLog(@"Up pressed!");
        break;
    }
}

<s>Thanks, though, where do you put this code and do you have to modify anything else?</s>

Hah, It works! Thank you!

-Gandolf

Now that the keys work, I am moving on to adding a while loop that will update the NSOpenGLView 40 fps per second.

When I do a regular “while (quit=1) {” loop, it freezes my application. Is there a way to slow it down so that the loop won’t go 200+ times per second? Just to 40 times per second?

-Gandolf

Usually, you use an NSTimer for this.

This is no longer about OpenGL. You need to read the AppKit documentation, and look at the examples that come with XCode. Like /Developer/Examples/AppKit/BlastApp, which shows timers and keyboard controls.

http://idevgames.com is a good general resource for these questions.

Thanks :slight_smile:

-Gandolf

You can also look at this

http://developer.apple.com/samplecode/glut/index.html

to see how apple did it.