Just a simple rectangle

Member
Posts: 24
Joined: 2008.05
Post: #1
Hello everyone, Im just starting to program and have absolutely no programming experience so I'm taking it really slow to get started. So I was just wondering if someone would help me make a very simple thing.

I just want to make a rectangle appear on the screen and that each time I press the arrow keys it moves in that direction. How can I go about this. I was just reading a Open Gl guide to making a triangle in objective c but I didnt understand much of it.
Quote this message in a reply
Member
Posts: 254
Joined: 2005.10
Post: #2
Personally, I would stay away from open gl until you are pretty good at a language (c for example).
Quote this message in a reply
Member
Posts: 24
Joined: 2008.05
Post: #3
So what would you suggest I do in the meantime, while I get better at C?
Quote this message in a reply
⌘-R in Chief
Posts: 1,254
Joined: 2002.05
Member
Posts: 24
Joined: 2008.05
Post: #5
Thank you. I actually started a tutorial I found and made a small rectangle. So thanks again.
Quote this message in a reply
Member
Posts: 281
Joined: 2009.04
Post: #6
I Just did exactly that. What I did was this:


  1. Learn the fundamentals of C at http://www.physics.drexel.edu/courses/Co.../C_basics/
  2. Using OneSadCookie's GLUT/Xcode Tutorial make a rectangle
  3. Use this thread, add keyboard input to your loop.


Here's my source code for main.c:
(The project's OneSadCookie's GLUT tutorial)

Code:
#include <stdlib.h>

#include <GLUT/glut.h>

int dir;
int shipPosX;
int shipPosY;


void keyboard(int key, int x, int y)
{
    //printf("key %d\n", key);
    switch (key)
    {
        case 100:
            //lefty
            shipPosX=shipPosX-20;
            dir=-90;
            break;
        case 101:
            //uppy
            shipPosY=shipPosY+20;
            dir=0;
            break;
        case 102:
            //righty
            shipPosX=shipPosX+20;
            dir=90;
            break;
        case 103:
            //downy
            shipPosY=shipPosY-20;
            dir=180;
            break;
    }
}



void display(void)
{
    
    
    
    
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    // This code  is where you put all drawing code. v
    
    // draw the ship @ the position
    

    
    
    glBegin(GL_LINE_LOOP);
    glVertex3f(shipPosX-40,shipPosY-40, 0.0f);
    glVertex3f(shipPosX+40,shipPosY-40, 0.0f);
    glVertex3f(shipPosX+40, shipPosY+40, 0.0f);
    glVertex3f(shipPosX-40,shipPosY+40,0.0f);
    
    
    
    glEnd();
    glBegin(GL_LINE_LOOP);
    glVertex3f(shipPosX-30,shipPosY-30, 0.0f);
    glVertex3f(shipPosX+30,shipPosY-30, 0.0f);
    glVertex3f(shipPosX+30, shipPosY+30, 0.0f);
    glVertex3f(shipPosX-30,shipPosY+30,0.0f);
    
    
    
    glEnd();

    // That's the ship drawn

    
    
    // drawframe
    glutSwapBuffers();
}

void reshape(int width, int height)
{
    glViewport(0, 0, width, height);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, width, 0, height);
    glMatrixMode(GL_MODELVIEW);
}


void idle(void)
{
    glutPostRedisplay();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(1680,1050);
    
    glutCreateWindow("GLUT Program");
    
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    glutSpecialFunc(keyboard); // <-- add this for keyboard

    
    
    
    glutFullScreen();
    glutMainLoop();
    return EXIT_SUCCESS;
}

// Keyboard Routines\\

~ Bring a Pen ~
Quote this message in a reply
Member
Posts: 260
Joined: 2005.05
Post: #7
You only need a minimal of the language to start with OpenGL. Once you start loading textures or processing meshes in your own code, you need more.

A few comments:
- It is more valuable for future serious applications to learn to draw the polygons from a vertex array. And slightly less code.
- You want to process both keydowns and keyups, so you don't move at keydown but every frame between keydown and keyup.
Quote this message in a reply
Moderator
Posts: 3,572
Joined: 2003.06
Post: #8
Ingemar Wrote:- You want to process both keydowns and keyups, so you don't move at keydown but every frame between keydown and keyup.

Yes. Here is an improved version which demonstrates smooth movement and how to cache keyboard events so you can more easily utilize them anywhere in your code, not just in the GLUT callbacks.

Use arrow keys for the smooth movement and wasd to demonstrate the discrete keyDowns.

Code:
#include <stdlib.h>

#include <GLUT/glut.h>

enum
{
    false,
    true
};

typedef unsigned char   Bool;

typedef enum
{
    ENTER    = 3,
    TAB        = 9,
    RETURN    = 13,
    ESC        = 27,
    SPACE    = 32,
    DEL        = 127,
    UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW,
    NUM_KEY_CODES
} KeyCode;

Bool    key[NUM_KEY_CODES], keyDown[NUM_KEY_CODES], keyUp[NUM_KEY_CODES];
int        lastFrameTime = 0;
float    dt; // delta time (how much time in between frames, used for all movement calculations)
float    shipPosX;
float    shipPosY;

void resetKeyboardInput(void)
{
    int        i;
    
    for (i = 0; i < NUM_KEY_CODES; i++)
    {
        keyDown[i] = false;
        keyUp[i] = false;
    }
}

void keyboard(unsigned char rawKeyCode, int x, int y)
{
    if (rawKeyCode < NUM_KEY_CODES)
    {
        key[rawKeyCode] = true;
        keyDown[rawKeyCode] = true;
    }
}

void keyboardUp(unsigned char rawKeyCode, int x, int y)
{
    if (rawKeyCode < NUM_KEY_CODES)
    {
        key[rawKeyCode] = false;
        keyUp[rawKeyCode] = false;
    }
}

void keyboardSpecial(int rawKeyCode, int x, int y)
{
    switch (rawKeyCode)
    {
        case GLUT_KEY_LEFT:
            key[LEFT_ARROW] = true;
            keyDown[LEFT_ARROW] = true;
            break;
        case GLUT_KEY_UP:
            key[UP_ARROW] = true;
            keyDown[UP_ARROW] = true;
            break;
        case GLUT_KEY_RIGHT:
            key[RIGHT_ARROW] = true;
            keyDown[RIGHT_ARROW] = true;
            break;
        case GLUT_KEY_DOWN:
            key[DOWN_ARROW] = true;
            keyDown[DOWN_ARROW] = true;
            break;
    }
}

void keyboardSpecialUp(int rawKeyCode, int x, int y)
{
    switch (rawKeyCode)
    {
        case GLUT_KEY_LEFT:
            key[LEFT_ARROW] = false;
            keyUp[LEFT_ARROW] = true;
            break;
        case GLUT_KEY_UP:
            key[UP_ARROW] = false;
            keyUp[UP_ARROW] = true;
            break;
        case GLUT_KEY_RIGHT:
            key[RIGHT_ARROW] = false;
            keyUp[RIGHT_ARROW] = true;
            break;
        case GLUT_KEY_DOWN:
            key[DOWN_ARROW] = false;
            keyUp[DOWN_ARROW] = true;
            break;
    }
}


void display(void)
{
    if (lastFrameTime == 0)
    {
        lastFrameTime = glutGet(GLUT_ELAPSED_TIME);
    }
    int now = glutGet(GLUT_ELAPSED_TIME);
    int elapsedMilliseconds = now - lastFrameTime;
    float dt = elapsedMilliseconds / 1000.0f;
    lastFrameTime = now;

    // "key" is cached locally so that it stays down until the next key up event
    if (key[LEFT_ARROW])
        shipPosX -= 200.0f * dt;
    if (key[RIGHT_ARROW])
        shipPosX += 200.0f * dt;
    if (key[UP_ARROW])
        shipPosY += 200.0f * dt;
    if (key[DOWN_ARROW])
        shipPosY -= 200.0f * dt;
    
    // also do wasd to demonstrate discrete "keyDown" events
    if (keyDown['a'])
        shipPosX -= 20.0f;
    if (keyDown['d'])
        shipPosX += 20.0f;
    if (keyDown['w'])
        shipPosY += 20.0f;
    if (keyDown['s'])
        shipPosY -= 20.0f;
    
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    // This code  is where you put all drawing code. v
    
    // draw the ship @ the position
    

    
    
    glBegin(GL_LINE_LOOP);
    glVertex3f(shipPosX-40,shipPosY-40, 0.0f);
    glVertex3f(shipPosX+40,shipPosY-40, 0.0f);
    glVertex3f(shipPosX+40, shipPosY+40, 0.0f);
    glVertex3f(shipPosX-40,shipPosY+40,0.0f);
    
    
    
    glEnd();
    glBegin(GL_LINE_LOOP);
    glVertex3f(shipPosX-30,shipPosY-30, 0.0f);
    glVertex3f(shipPosX+30,shipPosY-30, 0.0f);
    glVertex3f(shipPosX+30, shipPosY+30, 0.0f);
    glVertex3f(shipPosX-30,shipPosY+30,0.0f);
    
    
    
    glEnd();

    // That's the ship drawn

    
    
    // drawframe
    glutSwapBuffers();
    
    // do this to clear the key ups and key downs for each frame
    resetKeyboardInput();
}

void reshape(int width, int height)
{
    glViewport(0, 0, width, height);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, width, 0, height);
    glMatrixMode(GL_MODELVIEW);
}


void idle(void)
{
    glutPostRedisplay();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    //glutInitWindowSize(1680,1050);
    glutInitWindowSize(640, 480);
    
    glutCreateWindow("GLUT Program");
    
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    
    glutKeyboardFunc(keyboard);
    glutKeyboardUpFunc(keyboardUp);
    glutSpecialFunc(keyboardSpecial);
    glutSpecialUpFunc(keyboardSpecialUp);

    
    
    
    //glutFullScreen();
    glutMainLoop();
    return EXIT_SUCCESS;
}
Quote this message in a reply
Member
Posts: 281
Joined: 2009.04
Post: #9
Thanks, I know understand It. I see you've implemented the arrow keys, but not Space. When your switch section chooses keys (GLUT_KEY_LEFT) I tried adding (Since there's no GLUT, or is there, space key name) case 32:, but that fails too. How can I implement a space bar? Huh

~ Bring a Pen ~
Quote this message in a reply
Moderator
Posts: 3,572
Joined: 2003.06
Post: #10
If you look carefully you'll notice that I did implement space already. The constants are near the top:

Code:
typedef enum
{
    ENTER    = 3,
    TAB        = 9,
    RETURN    = 13,
    ESC        = 27,
    SPACE    = 32,
    DEL        = 127,
    UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW,
    NUM_KEY_CODES
} KeyCode;

What's not obvious is that the constants for regular characters and numbers don't need to be listed since they can be accessed using simple character constants like 'a', 'b', '1', 'H', etc.

You can find out if space is pressed by doing something like:

Code:
if (key[SPACE])
    shipPosX -= 5.0f * dt;

There are four GLUT keyboard functions here: keyboard(), keyboardUp(), keyboardSpecial(), and keyboardSpecialUp(); Don't put any code in those functions. What they do is cache the values sent from GLUT so you can use them elsewhere in your program, like in display(). They're "cached" by setting a Boolean flag in the three arrays: key[], keyDown[], keyUp[]

So here's how you would detect a key being held down:
Code:
if (key[LEFT_ARROW])
    shipPosX -= 200.0f * dt;

Here's how you would detect a key being pressed for just one frame. In this example we're checking to see if the "a" key was pressed:
Code:
if (keyDown['a'])
    shipPosX -= 20.0f;

You can also see if a key was let up:
Code:
if (keyUp['a'])
    shipPosX -= 20.0f;
