I’m working on adding a camera to my 2d texture rendering program so I can scroll around.
All of my textures are set on a sprite sheet.
I’ve got my textures to render in my window with no issues but I want to move the rendered textures offscreen to get my scrolling function to work anyone have any idea how to do that?
I’ve tried using glTranslatef in my render function from LUtil.cpp but it doesn’t move the textures at all.
I also tried moving the geometry that I’m rendering my textures on to, but that distorts the textures.
My code:
LUtil.cpp
#include "LUtil.h"
#include <IL/il.h>
#include <IL/ilu.h>
#include "LTexture.h"
int add = 0;
GLfloat gCameraX = 0.f, gCameraY = 0.f, gCameraZ = 0.f;
//Sprite texture
LTexture gArrowTexture;
//Sprite area
LFRect gArrowClips[ 6 ];
bool initGL()
{
//Set the viewport
glScalef( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH );
//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 );
//Check for error
GLenum error = glGetError();
if( error != GL_NO_ERROR )
{
printf( "Error initializing OpenGL! %s
", 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
", iluErrorString(ilError) );
return false;
}
return true;
}
//Move the sprite changes to a new function that gets called every time you make changes
void updateSpriteAreas()
{
//Set clip rectangles
gArrowClips[ 0 ].x = 0.f;
gArrowClips[ 0 ].y = 0.f;
gArrowClips[ 0 ].w = 330.f;
gArrowClips[ 0 ].h = 355.f;
gArrowClips[ 1 ].x = 331.f;
gArrowClips[ 1 ].y = 0.f;
gArrowClips[ 1 ].w = 310.f;
gArrowClips[ 1 ].h = 480.f;
gArrowClips[ 2 ].x = 0.f;
gArrowClips[ 2 ].y = 355.f;
gArrowClips[ 2 ].w = 330.f;
gArrowClips[ 2 ].h = 125.f;
gArrowClips[ 3 ].x = 0.f;
gArrowClips[ 3 ].y = 0.f;
gArrowClips[ 3 ].w = 310.f;
gArrowClips[ 3 ].h = 720.f;
gArrowClips[ 4 ].x = 0.f;
gArrowClips[ 4 ].y = 355.f;
gArrowClips[ 4 ].w = 800.f;
gArrowClips[ 4 ].h = 125.f;
gArrowClips[ 5 ].x = 0.f; //Don't mind these they were for a test
gArrowClips[ 5 ].y = 0.f;
gArrowClips[ 5 ].w = 330.f;
gArrowClips[ 5 ].h = 355.f;
}
bool loadMedia()
{
//Initialize the sprite rectangles
updateSpriteAreas();
//Load texture
if( !gArrowTexture.loadTextureFromFile( "Textures1.png" ) )
{
printf( "Unable to load texture!
" );
return false;
}
return true;
}
void update()
{
}
void render()
{
//Clear color buffer
glClear( GL_COLOR_BUFFER_BIT );
//Pop default matrix onto current matrix
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
//Save default matrix again
glPushMatrix();
//Render arrows
gArrowTexture.render( 0.f, 0.f, &gArrowClips[ 0 ] );
gArrowTexture.render( SCREEN_WIDTH - gArrowClips[ 1 ].w, SCREEN_HEIGHT - gArrowClips[ 3 ].h, &gArrowClips[ 1 ] );
gArrowTexture.render( SCREEN_WIDTH - gArrowClips[ 4 ].w, SCREEN_HEIGHT - gArrowClips[ 2 ].h, &gArrowClips[ 2 ] );
//Update screen
glutSwapBuffers();
}
void handleKeys( unsigned char key, int x, int y )
{
//If the user presses q
if( key == 'q' && add == 0)
{
gArrowTexture.loadTextureFromFile( "Textures2.png" );
add++;
}
else if( key == 'q' && add == 1)
{
gArrowTexture.loadTextureFromFile( "Textures1.png" );
add--;
}
//Update the sprite rectangles so the texture change takes effect
updateSpriteAreas();
if( key == 27 ) {
exit(0);
}
}
void SpecialKeys(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_LEFT:
gCameraX -= 16.f;
case GLUT_KEY_RIGHT:
gCameraX += 16.f;
case GLUT_KEY_UP:
gCameraY -= 16.f;
case GLUT_KEY_DOWN:
gCameraY += 16.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();
}
}
LTexture.cpp
#include "LTexture.h"
#include <IL/il.h>
LTexture::LTexture()
{
//Initialize texture ID
mTextureID = 0;
//Initialize texture dimensions
mTextureWidth = 0;
mTextureHeight = 0;
}
LTexture::~LTexture()
{
//Free texture data if needed
freeTexture();
}
bool LTexture::loadTextureFromFile( std::string path )
{
//Texture loading success
bool textureLoaded = false;
//Generate and set current image ID
ILuint imgID = 0;
ilGenImages( 1, &imgID );
ilBindImage( imgID );
//Load image
ILboolean success = ilLoadImage( path.c_str() );
//Image loaded successfully
if( success == IL_TRUE )
{
//Convert image to RGBA
success = ilConvertImage( IL_RGBA, IL_UNSIGNED_BYTE );
if( success == IL_TRUE )
{
//Create texture from file pixels
textureLoaded = loadTextureFromPixels32( (GLuint*)ilGetData(), (GLuint)ilGetInteger( IL_IMAGE_WIDTH ), (GLuint)ilGetInteger( IL_IMAGE_HEIGHT ) );
}
//Delete file from memory
ilDeleteImages( 1, &imgID );
}
//Report error
if( !textureLoaded )
{
printf( "Unable to load %s
", path.c_str() );
}
return textureLoaded;
}
bool LTexture::loadTextureFromPixels32( GLuint* pixels, GLuint width, GLuint height )
{
//Free texture if it exists
freeTexture();
//Get texture dimensions
mTextureWidth = width;
mTextureHeight = height;
//Generate texture ID
glGenTextures( 1, &mTextureID );
//Bind texture ID
glBindTexture( GL_TEXTURE_2D, mTextureID );
//Generate texture
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels );
//Set texture parameters
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
//Unbind texture
glBindTexture( GL_TEXTURE_2D, NULL );
//Check for error
GLenum error = glGetError();
if( error != GL_NO_ERROR )
{
printf( "Error loading texture from %p pixels! %s
", pixels, gluErrorString( error ) );
return false;
}
return true;
}
void LTexture::freeTexture()
{
//Delete texture
if( mTextureID != 0 )
{
glDeleteTextures( 1, &mTextureID );
mTextureID = 0;
}
mTextureWidth = 0;
mTextureHeight = 0;
}
void LTexture::render( GLfloat x, GLfloat y, LFRect* clip )
{
//If the texture exists
if( mTextureID != 0 )
{
//Remove any previous transformations
glLoadIdentity();
//Texture coordinates
GLfloat texTop = 0.f;
GLfloat texBottom = 1.f;
GLfloat texLeft = 0.f;
GLfloat texRight = 1.f;
//Vertex coordinates
GLfloat quadWidth = mTextureWidth;
GLfloat quadHeight = mTextureHeight;
//Handle clipping
if( clip != NULL )
{
//Texture coordinates
texLeft = clip->x / mTextureWidth;
texRight = ( clip->x + clip->w ) / mTextureWidth;
texTop = clip->y / mTextureHeight;
texBottom = ( clip->y + clip->h ) / mTextureHeight;
//Vertex coordinates
quadWidth = clip->w;
quadHeight = clip->h;
}
//Move to rendering point
glTranslatef( x, y, 0.f );
//Set texture ID
glBindTexture( GL_TEXTURE_2D, mTextureID );
//Render textured quad
glBegin( GL_QUADS );
glTexCoord2f( texLeft, texTop ); glVertex2f( 0.f, 0.f );
glTexCoord2f( texRight, texTop ); glVertex2f( quadWidth, 0.f );
glTexCoord2f( texRight, texBottom ); glVertex2f( quadWidth, quadHeight );
glTexCoord2f( texLeft, texBottom ); glVertex2f( 0.f, quadHeight );
glEnd();
}
}
GLuint LTexture::getTextureID()
{
return mTextureID;
}
GLuint LTexture::textureWidth()
{
return mTextureWidth;
}
GLuint LTexture::textureHeight()
{
return mTextureHeight;
}