OpenGL/SDL Anfänger - Fragen



  • Hey,
    habe jetzt mit OpenGL/SDL angefangen. Und habe von nem Tutorial her den folgenden Quelltext:

    /*
    Compile command:
    g++ -o test main.cpp -lSDLmain -lSDL -lGL
     */
    
    // specific headers
    #include "SDL.h"
    #include "SDL_opengl.h"
    #include <iostream>
    
    bool checkCollision(float Ax, float Ay, float Aw, float Ah, float Bx, float By, float Bw, float Bh) //Funcfion for checking collision 
    {
      if ( Ay+Ah < By ) return false; //if A is more to the left than B
      else if ( Ay > By+Bh ) return false; //if A is more to the right than B
      else if ( Ax+Aw < Bx ) return false; //if A is higher than B
      else if ( Ax > Bx+Bw ) return false; //if A is lower than B
    
      return true; //There is a collision because none of above returned false
    }
    
    struct Brick //Brick structures which holds 4 elements
    {
      //Elements are used for x and y position of the brick and its width and height
      float x; 
      float y;
      float width;
      float height;
      bool alive; //Alive variable. We use to to store in which state the brick is (broken, not broken)
    };
    
    //start of the program
    int main( int argc, char* args[] )
    {
    
      //initialize SDL
      SDL_Init(SDL_INIT_EVERYTHING);
      //Set OpenGL memory usage 
      SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
      SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8);
      SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
      SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8);
      SDL_GL_SetAttribute( SDL_GL_BUFFER_SIZE, 32);
      SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
      SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
      //Caption of the window
      SDL_WM_SetCaption( "Our first game", NULL );
      //Size of the window
      SDL_SetVideoMode(600,400,32, SDL_OPENGL );
      //Specific the clear color
      glClearColor(1,1,1,1); //RED,GREEN,BLUE,ALPHA
      //What portion of the screen we will display
      glViewport(0,0,600,400);
      //Shader model - Use this
      glShadeModel(GL_SMOOTH);
      //2D rendering
      glMatrixMode(GL_PROJECTION);
      //"Save" it
      glLoadIdentity();
      //Disable depth checking 
      glDisable(GL_DEPTH_TEST);
    
      //Handles the main loop
      bool isRunning = true;
    
      //For handling with event
      SDL_Event event;
    
      float myX = 300; //starting x position of rectangle
      float myY = 370; //starting y position of rectangle
      float width = 80; //width of the rectangle
      float height = 20; //height of the rectangle
    
      bool left = false,right = false; //we save in which state the button is  
    
      //The ball variables
      float ballX = 50; //x position
      float ballY = 350; //y position
      float ballWH = 30; //width and height of the ball
    
      float vellX = 0.2; //x speed
      float vellY = -0.2; //y speed
    
      //Brick elements
      const static int BRICKS = 45; //Constant number where we define how many bricks we want
    
      Brick bricks[BRICKS]; //We create an array of bricks
    
      for ( int n = 0, x = 4, y = 10; n < BRICKS; n++, x+=66 ) //A for loop that goes throught the array so we can set the positions 
        {
          if ( x > 560 ) //If x is near the right edge of the screen
    	{
    	  x = 4; //We start going from the left again
    	  y += 25; //And move a down a little
    	}
          bricks[n].x = x; //Set currents bricks x position
          bricks[n].y = y; //Y position
          bricks[n].width = 60; //Width
          bricks[n].height = 20; //Height
          bricks[n].alive = true; //Set alive to true (not broken)
        }
    
      //Main game loop
      while ( isRunning )
        {
          //EVENTS
          while ( SDL_PollEvent(&event) )
    	{
    	  //if the window was closed
    	  if ( event.type == SDL_QUIT )
    	    {
    	      isRunning = false;
    	    }
    
    	  //If a button was released and the button is escape
    	  if ( event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE )
    	    {
    	      isRunning = false;
    	    }
    
    	  if ( event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_r )
    	    {
    	      glClearColor(1,0,0,1);
    	    }
    
    	  if ( event.type == SDL_KEYDOWN ) //Check for presed down buttons
    	    {
    	      if ( event.key.keysym.sym == SDLK_LEFT ) //Check left key
    		{
    		  left = true; //Set the boolean value for left key to true (it is pressed)
    		}
    
    	      else if ( event.key.keysym.sym == SDLK_RIGHT ) //Check Right key
    		{
    		  right = true; //Set the boolean value for right key to true (it is pressed)
    		}
    
    	    }
    
    	  else if ( event.type == SDL_KEYUP ) //Checking for released buttons
    	    {
    	      if ( event.key.keysym.sym == SDLK_LEFT ) //Left key
    		{
    		  left = false; //Set the value to false (key is released)
    		}
    
    	      else if ( event.key.keysym.sym == SDLK_RIGHT ) //Right key
    		{
    		  right = false; //Key is released
    		}
    	    }
    
    	  //logic that should happen for a certain event
    	}
    
          //LOGIC
          if ( left == true ) //If left key is pressed
    	{
    	  myX -= 0.5; //Move left
    	}
    
          if ( right == true ) //If right key is pressed
    	{
    	  myX += 0.5; //Move right
    	}
    
          if ( myX < 0 ) //If the left border of the pad is over the left part of the screen
    	{
    	  myX = 0; //Put the pad back so it isn't over the border
    	}
    
          if ( myX+width > 600 ) //If the pad is over the right border of the screen
    	{
    	  myX = 600-width; //Move it back so it only touches the right border
    	}
    
          //The ball logic
          ballX += vellX; //Move the ball on x axis first
    
          for ( int n = 0; n < BRICKS; n++ ) //Go throught the array of bricks
    	{
    	  if ( bricks[n].alive == true ) //If the bricks is alive
    	    {
    	      if ( checkCollision(ballX,ballY,ballWH,ballWH,bricks[n].x,bricks[n].y,bricks[n].width, bricks[n].height) == true ) //Check for collision with the ball
    		{
    		  vellX = -vellX; //Change x velocity of the ball
    		  bricks[n].alive = false; //Set the alive variable to false (brick is broken)
    		  break; //Stop checking for collision on x axis
    		}
    	    }
    	}
    
          ballY += vellY; //move the ball on y axis second
    
          for ( int n = 0; n < BRICKS; n++ ) //Go throught the array of bricks
    	{
    	  if ( bricks[n].alive == true ) //If the brick is alive
    	    {
    	      if ( checkCollision(ballX,ballY,ballWH,ballWH,bricks[n].x,bricks[n].y,bricks[n].width, bricks[n].height) == true ) //Check for collision
    		{
    		  vellY = -vellY; //Change y velocity of the ball
    		  bricks[n].alive = false; //Set alive varible to false
    		  break; //Stop checking for collision on y axis
    		}
    	    }
    	}
    
          if ( ballX < 0 ) //Check if the ball hit the left edge of screen
    	{
    	  vellX = -vellX; //negate the x velocity
    	}
    
          else if ( ballX+ballWH>600 )
    	{
    	  vellX = -vellX;
    	}
    
          if ( ballY < 0 )
    	{
    	  vellY = -vellY;
    	}
    
          else if ( ballY+ballWH > 400 ) //if the ball hit the bottom edge of screen
    	{ 
    	  //We set everything back as it was on the start, so we get a restart game impresion
    
    	  myX = 300; //starting x position of rectangle
    	  myY = 370; //starting y position of rectangle
    	  width = 80; //width of the rectangle
    	  height = 20; //height of the rectangle
    
    	  left = false,right = false; //Set the buttons back to false  
    
    	  //The ball variables
    	  ballX = 50; //x position
    	  ballY = 350; //y position
    	  ballWH = 30; //width and height of the ball
    
    	  vellX = 0.2; //x speed
    	  vellY = -0.2; //y speed
    
    	  for ( int n = 0; n < BRICKS; n++ ) //A for loop that goes throught the array so we can set every bricks alive to true (not broken)
    	    {
    	      bricks[n].alive = true;
    	    }
    	}
    
          if ( checkCollision(ballX,ballY,ballWH,ballWH,myX,myY,width,height) == true ) //if there is a collision between the ball and pad
    	{
    	  vellY = -vellY; //change the ball's y velocity/speed
    	}
    
          //RENDERING to the screen
          glClear(GL_COLOR_BUFFER_BIT);
    
          glPushMatrix(); //Start rendering phase 
    
          glOrtho(0,600,400,0,-1,1); //Set the matrix
    
          glColor4ub(0,0,0,255); //Black color
    
          glBegin(GL_QUADS); //Start drawing the pad
    
          glVertex2f(myX,myY); //Upper-left corner
          glVertex2f(myX+width,myY); //Upper-right corner
          glVertex2f(myX+width,myY+height); //Down-right corner
          glVertex2f(myX,myY+height); //Down-left corner
    
          glEnd(); //End drawing
    
          glColor4ub(255,0,0,255); //Red color
    
          glBegin(GL_QUADS); //Render of the ball, same method as for the pad
          glVertex2f(ballX,ballY);
          glVertex2f(ballX+ballWH,ballY);
          glVertex2f(ballX+ballWH,ballY+ballWH);
          glVertex2f(ballX,ballY+ballWH);
          glEnd();
    
          glColor4ub(0,0,255,255); //Blue color
    
          glBegin(GL_QUADS); //Render the bricks
    
          for ( int n = 0; n < BRICKS; n++ ) //We go throught all the elements (bricks)
    	{
    	  if ( bricks[n].alive == true ) //We only draw the brick if it's alive
    	    {
    	      if ( n%2 == 0 ) glColor4ub(122,0,255,255); //Every 2nd bricks has a different color
    	      else glColor4ub(0,0,255,255); //Else it has normal blue color
    
    	      //The 4 edges of the current brick
    	      glVertex2f(bricks[n].x,bricks[n].y);
    	      glVertex2f(bricks[n].x+bricks[n].width,bricks[n].y);
    	      glVertex2f(bricks[n].x+bricks[n].width,bricks[n].y+bricks[n].height);
    	      glVertex2f(bricks[n].x,bricks[n].y+bricks[n].height);
    	    }
    	}
    
          glEnd(); //End drawing
    
          glPopMatrix(); //End rendering phase
    
          SDL_GL_SwapBuffers();
    
          SDL_Delay(1); //Delay / pause
        } 
    
      SDL_Quit();
    
      return 0;
    }
    

    So jetzt habe ich einige Fragen dazu:

    1. Wie z.B. bei Line 159 zu sehen ist wird die X-position des Blocks um 0.5 erhöht/vermindert.
    Doch wie kann man den Block denn um 0.5 Pixel verschieben?
    das ist doch unmöglich?

    2. Wenn ich bei Line 48 UND Line 52 (also SDL_SetVideoMode , glViewport) den Wert ändere, wird das Bild UND die Objekte also die geometrischen Figuren automatisch größer... aber ich habe gedacht man gibt den Formen eine bestimmte Pixelgröße ( z.B. bei Line 70,71).
    Weshalb verändert sich also die Größe eines Objekts, OBWOHL man eine bestimme Pixelgröße angibt?

    3. Wenn ich das Minispiel starte, dauert es immer, bis das Spiel "erscheint".
    Also das Fenster bleibt für ca ~ 1 sekunde weiß (siehe Frage 4 für bessere Beschreibung)
    Das liegt an der "SDL_SetVideoMode" Methode, die dauert so lange (hab ich mit paar Tests rausgefunden 😃 ).
    Ist das normal?

    4. Wenn ich zum Beispiel nur ein simples weißes Fenster erstellen möchte, also Code:

    int main( int argc, char* args[] )
    {
    
      //initialize SDL
      SDL_Init(SDL_INIT_EVERYTHING);
      //Set OpenGL memory usage 
      SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
      SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8);
      SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
      SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8);
      SDL_GL_SetAttribute( SDL_GL_BUFFER_SIZE, 32);
      SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
      SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
      //Caption of the window
      SDL_WM_SetCaption( "Our first game", NULL );
      //Size of the window
      SDL_SetVideoMode(600,400,32, SDL_OPENGL );
      //Specific the clear color
      glClearColor(1,1,1,1); //RED,GREEN,BLUE,ALPHA
      //What portion of the screen we will display
      glViewport(0,0,600,400);
      //Shader model - Use this
      glShadeModel(GL_SMOOTH);
      //2D rendering
      glMatrixMode(GL_PROJECTION);
      //"Save" it
      glLoadIdentity();
      //Disable depth checking 
      glDisable(GL_DEPTH_TEST);
      Sleep(5000);
      SDL_Quit();
    
      return 0;
    }
    

    Dabei entsteht logischerweise ein weißes Fenster, das jedoch unheimlich "laggt und buggy ist".
    Ich meine es lässt sich nur schwer bewegen, stockt immer wieder und reagiert nicht. (Bis 5 sekunden halt dann beendet es sich)
    Ist das normal?

    5. Falls ich das oberige "Spiel" einem anderen weitergebe(mit der SDL.dll) laggt es furchtbar bei ihm und er hat nur sehr wenig FPS.
    Weshalb?

    Danke schonmal und nicht böse sein wegen den Noobfragen 😃



  • Auf Frage 1 geh ich mal nicht ein, das dauert mir gerade zu lange.
    Aber doch: Es ist umsetzbar.

    2. ist doch logisch, dass alles größer wird.
    Die Szene orientiert sich halt nach deiner gewählten Projection.
    Wenn du nun z.B. einen Viewport von 800x600 hast und diesen auf 48x32 änderst, dann kann das Objekt ja nicht über deinen Viewport reichen.
    Kan ndas gerade schlecht erklären aber macht doch irgendwie Sinn oder?

    3. Ja das ist normal. SDL initalisiert ja auch ein paar Sachen und das dauert schon kurz.

    4. Okay, also du nimmst ein Sleep und wunderst dich, warum das Fenster nicht reagiert?! Woran liegt das wohl :p

    5. Gibst du ihm auch eine Release Version und nicht Debug? Hat er vllt. schlechtere Hardware?



  • GLSL schrieb:

    Auf Frage 1 geh ich mal nicht ein, das dauert mir gerade zu lange.
    Aber doch: Es ist umsetzbar.

    2. ist doch logisch, dass alles größer wird.
    Die Szene orientiert sich halt nach deiner gewählten Projection.
    Wenn du nun z.B. einen Viewport von 800x600 hast und diesen auf 48x32 änderst, dann kann das Objekt ja nicht über deinen Viewport reichen.
    Kan ndas gerade schlecht erklären aber macht doch irgendwie Sinn oder?

    3. Ja das ist normal. SDL initalisiert ja auch ein paar Sachen und das dauert schon kurz.

    4. Okay, also du nimmst ein Sleep und wunderst dich, warum das Fenster nicht reagiert?! Woran liegt das wohl :p

    5. Gibst du ihm auch eine Release Version und nicht Debug? Hat er vllt. schlechtere Hardware?

    Ok, danke. zu 5) :
    Ja hat er, aber dieses Spiel ist doch wirklich nicht Leistungsintensiv. Und ja, ich hab ihm die Release Versionen gegeben. (hab schon Debug und Release versucht).

    Wäre nett, wenn mir jemand noch die Frage 1 erklären könnte.
    Und Frage 2 versteh ich immer noch nicht so ganz


Anmelden zum Antworten