Quote this message in a reply
Member
Posts: 281
Joined: 2009.04
Post: #11
Ahh. Thanks loads. What I did try was right, it's the firing sequence that's broke:

It's still not working. I've tried moving the contents of fire() to inside the if block, but still no results. I've also tried putting a rudimentary drawing operation in fire(), but even that won't work.MadMadMadSneakyCryMadSad

Code:
#include <stdlib.h>


#include <GLUT/glut.h>

enum
{
    false,
    true
};

typedef unsigned char   Bool;

typedef enum
    {
        ENTER    = 3,
        TAB        = 9,
        RETURN    = 13,
        ESC        = 27,
        SPACE    = 32,
        DEL        = 127,
        UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW,
        NUM_KEY_CODES
    } KeyCode;

Bool    key[NUM_KEY_CODES], keyDown[NUM_KEY_CODES], keyUp[NUM_KEY_CODES];
int        lastFrameTime = 0;
float    dt; // delta time (how much time in between frames, used for all movement calculations)
float    shipPosX;
float    shipPosY;
int dir;



void fire()

{
    
    
    if (dir==0)
    {
        glBegin(GL_LINE_STRIP);
        glVertex3f(shipPosX,shipPosY,0.0f);
        glVertex3f(shipPosX,shipPosY+500,0.0f);
        glEnd();
    }
    else if (dir==90)
    {
        glBegin(GL_LINE_STRIP);
        glVertex3f(shipPosX,shipPosY,0.0f);
        glVertex3f(shipPosX+500,shipPosY,0.0f);
        glEnd();
    }
    else if (dir==180)
    {
        glBegin(GL_LINE_STRIP);
        glVertex3f(shipPosX,shipPosY,0.0f);
        glVertex3f(shipPosX,shipPosY-500,0.0f);
        glEnd();
    }
    else if (dir==-90)
    {
        glBegin(GL_LINE_STRIP);
        glVertex3f(shipPosX,shipPosY,0.0f);
        glVertex3f(shipPosX-500,shipPosY,0.0f);
        glEnd();
    }
    
    
}


void resetKeyboardInput(void)
{
    int        i;
    
    for (i = 0; i < NUM_KEY_CODES; i++)
    {
        keyDown[i] = false;
        keyUp[i] = false;
    }
}

void keyboard(unsigned char rawKeyCode, int x, int y)
{
    if (rawKeyCode < NUM_KEY_CODES)
    {
        key[rawKeyCode] = true;
        keyDown[rawKeyCode] = true;
    }
}

void keyboardUp(unsigned char rawKeyCode, int x, int y)
{
    if (rawKeyCode < NUM_KEY_CODES)
    {
        key[rawKeyCode] = false;
        keyUp[rawKeyCode] = false;
    }
}

void keyboardSpecial(int rawKeyCode, int x, int y)
{
    switch (rawKeyCode)
    {
        case GLUT_KEY_LEFT:
            key[LEFT_ARROW] = true;
            keyDown[LEFT_ARROW] = true;
            break;
        case GLUT_KEY_UP:
            key[UP_ARROW] = true;
            keyDown[UP_ARROW] = true;
            break;
        case GLUT_KEY_RIGHT:
            key[RIGHT_ARROW] = true;
            keyDown[RIGHT_ARROW] = true;
            break;
        case GLUT_KEY_DOWN:
            key[DOWN_ARROW] = true;
            keyDown[DOWN_ARROW] = true;
            break;
    
            
    }
}

void keyboardSpecialUp(int rawKeyCode, int x, int y)
{
    switch (rawKeyCode)
    {
        case GLUT_KEY_LEFT:
            key[LEFT_ARROW] = false;
            keyUp[LEFT_ARROW] = true;
            break;
        case GLUT_KEY_UP:
            key[UP_ARROW] = false;
            keyUp[UP_ARROW] = true;
            break;
        case GLUT_KEY_RIGHT:
            key[RIGHT_ARROW] = false;
            keyUp[RIGHT_ARROW] = true;
            break;
        case GLUT_KEY_DOWN:
            key[DOWN_ARROW] = false;
            keyUp[DOWN_ARROW] = true;
            break;

    }
}


