2009-08-06 14 views
1

J'ai écrit du code pour expérimenter avec la programmation opengl sur Ubuntu, ça fait un peu de temps mais j'avais une bonne compréhension de C. Comme on me dit que C++ est le langage de choix pour la programmation de jeux que j'essaie de développer avec ça.Nouveau sur SDL OpenGL sous Linux, quoi de mal à ça?

Ceci est ma première vraie tentative à opengl avec sdl et je suis arrivé à ce jour, il compile et fonctionne mais ma fonction de caméra ne semble pas faire quoi que ce soit. Je sais qu'il y a probablement de bien meilleures façons de faire ce genre de choses, mais je voulais avoir les bases avant de passer à des choses plus avancées.

main.cpp

#include <iostream> 
#include <cmath> 
#include "SDL/SDL.h" 
#include "SDL/SDL_opengl.h" 

int screen_width = 640; 
int screen_height = 480; 
const int screen_bpp = 32; 
float rotqube = 0.9f; 

float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0; 
float lastx, lasty; 

SDL_Surface *screen = NULL; // create a default sdl_surface to render our opengl to 

void camera (void) { 
glRotatef(xrot,1.0,0.0,0.0); // x-axis (left and right) 
glRotatef(yrot,0.0,1.0,0.0); // y-axis (up and down) 
glTranslated(-xpos,-ypos,-zpos); // translate the screen to the position 
SDL_GL_SwapBuffers(); 
} 

int DrawCube(void) 
{ 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glLoadIdentity(); 

glTranslatef(0.0f, 0.0f,-7.0f); 
glRotatef(rotqube,0.0f,1.0f,0.0f); 
glRotatef(rotqube,1.0f,1.0f,1.0f); 
glBegin(GL_QUADS); 
    glColor3f(0.0f,1.0f,0.0f); 
    glVertex3f(1.0f, 1.0f,-1.0f); 
    glVertex3f(-1.0f, 1.0f,-1.0f); 
    glVertex3f(-1.0f, 1.0f, 1.0f); 
    glVertex3f(1.0f, 1.0f, 1.0f); 
    glColor3f(1.0f,0.5f,0.0f); 
    glVertex3f(1.0f,-1.0f, 1.0f); 
    glVertex3f(-1.0f,-1.0f, 1.0f); 
    glVertex3f(-1.0f,-1.0f,-1.0f); 
    glVertex3f(1.0f,-1.0f,-1.0f); 
    glColor3f(1.0f,0.0f,0.0f); 
    glVertex3f(1.0f, 1.0f, 1.0f); 
    glVertex3f(-1.0f, 1.0f, 1.0f); 
    glVertex3f(-1.0f,-1.0f, 1.0f); 
    glVertex3f(1.0f,-1.0f, 1.0f); 
    glColor3f(1.0f,1.0f,0.0f); 
    glVertex3f(1.0f,-1.0f,-1.0f); 
    glVertex3f(-1.0f,-1.0f,-1.0f); 
    glVertex3f(-1.0f, 1.0f,-1.0f); 
    glVertex3f(1.0f, 1.0f,-1.0f); 
    glColor3f(0.0f,0.0f,1.0f); 
    glVertex3f(-1.0f, 1.0f, 1.0f); 
    glVertex3f(-1.0f, 1.0f,-1.0f); 
    glVertex3f(-1.0f,-1.0f,-1.0f); 
    glVertex3f(-1.0f,-1.0f, 1.0f); 
    glColor3f(1.0f,0.0f,1.0f); 
    glVertex3f(1.0f, 1.0f,-1.0f); 
    glVertex3f(1.0f, 1.0f, 1.0f); 
    glVertex3f(1.0f,-1.0f, 1.0f); 
    glVertex3f(1.0f,-1.0f,-1.0f); 
glEnd(); 
SDL_GL_SwapBuffers(); 

rotqube +=0.9f; 
return true; 
} 

bool init_sdl(void) 
{ 
if(SDL_Init(SDL_INIT_EVERYTHING) != 0) 
{ 
    return false; 
} 

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); 
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); 
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); 
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); 
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 

// TODO: Add error check to this screen surface init 
screen = SDL_SetVideoMode(screen_width, screen_height, screen_bpp, SDL_OPENGL | SDL_HWSURFACE | SDL_RESIZABLE); 

return true; 
} 

static void init_opengl() 
{ 
float aspect = (float)screen_width/(float)screen_height; 
glViewport(0, 0, screen_width, screen_height); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
gluPerspective(60.0, aspect, 0.1, 100.0); 
glMatrixMode(GL_MODELVIEW); 
glClearColor(0.0, 0.0 ,0.0, 0); 
glEnable(GL_DEPTH_TEST); 
} 

void heartbeat() 
{ 
float xrotrad, yrotrad; 
int diffx, diffy; 

SDL_Event event; 

while(1) 
{ 
    while(SDL_PollEvent(&event)) 
    { 
     switch(event.type) 
     { 
      case SDL_KEYDOWN: 
       switch(event.key.keysym.sym) 
       { 
        case SDLK_ESCAPE: 
         exit(0); 
         break; 
        case SDLK_w: 
         yrotrad = (yrot/180 * 3.141592654f); 
         xrotrad = (xrot/180 * 3.141592654f); 
         xpos += (float)sin(yrotrad); 
         zpos -= (float)cos(yrotrad); 
         ypos -= (float)sin(xrotrad); 
         std::cout << "w pressed" << std::endl; 
         break; 
        case SDLK_s: 
         yrotrad = (yrot/180 * 3.141592654f); 
         xrotrad = (xrot/180 * 3.141592654f); 
         xpos -= (float)sin(yrotrad); 
         zpos += (float)cos(yrotrad); 
         ypos += (float)sin(xrotrad); 
         break; 
        case SDLK_d: 
         yrotrad = (yrot/180 * 3.141592654f); 
         xpos += (float)cos(yrotrad) * 0.2; 
         zpos += (float)sin(yrotrad) * 0.2; 
          break; 
         case SDLK_a: 
         yrotrad = (yrot/180 * 3.141592654f); 
         xpos -= (float)cos(yrotrad) * 0.2; 
         zpos -= (float)sin(yrotrad) * 0.2; 
          break; 
        default: 
         break; 
       } 
       break; 

      case SDL_MOUSEMOTION: 
       diffx=event.motion.x-lastx; //check the difference between the current x and the last x position 
       diffy=event.motion.y-lasty; //check the difference between the current y and the last y position 
       lastx=event.motion.x; //set lastx to the current x position 
       lasty=event.motion.y; //set lasty to the current y position 
       xrot += (float)diffy; //set the xrot to xrot with the addition of the difference in the y position 
       yrot += (float)diffx; //set the xrot to yrot with the addition of the difference in the x position 
       break; 

      case SDL_QUIT: 
       exit(0); 
       break; 

      case SDL_VIDEORESIZE: 
       screen = SDL_SetVideoMode(event.resize.w, event.resize.h, screen_bpp, SDL_OPENGL | SDL_HWSURFACE | SDL_RESIZABLE); 
       screen_width = event.resize.w; 
       screen_height = event.resize.h; 
       init_opengl(); 
       std::cout << "Resized to width: " << event.resize.w << " height: " << event.resize.h << std::endl; 
       break; 

      default: 
       break; 
     } 
    } 

    DrawCube(); 
    camera(); 

    SDL_Delay(50); 
} 
} 

int main(int argc, char* argv[]) 
{ 
if(init_sdl() != false) 
{ 
    std::cout << "SDL Init Successful" << std::endl; 
} 

init_opengl(); 

std::cout << "Hello World" << std::endl; 

heartbeat(); // this is essentially the main loop 

SDL_Quit(); 

return 0; 
} 

Makefile

all: 
g++ -o test main.cpp -lSDL -lGL -lGLU 

Il compile et fonctionne, je suppose que j'ai juste besoin d'aide pour faire la traduction de la caméra. Merci

Répondre

1

Supprimez l'appel glLoadIdentity() de DrawCube(). Remplacez-le par glPushMatrix() au début et glPopMatrix() à la fin. Maintenant, en appuyant sur «w» fait quelque chose. (Je ne suis pas entièrement sûr de ce qu'il est censé faire.)

Le problème est que glLoadIdentity efface toutes les transformations précédentes mises en place avec glTranslatef et autres. Description détaillée: http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushmatrix.html

0

Essayez de rendre l'appareil photo avant de dessiner le cube. À l'heure actuelle, la traduction de la caméra fonctionne bien, mais vous dessinez le cube dans la même position par rapport à la caméra. Si vous dessinez le cube en premier, puis déplacez la caméra, vous devriez voir la traduction que vous attendiez.