(Solucion) Rendimiento con SDL ¿Que pasa? o Que puedo hacer?

(Solucion) Rendimiento con SDL ¿Que pasa? o Que puedo hacer?

Notapor Ricx-Dark » Mié Ago 07, 2013 6:32 pm

Hola!
soy nuevo en esta pagina y estoy aqui para ver si me pueden ayudar
con un problema que tengo con SDL
he estado un tiempo programando con SDL y mayormente haciendo
pruebas, mayormente con pocas imágenes, ahora que estoy haciendo
un nivel estoy colocando mas imágenes y se ve como si tuviera lag
y las imagenes no pesan mucho, entre todas las imagenes pesan unos
4mb
aqui coloco mi codigo aver si me ayudan Porfa! :)

#include <iostream>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>

using namespace std;

#define Ancho 1280
#define Alto 768
#define BPP 24

SDL_Surface *Ventana, *Fondo, *Galaxia, *PlanetaRojo, *LensFlare, *PlanetaAzul, *Plano2Alfa, *Scene, *Jugador;
SDL_Surface *Estrellas[6];
SDL_Rect RectGalaxia, RectPlanetaRojo, RectPlanetaAzul, RectJugador;
SDL_Rect RectScene[3];
SDL_Event Event;
Uint8 *Teclado;

