0

I am new to OpenGL. I have the following code that I am using from a tutorial I followed, what it does is render a tile map. It does this successfully but my problem now is that I want to add a moveable object onto the window however it is not appearing.

#include "stdafx.h"

#include <string> 
#include <windows.h> 
#include <iostream> 
#include <conio.h> 
#include <sstream>  
#include <math.h>  
#include <gl\gl.h> 
#include <gl\glu.h> 
#include "GL/freeglut.h" 
#pragma comment(lib, "OpenGL32.lib")


// window size and update rate (60 fps) 
int width = 700; 
int height = 700; 
int interval = 1000 / 60; 


// ball 
float ball_pos_x = width / 2; 
float ball_pos_y = height / 2; 
float ball_dir_x = -1.0f; 
float ball_dir_y = 0.0f; 
int ball_width = 20;
int ball_height = 20;
int ball_speed = 5;

GLuint texture; //the array for our texture
GLuint texture2; //the array for our second texture

void keyboard() {    

    if (GetAsyncKeyState(VK_LEFT)) ball_pos_x -= ball_speed;    
    if (GetAsyncKeyState(VK_RIGHT)) ball_pos_x += ball_speed;
    if (GetAsyncKeyState(VK_UP)) ball_pos_y += ball_speed;    
    if (GetAsyncKeyState(VK_DOWN)) ball_pos_y -= ball_speed;
}


int cMap[30][30] = { //our map
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
    {1, 0, 1, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 1, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 1, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 1, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
};

void drawRect(float x, float y, float width, float height) {    
    glBegin(GL_QUADS);        
    glVertex2f(x, y);        
    glVertex2f(x + width, y);        
    glVertex2f(x + width, y + height);        
    glVertex2f(x, y + height);    
    glEnd(); 
}


GLuint LoadTexture( const char * filename, int width, int height )
{
    GLuint texture;
    unsigned char * data;
    FILE * file;

    //The following code will read in our RAW file
    file = fopen( filename, "rb" );
    if ( file == NULL ) return 0;
    data = (unsigned char *)malloc( width * height * 3 );
    fread( data, width * height * 3, 1, file );
    fclose( file );

    glGenTextures( 1, &texture );
    glBindTexture( GL_TEXTURE_2D, texture );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, 
GL_MODULATE ); //set texture environment parameters

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR );

    //Here we are setting the parameter to repeat the texture 
//instead of clamping the texture
    //to the edge of our shape. 
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 
GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 
GL_REPEAT );

    //Generate the texture
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, 
GL_RGB, GL_UNSIGNED_BYTE, data);
    free( data ); //free the texture
    return texture; //return whether it was successfull
}

void FreeTexture( GLuint texture )
{
  glDeleteTextures( 1, &texture ); 
}

void drawTiles (void) { //our function to draw the tiles
    for (int i = 0; i < 10; i++) //loop through the height of the map
    {
        for (int j = 0; j < 10; j++) //loop through the width of the map
        {
            if (cMap[i][j] == 0) //if the map at this position contains a 0
            {
                glBindTexture( GL_TEXTURE_2D, texture ); //bind our grass texture to our shape
            }
            else //otherwise
            {
                glBindTexture( GL_TEXTURE_2D, texture2 ); //bind our dirt texture to our shape
            }

            glPushMatrix(); //push the matrix so that our translations only affect this tile
                glTranslatef(j, -i, 0); //translate the tile to where it should belong

                glBegin (GL_QUADS); //begin drawing our quads
                    glTexCoord2d(0.0, 0.0);
                    glVertex3f(0.0, 0.0, 0.0); //with our vertices we have to assign a texcoord

                    glTexCoord2d(1.0, 0.0);
                    glVertex3f(1.0, 0.0, 0.0); //so that our texture has some points to draw to

                    glTexCoord2d(1.0, 1.0);
                    glVertex3f(1.0, 1.0, 0.0);

                    glTexCoord2d(0.0, 1.0);
                    glVertex3f(0.0, 1.0, 0.0);
                glEnd();
            glPopMatrix(); //pop the matrix
        } //end first loop
    } //end second loop
}

void draw() {    
    // clear (has to be done at the beginning)    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
    glLoadIdentity();     // ToDo: draw our scene 

    // draw ball
    drawRect(ball_pos_x - ball_width / 2, ball_pos_y - ball_height / 2, ball_width, ball_height);



    glEnable( GL_TEXTURE_2D );
    glTranslatef(-5, 4, -20); //translate back a bit to view the map correctly

    drawTiles(); //draw our tiles

    // swap buffers (has to be done at the end)    
    glutSwapBuffers(); 
}




void UpdatePlayer(){
    // hit by right racket?    
    if (ball_pos_x < ball_pos_x + ball_width &&         
        ball_pos_x > enemy_pos_x &&        
        ball_pos_y < enemy_pos_y + enemy_height &&        
        ball_pos_y > enemy_pos_y) {        


            ball_pos_x = ball_pos_x;        
            ball_pos_y = ball_pos_y;    
    }   


}

void update(int value) {   // Call update() again in 'interval' milliseconds   

    // input handling   
    keyboard();  

    UpdatePlayer();

    glutTimerFunc(interval, update, 0);    
    // Redisplay frame   
    glutPostRedisplay(); 
}


void enable2D(int width, int height) {    
    glViewport(0, 0, width, height);    
    glMatrixMode(GL_PROJECTION);    
    glLoadIdentity();    
    glOrtho(0.0f, width, 0.0f, height, 0.0f, 1.0f);    
    glMatrixMode (GL_MODELVIEW);    
    glLoadIdentity(); 
}

void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    glMatrixMode (GL_MODELVIEW);
}

int _tmain(int argc, char** argv)
{

    // initialize opengl (via glut)    
    glutInit(&argc, argv);    
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);    
    glutInitWindowSize(width, height);    glutCreateWindow("noobtuts.com Pong");     

    // Register callback functions       
    glutDisplayFunc(draw);
    glutIdleFunc (draw);
    glutReshapeFunc (reshape);
    glutTimerFunc(interval, update, 0);

    // setup scene to 2d mode and set draw color to white    
    enable2D(width, height);    
    glColor3f(1.0f, 1.0f, 1.0f); 


    //Load our texture
    texture = LoadTexture("texture.raw", 256, 256);
    texture2 = LoadTexture("texture2.raw", 256, 256);

    glutMainLoop ();

    //Free our texture
    FreeTexture(texture);
    FreeTexture(texture2);

    return 0;
}

If I was to comment out in the main...

glutIdleFunc (draw);
glutReshapeFunc (reshape);

The tile map will disappear and my moveable square is visible and works...I just can't implement the two together successfully. Again i'm completely new to this so apologise if I am doing something really stupid Any ideas where I am going wrong?

P.Smith
  • 71
  • 9
  • It still draws my square which I can navigate with key input – P.Smith Jan 26 '16 at 00:42
  • So just to make it clear, my ball isn't rendering with the tiles, only the tiles are visible – P.Smith Jan 26 '16 at 00:44
  • I would guess it's because you're drawing the ball way outside the visible area somewhere. When you comment out `glutReshapeFunc(reshape);`, then `reshape` is never called, and so it never sets the projection matrix to the perspective one, so it stays as the one set by `enable2D`. – user253751 Jan 26 '16 at 00:45

1 Answers1

0

Are you sure you want to draw the tile map with a perspective projection? It seems to me that you should be using an orthographic projection for both the tile map and the ball.

Change your reshape function to simply call enable2D(w, h). Then change your drawTiles function to draw using screen coordinates instead. That should work.

Some additional notes:

  • Don't forget to disable texturing when drawing your ball (you don't seem to be setting any texture for it, so it will just render with the last texture set).
  • You could also disable depth testing with glDisable(GL_DEPTH_TEST) since you don't really need it (and use glVertex2f for drawing the tile map instead of glVertex3f)
Sam
  • 3,320
  • 1
  • 17
  • 22