void display(void)
{
    if (lastFrameTime == 0)
    {
        lastFrameTime = glutGet(GLUT_ELAPSED_TIME);
    }
    int now = glutGet(GLUT_ELAPSED_TIME);
    int elapsedMilliseconds = now - lastFrameTime;
    float dt = elapsedMilliseconds / 1000.0f;
    lastFrameTime = now;
    
    // "key" is cached locally so that it stays down until the next key up event
    if (key[LEFT_ARROW])
    {
        shipPosX -= 200.0f * dt;
        dir = -90;
    

    }
    if (key[RIGHT_ARROW])
    {
        shipPosX += 200.0f * dt;
        dir = 90;
    }
    if (key[UP_ARROW])
    {
        shipPosY += 200.0f * dt;
        dir = 0;
    }
    if (key[DOWN_ARROW])
    {
        shipPosY -= 200.0f * dt;
        dir =180;
    }
    if (key[SPACE])
    {
        fire();
        
    }
    
    // also do wasd to demonstrate discrete "keyDown" events

    
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    // This code  is where you put all drawing code. v
    
    // draw the ship @ the position
    
    
    
    
    glBegin(GL_LINE_LOOP);
    glVertex3f(shipPosX-40,shipPosY-40, 0.0f);
    glVertex3f(shipPosX+40,shipPosY-40, 0.0f);
    glVertex3f(shipPosX+40, shipPosY+40, 0.0f);
    glVertex3f(shipPosX-40,shipPosY+40,0.0f);
    
    
    
    glEnd();
    glBegin(GL_LINE_LOOP);
    glVertex3f(shipPosX-30,shipPosY-30, 0.0f);
    glVertex3f(shipPosX+30,shipPosY-30, 0.0f);
    glVertex3f(shipPosX+30, shipPosY+30, 0.0f);
    glVertex3f(shipPosX-30,shipPosY+30,0.0f);
    
    
    
    glEnd();
    
    if (dir==0)
    {
        glBegin(GL_LINES);
        glVertex3f(shipPosX,shipPosY,0.0f);
        glVertex3f(shipPosX,shipPosY+40,0.0f);
        glEnd();
    }
    else if (dir==90)
    {
        glBegin(GL_LINES);
        glVertex3f(shipPosX,shipPosY,0.0f);
        glVertex3f(shipPosX+40,shipPosY,0.0f);
        glEnd();
    }
    else if (dir==180)
    {
        glBegin(GL_LINES);
        glVertex3f(shipPosX,shipPosY,0.0f);
        glVertex3f(shipPosX,shipPosY-40,0.0f);
        glEnd();
    }
    else if (dir==-90)
    {
        glBegin(GL_LINES);
        glVertex3f(shipPosX,shipPosY,0.0f);
        glVertex3f(shipPosX-40,shipPosY,0.0f);
        glEnd();
    }
    
    
    
    
    // That's the ship drawn
    
    
    
    // drawframe
    glutSwapBuffers();
    
    // do this to clear the key ups and key downs for each frame
    resetKeyboardInput();
}

void reshape(int width, int height)
{
    glViewport(0, 0, width, height);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, width, 0, height);
    glMatrixMode(GL_MODELVIEW);
}


void idle(void)
{
    glutPostRedisplay();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    //glutInitWindowSize(1680,1050);
    glutInitWindowSize(640, 480);
    
    glutCreateWindow("GLUT Program");
    
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    glutFullScreen();
    
    glutKeyboardFunc(keyboard);
    glutKeyboardUpFunc(keyboardUp);
    glutSpecialFunc(keyboardSpecial);
    glutSpecialUpFunc(keyboardSpecialUp);
    
    
    
    
    //glutFullScreen();
    glutMainLoop();
    return EXIT_SUCCESS;
}

~ Bring a Pen ~
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Sphere/Rectangle collision detection sinclair44 5 7,829 Dec 12, 2007 02:44 PM
Last Post: scgames