SDL Opengl help

Started by
3 comments, last by cory_mcm 12 years, 10 months ago
First off just wanted to let everyone know that im am a beginner hence why im posting in this section :). Second I am trying to create a asteroids clone using sdl for everything besides rotation.
Im using SDL 1.3 with opengl and everythings working intill I call my rotate function which takes a opengl texture does a glrotate then grabs the pixels and i create a SDL texture from that rotated surface. I know my method is way off because its going to be slow in real time but i dont want to do it in only opengl because im making a game pack where you can select from my retro arcade and
the rest of the games are created with sdl and sdl renderer. So my problem is i have a big memleak when rotating when i free my buffer, sdl surfaces and sdl texture then rotate again i can watch my memory build up each time in the task manager. Just hoping some of the pros can help me with this leak here some of my code where it is called.
Function where i rotate
SDL_Texture *loadText(GLuint texture,SDL_Renderer *renderer)

{

SDL_Surface *newsur;

GLfloat textureWidth, textureHeight;

Uint32 rmask, gmask, bmask, amask;

/* SDL interprets each pixel as a 32-bit number, so our masks must depend

on the endianness (byte order) of the machine */

#if SDL_BYTEORDER == SDL_BIG_ENDIAN

rmask = 0xff000000;

gmask = 0x00ff0000;

bmask = 0x0000ff00;

amask = 0x000000ff;

#else

rmask = 0x000000ff;

gmask = 0x0000ff00;

bmask = 0x00ff0000;

amask = 0xff000000;

#endif

glGetTexLevelParameterfv(GL_TEXTURE_2D, 1, GL_TEXTURE_WIDTH, &textureWidth);

glGetTexLevelParameterfv(GL_TEXTURE_2D, 1, GL_TEXTURE_HEIGHT, &textureHeight);

GLushort *buffer = (GLushort *)malloc(textureWidth*textureHeight*4);

glReadPixels(200,150,textureWidth,textureHeight,GL_RGBA, GL_UNSIGNED_BYTE,buffer);

newsur=SDL_CreateRGBSurface(SDL_ANYFORMAT,256,256,32,rmask,gmask,bmask,amask);

newsur->pixels = buffer;

text = SDL_CreateTextureFromSurface(renderer,newsur);
if(newsur)

{

SDL_FreeSurface(newsur);

newsur = NULL;

}

if(buffer)

{

free(buffer);

buffer = NULL;

}

return text;

}



And my main

int main(argc, argv[])

{

if ( SDL_Init(SDL_INIT_VIDEO) != 0 )

{

printf("Unable to initialize SDL: %s\n", SDL_GetError());

return 1;

}

SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

SDL_Window *window;

/* Set 640x480 video mode */

window = SDL_CreateWindow("Test", 0, 250, 640, 480,

SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);

SDL_GLContext glcontext= SDL_GL_CreateContext(window);

renderer = SDL_CreateRenderer(window, 0, 1);

SDL_GL_MakeCurrent(window, glcontext);

init();

glEnable( GL_TEXTURE_2D );

/* Enable swap on VSYNC */

SDL_GL_SetSwapInterval(1);

GLuint texture; //This is a handle to our texture object

texture = CreateTexture("sky.bmp",NORM);

SDL_Texture *background =0;

SDL_Rect dstbg, srcbg;

dstbg.x = 0; // Sets X and Y position for image (Foreground)

dstbg.y = 0;

srcbg.x = 0;

srcbg.y = 0;

dstbg.w = 256 ;

dstbg.h = 256 ;

done = false;
while (!done)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
// check for messages
switch (event.type)
{
// exit if the window is closed
case SDL_QUIT:
done = true;
break;
// check for keypresses
case SDL_KEYDOWN:
// exit if ESCAPE is pressed
if (event.key.keysym.sym == SDLK_ESCAPE)
done = true;
if (event.key.keysym.sym == SDLK_LEFT)
{
angle -=.75;
background = loadText(texture,renderer);
text = NULL;
}
if (event.key.keysym.sym == SDLK_RIGHT)
{
angle +=.75;
background = loadText(texture,renderer);
text = NULL;
}
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);

if(background)
SDL_RenderCopy(renderer, background, 0, &dstbg);


display();
SDL_RenderPresent(renderer);
}

return 0;
}



Please any help or comments are appreciated
Advertisement
Hm, that sounds like a rather roundabout way of rotating an image.

Are you sure you really need to support software rendering? Or by 'OpenGL texture', do you mean an actual hardware-accelerated sprite backed by a texture object? (If it's the latter, that's even more roundabout ;)

Generally, you'd just use OpenGL directly for this sort of thing (it'd be a lot easier).
Ok so I have found out what the problem is. The call that eats up my memory is text = SDL_CreateTextureFromSurface(renderer,newsur); and I just switched to streaming textures and switched the call to SDL_UpdateTexture and It also eats up my resources. Ive commented out all the lines in the function and it only starts eat up memory when i use those two calls. If anyone knows of a better way to change the pixels on a texture please reply back.


If anyone knows of a better way to change the pixels on a texture please reply back.

Typically you wouldn't modify a texture after it's been created. If you're just wanting to be able to create freely rotating sprites, the most straightforward solution would probably be to use OpenGL directly and rotate your objects by applying an appropriate transform.
Ya i figured i was rotating sprites oddly but i wanted to do it on the fly and not have to code the whole game in open gl. my other option is to use 8 pre rotated images. This is my opengl draw and texture loading code just for more info thanks again.

GLuint CreateTexture(char * ImgName, int type)
{
GLuint texture;
SDL_Surface *surface;
GLenum texture_format;
GLint nOfColors;

if ( (surface = SDL_LoadBMP(ImgName)) )
{

// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 )
{
printf("warning: image.bmp's width is not a power of 2\n");
}

// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 )
{
printf("warning: image.bmp's height is not a power of 2\n");
}

// get the number of channels in the SDL surface
nOfColors = surface->format->BytesPerPixel;
if (nOfColors == 4) // contains an alpha channel
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
}
else if (nOfColors == 3) // no alpha channel
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
}
else
{
printf("warning: the image is not truecolor.. this will probably break\n");
// this error should not go unhandled
}
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
// Bind the texture object
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR );
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels );
}
else
{
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
// Free the SDL_Surface only if it was successfully created
if ( surface )
{
SDL_FreeSurface( surface );
}
return texture;
}

void
drawBox(void)
{
glTranslatef(1, 1, 0);
glRotatef(angle,0.0,0.0,1.0);
glTranslatef(-1, -1, 0);
glBegin( GL_QUADS );
glTexCoord2d(0.0,0.0);
glVertex2d(0.0,0.0);
glTexCoord2d(1.0,0.0);
glVertex2d(2.0,0.0);
glTexCoord2d(1.0,1.0);
glVertex2d(2.0,2.0);
glTexCoord2d(0.0,1.0);
glVertex2d(0.0,2.0);
glEnd();

}

This topic is closed to new replies.

Advertisement