int main(){
bool Salir=false;
int Cont=0, i=0;

atexit(SDL_Quit);

if(SDL_Init(SDL_INIT_VIDEO)<0){
cout<<"Error al iniciar SDL. Error: "<<SDL_GetError();
exit(1);
}

SDL_WM_SetCaption("PruebaNivelPiloto v1",NULL);

Ventana=SDL_SetVideoMode(Ancho, Alto, BPP, SDL_HWSURFACE | SDL_DOUBLEBUF);
if(Ventana==NULL){
cout<<"No se pudo iniciar el modo de video. Error: "<<SDL_GetError();
exit(1);
}

Fondo=IMG_Load("MundoPiloto/Fondo0.png");
if(Fondo==NULL){
cout<<"No se ha podido cargar la imagen 'Fondo0.png'.Error: "<<SDL_GetError();
exit(1);
}

Estrellas[0]=IMG_Load("MundoPiloto/StarsA1.png");
Estrellas[1]=IMG_Load("MundoPiloto/StarsA2.png");
Estrellas[2]=IMG_Load("MundoPiloto/StarsA3.png");
Estrellas[3]=IMG_Load("MundoPiloto/StarsB1.png");
Estrellas[4]=IMG_Load("MundoPiloto/StarsB2.png");
Estrellas[5]=IMG_Load("MundoPiloto/StarsB3.png");
for(int i=0;i<=5;i++){
if(Estrellas[i]==NULL){
cout<<"No se ha podido cargar alguna imagen de las estrellas.Error: "<<SDL_GetError();
exit(1);
}
}

Galaxia=IMG_Load("MundoPiloto/Galaxia.png");
if(Galaxia==NULL){
cout<<"No se ha podico cargar la imagen 'Galaxia.png'. Error: "<<SDL_GetError();
exit(1);
}

PlanetaRojo=IMG_Load("MundoPiloto/PlanetaRojo.png");
if(PlanetaRojo==NULL){
cout<<"No se ha podido cargar 'PlanetaRojo.png'. Error: "<<SDL_GetError()<<endl;
exit(1);
}

LensFlare=IMG_Load("MundoPiloto/LensFlare.png");
if(LensFlare==NULL){
cout<<"No se ha podido cargar la imagen 'LensFlare.png'. Error: "<<SDL_GetError()<<endl;
exit(1);
}

PlanetaAzul=IMG_Load("MundoPiloto/PlanetaAzul.png");
if(PlanetaAzul==NULL){
cout<<"No se ha podido cargar la imagen 'PlanetaAzul.png'. Error: "<<SDL_GetError()<<endl;
exit(1);
}

Plano2Alfa=IMG_Load("MundoPiloto/Plano2Alfa.png");
if(Plano2Alfa==NULL){
cout<<"No se ha podido cargar la imagen 'Plano2Alfa.png'. Error: "<<SDL_GetError()<<endl;
exit(1);
}

Scene=IMG_Load("MundoPiloto/Scene.png");
if(Scene==NULL){
cout<<"No se ha podido cargar 'Scene.png'. Error: "<<SDL_GetError()<<endl;
exit(1);
}

Jugador=IMG_Load("MundoPiloto/Jugador.png");
if(Jugador==NULL){
cout<<"No se ha podido cargar la imagen 'Jugador.png'. Error: "<<SDL_GetError()<<endl;
exit(1);
}

RectGalaxia.x=194;
RectGalaxia.y=45;
RectPlanetaRojo.x=12;
RectPlanetaRojo.y=43;
RectPlanetaAzul.x=818;
RectPlanetaAzul.y=214;
RectScene[0].x=0;
RectScene[0].y=0;
RectScene[0].w=Ancho;
RectScene[0].h=Alto;
RectScene[1].x=0;
RectScene[1].y=0;
RectScene[1].w=0;
RectScene[1].h=Alto;
RectScene[2].x=Ancho;
RectScene[2].y=0;
RectScene[2].h=Alto;
RectScene[2].w=Ancho;
RectJugador.x=20;
RectJugador.y=120;//120

while(Salir==false){
SDL_BlitSurface(Fondo, NULL, Ventana, NULL);
SDL_BlitSurface(Estrellas[Cont], NULL, Ventana, NULL); // Si no muestro
SDL_BlitSurface(Galaxia, NULL, Ventana, &RectGalaxia); // algunas de
SDL_BlitSurface(PlanetaRojo, NULL, Ventana, &RectPlanetaRojo);// estas imagenes
SDL_BlitSurface(LensFlare, NULL, Ventana, NULL); // dejando solamente
SDL_BlitSurface(PlanetaAzul, NULL, Ventana, &RectPlanetaAzul);// a Fondo y Jugador
SDL_BlitSurface(Plano2Alfa, NULL, Ventana, NULL); // el juego corre bien
SDL_BlitSurface(Scene, &RectScene[0], Ventana, NULL);
SDL_BlitSurface(Scene, &RectScene[1], Ventana, &RectScene[2]);
SDL_BlitSurface(Jugador, NULL, Ventana, &RectJugador);

i++;
if(i==2){
if(Cont<5) Cont++;
else Cont=0;
i=0;
}

SDL_Flip(Ventana);

Teclado=SDL_GetKeyState(NULL);
if(Teclado[SDLK_RIGHT] && (RectJugador.x+Jugador->w)<=Ancho){
RectJugador.x+=10;
RectScene[0].x+=10;
RectScene[0].w-=10;
RectScene[1].w=RectScene[0].x;
RectScene[2].x-=10;

if(RectScene[0].x>=Ancho){
RectScene[0].x=0;
RectScene[0].y=0;
RectScene[0].w=Ancho;
RectScene[0].h=Alto;
RectScene[1].x=0;
RectScene[1].y=0;
RectScene[1].w=0;
RectScene[1].h=Alto;
RectScene[2].x=Ancho;
RectScene[2].y=0;
RectScene[2].h=Alto;
RectScene[2].w=Ancho;
}
}
if(Teclado[SDLK_LEFT] && RectJugador.x>=0) {
RectJugador.x-=10;
RectScene[0].x-=10;
RectScene[0].w+=10;
RectScene[1].w=RectScene[0].x;
RectScene[2].x+=10;
}
if(Teclado[SDLK_UP] && (RectJugador.y+Jugador->h>=520)) RectJugador.y-=10;
if(Teclado[SDLK_DOWN] && (RectJugador.y+Jugador->h<=Alto)) RectJugador.y+=10;

if(RectScene[0].x+Scene->w<=0) RectScene[0].x=Ancho;
if(RectScene[1].x+Scene->w<=0) RectScene[1].x=Ancho;

while(SDL_PollEvent(&Event)){
switch(Event.type){
case(SDL_KEYDOWN):{
if(Event.key.keysym.sym==SDLK_ESCAPE) Salir=true;
}
break;

case(SDL_KEYUP):{
if(Event.key.keysym.sym==SDLK_RIGHT) RectJugador.x-=10;
if(Event.key.keysym.sym==SDLK_LEFT) RectJugador.x+=10;
}
break;

case(SDL_QUIT): Salir=true;
break;
}
}
}

SDL_FreeSurface(Fondo);
for(int i=0;i<5;i++){
SDL_FreeSurface(Estrellas[i]);
}

return(0);
}
Última edición por Ricx-Dark el Vie Ago 23, 2013 5:28 am, editado 1 vez en total
Ricx-Dark
 
Mensajes: 3
Registrado: Mié Ago 07, 2013 5:57 pm

Re: Rendimiento con SDL baja ¿Que pasa? o ¿Que puedo hacer?

Notapor shackra » Dom Ago 18, 2013 8:38 pm

el problema ésta acá:

