Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: OpenGL, DevIL, C++, How to animate tilesheet?

  1. #1
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    16

    OpenGL, DevIL, C++, How to animate tilesheet?

    I've made my gif into a tilesheet and can render it just fine. Now I need to know how to make it change the Y coordinate while the program is running to animate it without crashing.

    Code :
    #include "LUtil.h"
    #include <IL/il.h>
    #include <IL/ilu.h>
    #include "LSpriteSheet.h"
     
    int add = 0;
    int zoom = 0;
    int factor = 0;
    int factor2 = 0;
    float y = 0.f;
    int scroll = 0;
    GLfloat gCameraX = 0.f, gCameraY = 0.f, gCameraZ = 0.f;
     
    //Sprite texture
     
    LSpriteSheet gArrowSprites;
    LSpriteSheet gGIFSprites;
     
    bool initGL()
    {
            //Initialize GLEW
        GLenum glewError = glewInit();
        if( glewError != GLEW_OK )
        {
            printf( "Error initializing GLEW! %s\n", glewGetErrorString( glewError ) );
            return false;
        }
     
        //Make sure OpenGL 2.1 is supported
        if( !GLEW_VERSION_2_1 )
        {
            printf( "OpenGL 2.1 not supported!\n" );
            return false;
        }
     
        //Set the viewport
        glViewport( 0.f, 0.f, SCREEN_WIDTH, SCREEN_HEIGHT );
     
        //Initialize Projection Matrix
        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
        glOrtho( 0.0, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0, 5.0, -5.0 );
     
        //Initialize Modelview Matrix
        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();
     
        glPushMatrix();
     
        //Initialize clear color
        glClearColor( 0.f, 0.f, 0.f, 1.f );
     
        //Enable texturing
        glEnable( GL_TEXTURE_2D );
     
        glEnable( GL_BLEND );
        glDisable( GL_DEPTH_TEST );
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
     
        //Check for error
        GLenum error = glGetError();
        if( error != GL_NO_ERROR )
        {
            printf( "Error initializing OpenGL! %s\n", gluErrorString(error));
            return false;
        }
     
        //Initialize DevIL
        ilInit();
        ilClearColour( 255, 255, 255, 000 );
     
        //Check for error
        ILenum ilError = ilGetError();
        if( ilError != IL_NO_ERROR )
        {
            printf( "Error initializing DevIL! %s\n", iluErrorString(ilError) );
            return false;
        }
     
        return true;
    }
     
     
    bool loadMedia()
    {
     
        //Load texture
        if( !gArrowSprites.loadTextureFromFile( "StillSpriteSheet.png" ) )
        {
            printf( "Unable to load texture!\n" );
            return false;
        }
    LFRect clip = { 0.f, 0.f, 330.f, 355.f };
     
    	//Top left
    	clip.x = 0.f;
    	clip.y = 0.f;
    	gArrowSprites.addClipSprite( clip );
     
    	//Top right
    	clip = {0.f, 0.f, 310.f, 480.f};
     
    	clip.x = 331.f;
    	clip.y = 0.f;
    	gArrowSprites.addClipSprite( clip );
     
    	clip = {0.f, 0.f, 330.f, 125.f};
    	//Bottom left
    	clip.x = 0.f;
    	clip.y = 355.f;
     
    	gArrowSprites.addClipSprite( clip );
     
    	clip = { 0.f, 0.f, 330.f, 355.f };
     
    	//Top left
    	clip.x = 0.f;
    	clip.y = 480.f;
    	gArrowSprites.addClipSprite( clip );
     
    	//Top right
    	clip = {0.f, 0.f, 310.f, 480.f};
     
    	clip.x = 331.f;
    	clip.y = 480.f;
    	gArrowSprites.addClipSprite( clip );
     
    	clip = {0.f, 0.f, 330.f, 125.f};
    	//Bottom left
    	clip.x = 0.f;
    	clip.y = 835.f;
     
    	gArrowSprites.addClipSprite( clip );
    	//Generate VBO
    	if( !gArrowSprites.generateDataBuffer() )
    	{
    	    printf( "Unable to clip sprite sheet!\n" );
    		return false;
    	}
        if( !gGIFSprites.loadTextureFromFile( "TileSheet.png" ) )
        {
            printf( "Unable to load texture!\n" );
            return false;
        }
     
        clip = {0.f, 0.f, 213.f, 214.f};
     
        clip.x = 0.f;
        clip.y = y;
     
    for (scroll = 0; scroll < 40; ++scroll, clip.y += 214.f, SCREEN_FPS % 10 ){
            glutSwapBuffers();
        if(scroll == 39){
            scroll = 0;
        }
    }
     
    	gGIFSprites.addClipSprite( clip );
     
    	if( !gGIFSprites.generateDataBuffer() )
    	{
    	    printf( "Unable to clip sprite sheet!\n" );
    		return false;
    	}
        return true;
    }
     
    void update()
    {
     
    }
     
    void render()
    {
        //Clear color buffer
     
        glClear( GL_COLOR_BUFFER_BIT );
     
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
     
        glPushMatrix();
     
    if(add == 0){
            if(zoom < 101){
            double const f_zoom = 1.0 + 0.1 * zoom;
            glScaled(f_zoom, f_zoom, f_zoom);
            }
            if(zoom < -10){
            double const f_zoom = 1.0 - 0.1 * zoom;
            glScaled(f_zoom, f_zoom, f_zoom);
            }
     
    	glTranslatef( -100.f, 178.f, 0.f );
    	gArrowSprites.renderSprite( 0 );
     
    	//Render top right arrow
        glTranslatef( +100.f, -178.f, 0.f );
    	glTranslatef( 1240.f, 240.f, 0.f );
    	gArrowSprites.renderSprite( 1 );
     
    	//Render bottom left arrow
        glTranslatef( -1240.f, +240.f, 0.f );
    	glTranslatef( 620.f, 500.f ,0.f );
    	gArrowSprites.renderSprite( 2 );
     
        glTranslatef( -620.f, -500.f, 0.f );
    	glTranslatef( 620.f, 0.f , 0.f );
    	gGIFSprites.renderSprite( 0 );
     
    }
    	if(add == 1){
            if(zoom < 101){
            double const f_zoom = 1.0 + 0.1 * zoom;
            glScaled(f_zoom, f_zoom, f_zoom);
            }
            if(zoom < -10){
            double const f_zoom = 1.0 - 0.1 * zoom;
            glScaled(f_zoom, f_zoom, f_zoom);
            }
     
    	glTranslatef( -100.f, 178.f, 0.f );
    	gArrowSprites.renderSprite( 3 );
     
        glTranslatef( +100.f, -178.f, 0.f );
    	glTranslatef( 1240.f, 240.f, 0.f );
    	gArrowSprites.renderSprite( 4 );
     
        glTranslatef( -1240.f, +240.f, 0.f );
    	glTranslatef( 620.f, 500.f ,0.f );
    	gArrowSprites.renderSprite( 5 );
    	}
     
    	glLoadIdentity();
     
     
        glutSwapBuffers();
     
    }
    void handleKeys( unsigned char key, int x, int y )
    {
        //If the user presses q
       if( key == 'q' && add == 0)
        {
                        add++;
        }
       else if( key == 'q' && add == 1)
        {
            add--;
        }
            //Update the sprite rectangles so the texture change takes effect
            if( key == 27 ) {
                exit(0);
            }
    		if(key == 'a') {
    		gCameraX += 8.f;
    		factor--;
    		factor2++;
    		}
    		else if (key == 'd') {
    		gCameraX -= 8.f;
    		factor++;
    		factor2--;
    		}
    		else if (key == 'w') {
    	    gCameraY += 8.f;
    		}
    		else if (key == 's') {
    		gCameraY -= 8.f;
    		}
    		else if (key == '+' && zoom != 100) {
            zoom += 1;
            if(factor >= 19) {
            gCameraX -= 64.f;
            }
            if(factor2 >= 33){
                gCameraX += 16.f;
            }
            else{
                gCameraX -= 64.f;
                gCameraY -= 50.f;
            }
    		}
    		else if (key == '-' && zoom != -9) {
            zoom -= 1;
            if(factor >= 19){
                gCameraX += 64.f;
            }
            if(factor2 >= 33){
            gCameraX -= 32.f;
            }
            else{
            gCameraX += 64.f;
            gCameraY += 50.f;
    		}
    		}
    		    //Take saved matrix off the stack and reset it
        glMatrixMode( GL_MODELVIEW );
        glPopMatrix();
        glLoadIdentity();
     
        //Move camera to position
        glTranslatef( gCameraX, gCameraY, gCameraZ );
     
        //Save default matrix again with camera translation
        glPushMatrix();
    }

    Right now the while loop causes a crash and I assume that it's because I don't have an FPS limit on it, but I don't know how to implement that.
    Also I know the loop can run because when I remove the if statement that resets the loop it doesn't crash but it stops on the last frame.
    Any help?

    EDIT: Updated the loop.

    Update on issue: In the new loop, if 39 is changed to 40 it stops on the last frame. If 39 is kept as it is it will crash while on a black screen.
    Last edited by PocketTNT; 05-23-2016 at 11:21 AM.

  2. #2
    Member Regular Contributor
    Join Date
    Apr 2012
    Location
    Los Angeles
    Posts
    388
    Sounds like a memory leak.

  3. #3
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    16
    Quote Originally Posted by Carmine View Post
    Sounds like a memory leak.
    How can I fix it though?

  4. #4
    Member Regular Contributor
    Join Date
    May 2016
    Posts
    445
    Quote Originally Posted by PocketTNT View Post
    Right now the while loop causes a crash and I assume that it's because I don't have an FPS limit on it, but I don't know how to implement that.
    you just need a clock
    then in your main loop, you only call update() and render IF enough time is passed since the last frame
    BUT: by default, vsync is on, which means your fps cant get over 60 (frequency of the monitor)
    only if you disable vsync, fps can go up to about 3000 or so ...

    Code :
     
    #define FPS_GOAL 60
     
    ... 
    static double tnow(0), tlast(0), tframe(0);
    tnow = m_time.GetTime();    // http://www.cplusplus.com/reference/chrono/high_resolution_clock/now/
    tframe = tnow - tlast;
    if (tframe < 1.0 / FPS_GOAL)
         continue;
    tlast = tnow;
     
    // update(tframe);
    // render();

  5. #5
    Member Regular Contributor
    Join Date
    Apr 2012
    Location
    Los Angeles
    Posts
    388
    How can I fix it though?
    First, confirm it by monitoring how much RAM your application uses while it is running. If you have a leak, it will show up clearly. RAM usage will go up until the app. crashes.

  6. #6
    Junior Member Newbie
    Join Date
    May 2016
    Posts
    16
    Quote Originally Posted by john_connor View Post
    you just need a clock
    then in your main loop, you only call update() and render IF enough time is passed since the last frame
    BUT: by default, vsync is on, which means your fps cant get over 60 (frequency of the monitor)
    only if you disable vsync, fps can go up to about 3000 or so ...

    Code :
     
    #define FPS_GOAL 60
     
    ... 
    static double tnow(0), tlast(0), tframe(0);
    tnow = m_time.GetTime();    // http://www.cplusplus.com/reference/chrono/high_resolution_clock/now/
    tframe = tnow - tlast;
    if (tframe < 1.0 / FPS_GOAL)
         continue;
    tlast = tnow;
     
    // update(tframe);
    // render();
    Yeah, that's what I thought. But where am I supposed to put it? I've never made my own clock so I have no idea what to do with it.
    Edit: I modified my loop a bit
    Last edited by PocketTNT; 05-23-2016 at 11:32 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •