OpenGl рисует поверх тайловой карты С++

Я новичок в OpenGL. У меня есть следующий код, который я использую из учебника, которому я следовал, он отображает карту плитки. Он делает это успешно, но теперь моя проблема в том, что я хочу добавить подвижный объект в окно, но он не появляется.

#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;
}

Если бы я прокомментировал в основном...

glutIdleFunc (draw);
glutReshapeFunc (reshape);

Карта плитки исчезнет, ​​и мой подвижный квадрат будет виден и работает... Я просто не могу успешно реализовать их вместе. Опять же, я совершенно новичок в этом, поэтому извините, если я делаю что-то действительно глупое. Есть идеи, где я ошибаюсь?


person P.Smith    schedule 26.01.2016    source источник
comment
Он по-прежнему рисует мой квадрат, по которому я могу перемещаться с помощью клавиш   -  person P.Smith    schedule 26.01.2016
comment
Итак, чтобы было понятно, мой мяч не отображается с плитками, видны только плитки.   -  person P.Smith    schedule 26.01.2016
comment
Я предполагаю, что это потому, что вы рисуете мяч где-то за пределами видимой области. Когда вы закомментируете glutReshapeFunc(reshape);, то reshape никогда не вызывается, и поэтому он никогда не устанавливает матрицу проекции на перспективную, поэтому она остается той, что установлена ​​enable2D.   -  person user253751    schedule 26.01.2016


Ответы (1)


Вы уверены, что хотите нарисовать тайловую карту с перспективной проекцией? Мне кажется, что вы должны использовать орфографическую проекцию как для тайловой карты, так и для шара.

Измените свою функцию reshape, чтобы она просто вызывала enable2D(w, h). Затем измените свою функцию drawTiles, чтобы вместо этого рисовать с использованием экранных координат. Это должно сработать.

Некоторые дополнительные примечания:

  • Не забудьте отключить текстурирование при рисовании мяча (похоже, вы не устанавливаете для него какую-либо текстуру, поэтому он просто будет отображаться с последней установленной текстурой).
  • Вы также можете отключить тестирование глубины с помощью glDisable(GL_DEPTH_TEST), так как оно вам на самом деле не нужно (и использовать glVertex2f для рисования тайловой карты вместо glVertex3f)
person Sam    schedule 26.01.2016