Ricx-Dark escribió:
while(Salir==false){
SDL_BlitSurface(Fondo, NULL, Ventana, NULL);
SDL_BlitSurface(Estrellas[Cont], NULL, Ventana, NULL); // Si no muestro
SDL_BlitSurface(Galaxia, NULL, Ventana, &RectGalaxia); // algunas de
SDL_BlitSurface(PlanetaRojo, NULL, Ventana, &RectPlanetaRojo);// estas imagenes
SDL_BlitSurface(LensFlare, NULL, Ventana, NULL); // dejando solamente
SDL_BlitSurface(PlanetaAzul, NULL, Ventana, &RectPlanetaAzul);// a Fondo y Jugador
SDL_BlitSurface(Plano2Alfa, NULL, Ventana, NULL); // el juego corre bien
SDL_BlitSurface(Scene, &RectScene[0], Ventana, NULL);
SDL_BlitSurface(Scene, &RectScene[1], Ventana, &RectScene[2]);
SDL_BlitSurface(Jugador, NULL, Ventana, &RectJugador);
//···


Aunque aun estoy leyendo Pensar en C++ de Bruce Eckel, se nota que ahí estas dibujando en la pantalla el 100% de las imágenes de forma innecesaria por cada frame, y la operación de pintado de sprites e imágenes en la pantalla es algo costosa en cuanto a rendimiento, según se por mi experiencia ¿Te imaginas el gasto en rendimiento si tratas de dibujar 60 veces por segundo una imagen?

Lo que necesitas es implementar la técnica de rectangulos sucios, que pinta única y exclusivamente las áreas de una imagen que fueron ensuciadas por otra (digamos, el piso debe ser redibujado en ciertas áreas porque el héroe de tu juego pasó por ahí), la cosa es, que no estoy seguro si SDL tiene implementada la técnica y te puede dar la API para que hagas tu respectiva labor, porque yo no uso SDL, claro. Tendrás que investigar un poco en Internet, quizás las siguientes palabras claves en un buscador te lleven a alguna parte: sdl dirty rectangles

Por otra parte, aunque no esta mal del todo, estas mezclando C con C++, SDL fue pensado, creo yo, para programación procedural (un ejemplo de esto es la sentencia SDL_Flip(Ventana); en tu código fuente), no sé si esto ha cambiado en SDL 2, pero seria más practico y bonito que SDL fuera orientado a objetos (para tener sentencias en forma de Ventana.SDL_Flip();)... en fin.

Solamente trata de no dibujar el 100% de todas las imágenes en cada frame de tu juego, y deberías experimentar una mejora en el rendimiento :)
Avatar de Usuario
shackra
 
Mensajes: 308
Registrado: Lun Jun 15, 2009 4:10 pm
Ubicación: Costa Rica

Re: Rendimiento con SDL baja ¿Que pasa? o ¿Que puedo hacer?

Notapor Ricx-Dark » Lun Ago 19, 2013 12:06 am

Hola shackra,
sobre lo que me dijiste ya lo he intentado.
por ejemplo lo que es el fondo y el piso lo muestro antes del
while y luego las otras imágenes. ok bien corre bien, pero, hay
un problema y es que en el caso del personaje que es una imagen que se
mueve mancha(por decirlo asi) las imágenes de atras (en este caso el fondo y el piso)
ya que estas imágenes no se actualizaron con las demás
Ricx-Dark
 
Mensajes: 3
Registrado: Mié Ago 07, 2013 5:57 pm

Re: Rendimiento con SDL baja ¿Que pasa? o ¿Que puedo hacer?

Notapor carleto » Lun Ago 19, 2013 5:41 pm

Hola

Puede ser que el problema lo tengas al cargar las imágenes, hace mucho que no uso SDL, pero revisando código que tengo por ahí y la documentación, diría que tienes que usar la función SDL_DisplayFormat después de cargar cada imagen para convertir la imagen al formato de pantalla. Si no lo haces, esa conversión se hace cada vez que la dibujas.

Un trozo de código que encontré de un juego que hice hace mucho:
//  Carga una imagen de un archivo y la retorna
// Recibe la ruta del archivo a cargar
SDL_Surface *CargarImagen(char *ruta)
{
SDL_Surface *img_tmp, *img;

img_tmp = IMG_Load(ruta);

img = SDL_DisplayFormatAlpha(img_tmp);
SDL_FreeSurface(img_tmp);
return img;
}

Saludos
std::cout << "Usuario registrado de Linux Nº 504222" << std::endl;
Avatar de Usuario
carleto
 
Mensajes: 42
Registrado: Mar Ago 21, 2007 9:38 pm
Ubicación: Almería, España

Re: Rendimiento con SDL baja ¿Que pasa? o ¿Que puedo hacer?

Notapor Ricx-Dark » Vie Ago 23, 2013 5:26 am

Hola!, Bueno ya pude arreglar el error,
y estaba en BPP que yo colocaba 24
y tenia que colocarlo en 32 ya que las
y imágenes eran *.png, ademas, tuve que
colocar SDL_DisplayFormatAlpha()---->gracias a carleto.
(Yo utilizaba SDL_DisplayFormat la cual no copiaba la transparencia)
XD Muchas gracias a todos :)
Ricx-Dark
 
Mensajes: 3
Registrado: Mié Ago 07, 2013 5:57 pm


Volver a Videojuegos

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado