Error ejecutando codigo OpenGL/SDL

Tratamos sobre el manejo de APIs frecuentemente utilizadas en el desarrollo de videojuegos, como SDL, pygame o SFML.

Error ejecutando codigo OpenGL/SDL

Notapor lacabra25 » Mié Sep 23, 2009 4:55 pm

Hola, he intentado un ejemplo que habia conseguido compilar y que se ejecutara con exito usando OpenGL y GLUT pasarlo a SDL para gestionar la ventana en lugar de GLUT para asi usar OpenGL y SDL, compila sin ningun problema, el problema es cuando intento ejecutarlo y segun se abre la ventana me sale en la terminal un error tras el cual se cierra la ventana.

El codigo es el siguiente:
Código: Seleccionar todo
#include <stdio>
#include <stdlib>
#include <GL>
#include <GL>
#include <SDL>

int main(int argc, char *argv[]){
SDL_Surface *pantalla;
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) == 0){
   pantalla= SDL_SetVideoMode(500, 550, 24, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_OPENGLBLIT);
   if(pantalla != NULL){
      glViewport(0, 0, 500, 550);
      glClearColor(0.0,0.0,0.0,0.0);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective(60.0,1.0,1.0,100.0);
      glTranslatef(0.0,0.0,-2.0);
      glDepthFunc(GL_LEQUAL);
      glEnable(GL_DEPTH_TEST);
      glClearDepth(1.0);
      glMatrixMode(GL_MODELVIEW);
      glBegin(GL_TRIANGLES);
      glColor3f(1.0,0.0,0.0);
      glVertex3f(0.0,0.8,0.0);
      glColor3f(0.0,1.0,0.0);
      glVertex3f(-0.6,-0.2,0.0);
      glColor3f(0.0,0.0,1.0);
      glVertex3f(0.6,-0.2,0.0);
      glEnd();
      glFlush();
      glBegin(GL_QUADS);
      glColor3f(0.0,1.0,1.0);
      glVertex3f(-0.5,0.5,-0.5);
      glVertex3f(-0.5,-0.5,0.5);
      glVertex3f(0.5,-0.5,0.5);
      glVertex3f(0.5,0.5,-0.5);
      glEnd();
      glFlush();
      SDL_Flip(pantalla);
      SDL_Delay(100);
      SDL_FreeSurface(pantalla);
   }
   SDL_Quit();
}
return 0;
}


Y el error que aparece en la terminal es:
NVIDIA: could not open the device file /dev/nvidiactl (Permission denied).


No entiendo por que aparece ese error de que no se puede abrir el dispositivo cuando tengo aplicaciones que usan OpenGL y funcionan sin problemas.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Meldron » Mié Sep 23, 2009 7:48 pm

lacabra25 tu problema es el siguiente: tu codigo no crea un contexto renderizable para OpenGL. Hacerlo con SDL es muy facil, solamente tenes que llamar a SDL_GL_SetAttribute aplicandole parametros especiales (valores de colores, profundidad, doblebuffer etc.). Ademas te combiene incluir el archivo SDL_opengl.h, que tiene las definiciones de los archivos de OpenGL para diversas plataformas, asi tu aplicacion incluso seria multiplataforma.

No se que tan bien andas con el ingles, pero te recomiendo que te fijes en http://anomtech.uuuq.com/Tutorials.php que tiene tutoriales especificamente sobre SDL/OpenGL (usando el Visual C++, pero solo quitando lo especifico de ese compilador funciona perfectamente con el gcc o g++). Tambien en http://nehe.gamedev.net/ tenes ports de los tutoriales para SDL y linux.

PD: revisando bien el codigo hay un par mas de detalles como tener que usar SDL_GL_SwapBuffers() en vez de SDL_Flip(). Asi que te recomiendo que le heches una ojeada al primer tutorial.
Saludos.
Avatar de Usuario
Meldron
 
Mensajes: 20
Registrado: Jue Jun 04, 2009 6:04 pm
Ubicación: Cap. Fed.- Argentina

Notapor lacabra25 » Vie Sep 25, 2009 2:30 pm

Gracias por el enlace, la verdad es que de ingles no es que sepa demasiado, aunque ya entiendo el ingles mejor que antes, de todos modos no he tenido problemas con el ingles para poder modificar el codigo anterior. Aun me sigue apareciendo en terminal el mismo error de antes, pero sin embargo el codigo se compila y ejecuta sin problemas, es decir, aparece al comenzar a ejecutarse el mismo mensaje de error de antes de que no se tienen permisos necesarios para abrir el dispositivo, pero el ejecutable continua la ejecucion, muestra la ventana con el triangulo y el cuadrado espera un tiempo determinado y se cierra sin problemas.

El codigo tal y como esta ahora:
Código: Seleccionar todo
#include <stdio>
#include <stdlib>
#include <GL>
#include <GL>
#include <SDL>
#include <SDL>

int main(int argc, char *argv[]){
SDL_Surface *pantalla;
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) == 0){
   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_DEPTH_SIZE, 8);
   SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
   pantalla= SDL_SetVideoMode(500, 550, 24, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_OPENGLBLIT);
   if(pantalla != NULL){
      glShadeModel(GL_SMOOTH);
      glClearColor(0, 0, 0, 1);
      glViewport(0, 0, 500, 550);
      glClearColor(0.0,0.0,0.0,0.0);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective(60.0,1.0,1.0,100.0);
      glTranslatef(0.0,0.0,-2.0);
      glDepthFunc(GL_LEQUAL);
      glEnable(GL_DEPTH_TEST);
      glClearDepth(1.0);
      glMatrixMode(GL_MODELVIEW);
      glBegin(GL_TRIANGLES);
      glColor3f(1.0,0.0,0.0);
      glVertex3f(0.0,0.8,0.0);
      glColor3f(0.0,1.0,0.0);
      glVertex3f(-0.6,-0.2,0.0);
      glColor3f(0.0,0.0,1.0);
      glVertex3f(0.6,-0.2,0.0);
      glEnd();
      glFlush();
      glBegin(GL_QUADS);
      glColor3f(0.0,1.0,1.0);
      glVertex3f(-0.5,0.5,-0.5);
      glVertex3f(-0.5,-0.5,0.5);
      glVertex3f(0.5,-0.5,0.5);
      glVertex3f(0.5,0.5,-0.5);
      glEnd();
      glFlush();
      SDL_GL_SwapBuffers();
      SDL_Delay(4000);
      SDL_FreeSurface(pantalla);
   }
   SDL_Quit();
}
return 0;
}


Ahora, unas pregutnas. Por lo que he visto en los codigos de la pagina del enlace que me recomendastes, antes de finalizar SDL no liberan la superficie (es decir, no es como cuando se usa solo SDL que se tiene que liberar la superficie devuelta; ademas de no ser necesario pasarle el puntero a la superficie de pantalla a la funcion que hay que usar en lugar de SDL_Flip), ahora la cuestion es ¿las superficie de pantalla, ya la libera SDL cuando se usa junto con OpenGL, o se libera con alguna otra funcion que no es SDL_FreeSurface? yo la libero por si acaso, pero el que en los codigos de ejemplo no lo hicieron me parecio extraño.

Otra cuestion es que todo lo que he leido en el enlace, explica como usar OpenGL con SDL pero usando solo OpenGL para toda la parte grafica, pero, para poder hacer tambien volcados normales con SDL (que por eso tengo la bandera de SDL_OPENGLBLIT cuando inicio el modo de video, en lugar de SDL_OPENGL, ¿como se aria, se copiarian las superficies a la superficie de pantalla, como se hace normalmente, sin que de ningun tipo de error?, ¿como se realizaria el intercambio de bufferes al hacer volcados normales de SDL, con la funcion que hay que usar con OpenGL, o en esa situacion si habria que usar SDL_Flip? ¿haciendo los volcados de SDL tampoco hace falta liberar la superficie de pantalla al usar OpenGL, o en ese caso si?

Gracias por la ayuda.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Juanxo » Vie Sep 25, 2009 3:08 pm

Buenas lacabra:

Yo también he estado viendo los tutoriales, y creo que puedo responderte a la primera pregunta:

El tema de guardar el puntero que devuelve lo de SDL_SetVideoMode es por si luego te interesa usar los parametros de la superficie para hacer algún tipo de cálculos.
El autor de los tutoriales dice que el no va a necesitar utilizar las propiedades de la superficie pantalla (las cuales se pueden obtener a través de otras funciones) por lo que no usa ningún puntero.
El hecho de liberar tu mismo la superficie es más por usar un buen estilo de programación más que nada. Ten en cuenta que, en la mayoría de los casos(si no siempre) liberas la pantalla justo antes de terminar el programa, por lo que no es necesario (cuando un programa se termina, toda su memoria queda libre(que no vacía) por lo que otros programas pueden sobrescribirla.
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor endaramiz » Vie Sep 25, 2009 5:22 pm

lacabra25 escribió:Otra cuestion es que todo lo que he leido en el enlace, explica como usar OpenGL con SDL pero usando solo OpenGL para toda la parte grafica, pero, para poder hacer tambien volcados normales con SDL (que por eso tengo la bandera de SDL_OPENGLBLIT cuando inicio el modo de video, en lugar de SDL_OPENGL, ¿como se aria, se copiarian las superficies a la superficie de pantalla, como se hace normalmente, sin que de ningun tipo de error?, ¿como se realizaria el intercambio de bufferes al hacer volcados normales de SDL, con la funcion que hay que usar con OpenGL, o en esa situacion si habria que usar SDL_Flip? ¿haciendo los volcados de SDL tampoco hace falta liberar la superficie de pantalla al usar OpenGL, o en ese caso si?

El flag SDL_OPENGLBLIT será eliminado en próximas versiones (está deprecated) así que no te aconsejo dedicar tiempo a aprender como va. Además, hacer un blit al estilo de OpenGL es mucho más potente (reescalado automático, tinte a la imagen, ¡velocidad!...).

http://www.libsdl.org/cgi/docwiki.cgi/SDL_SetVideoMode escribió:SDL_OPENGLBLIT
Create an OpenGL rendering context, like above, but allow normal blitting operations. The screen (2D) surface may have an alpha channel, and SDL_UpdateRects must be used for updating changes to the screen surface. NOTE: This option is kept for compatibility only, and will be removed in next versions. Is not recommended for new code.


Saludos.
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

Notapor lacabra25 » Vie Sep 25, 2009 5:57 pm

endaramiz escribió:
lacabra25 escribió:Otra cuestion es que todo lo que he leido en el enlace, explica como usar OpenGL con SDL pero usando solo OpenGL para toda la parte grafica, pero, para poder hacer tambien volcados normales con SDL (que por eso tengo la bandera de SDL_OPENGLBLIT cuando inicio el modo de video, en lugar de SDL_OPENGL, ¿como se aria, se copiarian las superficies a la superficie de pantalla, como se hace normalmente, sin que de ningun tipo de error?, ¿como se realizaria el intercambio de bufferes al hacer volcados normales de SDL, con la funcion que hay que usar con OpenGL, o en esa situacion si habria que usar SDL_Flip? ¿haciendo los volcados de SDL tampoco hace falta liberar la superficie de pantalla al usar OpenGL, o en ese caso si?

El flag SDL_OPENGLBLIT será eliminado en próximas versiones (está deprecated) así que no te aconsejo dedicar tiempo a aprender como va. Además, hacer un blit al estilo de OpenGL es mucho más potente (reescalado automático, tinte a la imagen, ¡velocidad!...).

http://www.libsdl.org/cgi/docwiki.cgi/SDL_SetVideoMode escribió:SDL_OPENGLBLIT
Create an OpenGL rendering context, like above, but allow normal blitting operations. The screen (2D) surface may have an alpha channel, and SDL_UpdateRects must be used for updating changes to the screen surface. NOTE: This option is kept for compatibility only, and will be removed in next versions. Is not recommended for new code.


Saludos.


Haber si lo he entendido, van a quitar eso de SDL, entonces no se podra copiar superficies cargadas desde archivos a la superficie de pantalla tal y como se hace con SDL normalmente ¿no?, entonces, una vez que tenga cargada una imagen en una superficie de SDL, ¿como puedo copiarla a la pantalla mediante OpenGL (supongo que ya lo imaginareis, pero, me estoi refiriendo a aparte de usar OpenGL para el 3D a tambien, de alguna manera, poder mostrar imagenes 2D en pantalla)? ¿OpenGL soporta todo lo que SDL soporta, como lo del color key y todo eso? ¿podrias indicarme documentacion, o algo con lo que poder aprender a trabajar en 2D ademas de en 3D con OpenGL?

Sobre lo de que la pantalla se libere cuando acabe el programa, esta bien, pero aun asi creo que es mas eficiente (sobretodo cuando se este trabajando con muchas superficies en memoria y otras estructuras de datos dinamicas) que cuando se vaya a finalizar el programa se libere la superficie de la pantalla (que en principio se supone que es la superficie de mayor tamaño del programa) para asi ya dejarla liberada para otros programas en lo que se continua liberando el resto de memoria dinamica y realizando otras tareas que sean necesarias antes de finalizar el programa (guardar configuraciones, records, tec, etc), no se que os parecera a los demas, pero me aprece bien el liberar la superficie de la pantalla.

Gracias por la ayuda nuevamente.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Meldron » Vie Sep 25, 2009 7:25 pm

lacabra25 escribió:Haber si lo he entendido, van a quitar eso de SDL, entonces no se podra copiar superficies cargadas desde archivos a la superficie de pantalla tal y como se hace con SDL normalmente ¿no?, entonces, una vez que tenga cargada una imagen en una superficie de SDL, ¿como puedo copiarla a la pantalla mediante OpenGL (supongo que ya lo imaginareis, pero, me estoi refiriendo a aparte de usar OpenGL para el 3D a tambien, de alguna manera, poder mostrar imagenes 2D en pantalla)? ¿OpenGL soporta todo lo que SDL soporta, como lo del color key y todo eso? ¿podrias indicarme documentacion, o algo con lo que poder aprender a trabajar en 2D ademas de en 3D con OpenGL?

Sobre lo de que la pantalla se libere cuando acabe el programa, esta bien, pero aun asi creo que es mas eficiente (sobretodo cuando se este trabajando con muchas superficies en memoria y otras estructuras de datos dinamicas) que cuando se vaya a finalizar el programa se libere la superficie de la pantalla (que en principio se supone que es la superficie de mayor tamaño del programa) para asi ya dejarla liberada para otros programas en lo que se continua liberando el resto de memoria dinamica y realizando otras tareas que sean necesarias antes de finalizar el programa (guardar configuraciones, records, tec, etc), no se que os parecera a los demas, pero me aprece bien el liberar la superficie de la pantalla.

Gracias por la ayuda nuevamente.


Bueno primero una aclaracion que tiene que ver solo con SDL. Teoricamente, si no te olvidas de llamar a SDL_Quit() cuando termina el programa, todos los recursos que tomo SDL los va a liberar. Es decir que no tendrian que quedar memory leaks. Pero no es una buena practica, ya que algunas veces usas una superficie temporal para hacer una conversion que despues no vas a necesitar y ahi si necesitas hacer SDL_FreeSurface(temporal) para optimizar la aplicacion.



Con respecto a tus dudas; en primer lugar no se recomienda mezclar SDL y OpenGL para la parte grafica (de ahi que SDL_OPENGLBLIT sea deprecated).
A SDL generalmente se lo usa para crear el contexto renderizable y manejar los eventos. Despues para la parte grafica se usa OpenGL, que es exactamente lo unico que hace. OpenGL no gestiona sonidos, ni eventos ni nada. Tampoco carga imagenes de distintos formatos. Por esto ultimo, tenes que usar una libreria para cargar imagenes, que tranquilamente puede ser SDL.
Ahora la question es que OpenGL no se maneja con superficies, si no que utiliza lo que se llama "texturas". La idea básica, es que con por ej SDL_image cargas una imagen y luego la "transformas" en una textura con OpenGL. En el primer tutorial que te pase, hay una seccion que explica como hacerlo.
OpenGL soporta todo y mucho mas de lo que soporta SDL, pero de otra manera. Es bastante dificil de explicar en un foro y la documentacion en español no existe practicamente(ya en ingles encontrar un buen tutorial de SDL/OpenGL es raro, y muchisimo mas si lo queres explicado para GNU/Linux :( ).
Pero bueno lo unico que te puedo recomendar son dos cosas:
1-Tener buenos conocimientos de Algebra Lineal (especificamente
vectores y matrices) y Analisis . Porque? bueno porque OpenGL se maneja con transformaciones que se aplican a distintos puntos o vertices. Explicado muy vagamente, a un punto que tiene 3 coordenadas (vector (x,y,z)) le vas aplicando diferentes transformaciones de rotacion, escalado, traslacion etc para representarlo en un espacio. Y basicamente esas transformaciones es multiplicar el vector por la matriz correspondiente a la transformacion que queres aplicar. Asi que es un requisito manejarse bien (no ser un matematico) con Algebra.
2- El unico tutorial decente que encontre en español es este: http://unsitioweb.com/videojuegos tiene 2 ventajas y 2 desventajas.

Primero las ventajas:
-Esta en español
-Esta explicado MUY bien, con esto me refiero a que te enseña a entender lo que estas haciendo y no solamente te da la informacion.

Desventajas:
-Lamentablemente (por lo menos para mì) esta destinado para Windows y ni siquiera usa SDL, si no que usa la WinAPI32. Que realmente es un dolor de huev... y si no tenes idea de usarla (ademas que es bastante enquilombada) tratar de aprender algo complicado como OpenGL usando la WinAPI32 puede ser molesto.
-La otra desventaja es que esta basado en el estandar de OpenGL 1.1, que a esta altura ya es muy viejo (se va por OpenGL 3.0 y la diferencia es mucha). No te creas que el tutorial es viejo, el que lo escribio lo hizo hace un par de meses, pero bueno no esta actualizado principalmente porque Windows dejo de dar soporte a OpenGL justamente en la 1.1 y se dedico a Directx(Esto NO quiere decir que no se pueda correr OpenGL 3 en Windows).

Pero igualmente la parte teorica esta muy interesante.

Por ultimo si queres aprender bien OpenGL, algun dia vas a tener que comprarte un libro, porque libros si hay muchos. Pero eso si, todos en ingles.

Bueno espero haberte ayudado en algo (seguro que la complique :P )
Saludos
Avatar de Usuario
Meldron
 
Mensajes: 20
Registrado: Jue Jun 04, 2009 6:04 pm
Ubicación: Cap. Fed.- Argentina

Notapor lacabra25 » Sab Sep 26, 2009 12:19 pm

Lo que mencionas de liberar la superficies para optimizar la aplicacion lo entiendo, es lo que yo intentaba decir antes, que aunque al acabar el programa se libere la memoria, cuanto antes se libere desde que deja de hacer falta, mejor.

Lo de no mezclar SDL y OpenGL, se me ocurrio por ser lo mas facil para el blittin 2D al ya saber como hacerlo en SDL, pero si con OpenGL puedo obtener los mismos resultados que el que obtendria haciendolo con SDL, y además lo haria mas rapido el ejecutable, pues aunque tenga que aprender más supongo que es mejor hacerlo con OpenGL y merecera la pena el tener que 'empollar' más OpenGL. (lo de el tema de la documentacion, me he ido dando cuenta al no encontrar apenas nada de documentacion, pero es una pena que exista tan poca documentacion de SDL/OpenGL para usuarios de GNU/Linux y más pena aun que no exista en español).

La algebra lineal, vectores y matrices no me suponen demasiado problema, ya di en matematicas las matrices, las operaciones con ellas, los vectores, sistemas de ecuaciones usando matrices y geometria en el espacio (con vectores y matrices), por lo que solo seria repasar los apuntes de matematicas, y si acaso aprender algo nuevo que no haya dado sobre las matrices y vectores.

Gracias pro el tutorial, estando en español y bien explicado aunque este destinado para windows (que para mi tambien es algo decepcionante) la parte teorica se deberia poder utilizar para GNU/Linux (y a base de probar codigo y cambiarlo, poco a poco deberia de ir aprendiendo).

En cuanto a lo de libros para aprender OpenGL, tengo en PDF el libro rojo y el azul, o el rojo y otro, que no los e tocado demasiado por como estan en ingles y es mas dificil enterarse que con documentacion en español.

Y gracias por la ayuda (que lo has complicado, solamente me toca leer mas documentacion y probar mas codigo).

Una ultima cosa ¿por que si el codigo que tengo ahoramismo probando, que funciona sin problemas, al ejecutarse muestra en terminal aun el mensaje que mostraba al principio cuando no funcionaba? ¿si con los cambios hecos funciona, no deberia haber dejado de mostrar ese mensaje?
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Juanxo » Sab Sep 26, 2009 1:37 pm

Buenas lacabra:

Googleando un poco he visto un par de posibles soluciones, que no se si te funcionarán:

Primera opción:

En el directorio /etc/modprobe.d deberías tener algún archivo que pusiera algo de nvidia. Si no existe lo creas con nombre "nvidia" y dentro le pones:

options nvidia NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=33 NVreg_DeviceFileMode=0666

donde NVreg_DeviceFileGID es el identificador que tiene en tu ordenador el grupo "video".

Opción 2:

Cambiar el archivo /etc/udev/rules.d/40-video.rules (si no existe lo creas) y el archivo tiene que tener:

KERNEL=="nvidia*", GROUP="video", MODE="0666"


Supongo que después de esto tendrás que reiniciar.
Esta información no es super completa, pero yo la he encontrado googleando en 5 mins, si le dedicas más tiempo podrás asegurarte. Problema (para algunos) que casi todo ta en inglés.

Lo de cambiar el MODE a 0666 es para que lo pueda usar cualquier usuario, aunque esté fuera del grupo video
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Meldron » Sab Sep 26, 2009 2:40 pm

Bueno estuve trabajando con el codigo que escribiste y tal como esta, a mi no me compila con el gcc. Hay un par de cosas que no entiendo, por ejemplo porque incluis dos veces el mismo archivo en el caso de <SDL> y de <GL>?
Igualmente la declaracion correcta, por lo menos para que a mi me funcione es GL/gl.h, si usamos GNU/Linux. Despues lo compilo y funciona, pero igualmente fijate esto:

Código: Seleccionar todo
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_DEPTH_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
pantalla= SDL_SetVideoMode(500, 550, 24, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_OPENGLBLIT);


Cuando creas el contexto para OpenGL con el SDL_GL_SetAttribute ya especificas el doblebuffer, asi que no hace falta que en SDL_SetVideoMode pongas SDL_DOUBLEBUF, el SDL_OPENGLBLIT esta deprecated y no tiene sentido porque la parte grafica la va a hacer OpenGL no SDL(en caso contrario no vale la pena usar OpenGL). El SDL_HWSURFACE tampoco va porque OpenGL usa directamente la placa de video (si es que existe y esta configurada). Por ultimo fijate que para cada color especificas 8 bits y 8 bits mas para el alpha, osea en total tu profundidad de color es 32, sin embargo en SDL_SetVideoMode pones 24. Asi que directamente quedaria como:

Código: Seleccionar todo
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_DEPTH_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_SetVideoMode(500, 550, 32, SDL_OPENGL);

que ya especifica que vas a usar OpenGL.

Por otra parte, al tutorial en español de
Código: Seleccionar todo
http://unsitioweb.com/videojuegos
, usalo para la parte teorica, y compara el codigo del mismo con el de
Código: Seleccionar todo
http://anomtech.uuuq.com/Tutorials.php
que esta en SDL/OpenGL.

En cuanto al error que te sigue apareciendo, la verdad me confunde bastante, sobre todo el hecho de que hayas podido compilar ese codigo y funcionara(yo lo tuve que modificar para que compile), asi que podrias decirnos que compilador usaste y que distribucion tenes.

Saludos.
Avatar de Usuario
Meldron
 
Mensajes: 20
Registrado: Jue Jun 04, 2009 6:04 pm
Ubicación: Cap. Fed.- Argentina

Notapor endaramiz » Sab Sep 26, 2009 5:54 pm

lacabra25 escribió:Haber si lo he entendido, van a quitar eso de SDL, entonces no se podra copiar superficies cargadas desde archivos a la superficie de pantalla tal y como se hace con SDL normalmente ¿no?, entonces, una vez que tenga cargada una imagen en una superficie de SDL, ¿como puedo copiarla a la pantalla mediante OpenGL (supongo que ya lo imaginareis, pero, me estoi refiriendo a aparte de usar OpenGL para el 3D a tambien, de alguna manera, poder mostrar imagenes 2D en pantalla)? ¿OpenGL soporta todo lo que SDL soporta, como lo del color key y todo eso? ¿podrias indicarme documentacion, o algo con lo que poder aprender a trabajar en 2D ademas de en 3D con OpenGL?

Tranquilo, OpenGL también trabaja con 2D. Lo bueno es que a parte de hacer juegos al estilo retro, también le puedes añadir efectos más modernos (No creo que SDL consiguiese tirar el sistema de partículas del geometry wars). Por ejemplo, el supertux utiliza OpenGL, tiene un aspecto clásico pero ahora están añadiendole un sistema de luces al engine que promete bastante, zoom...

De documentación sobre 2D en OpenGL, yo estuve buscando y encontré muy poca. Básicamente, solo he leído nehe. A mí también se me da mal el inglés porque no prestaba atención en el colegio. Pero leyendo esos tutoriales con el traductor de google al lado he aprendido bastante. Aunque al principio te cueste, tienes que seguir intentando. Ahora estoy tan animado que me he comprado el pack de libros rojo y naranja.

Respecto a lo de hacer un blit, te paso un código que he ido montando por piezas. Si te digo la verdad, no entiendo muchas líneas de configuración de OpenGL (lo de initGL...) y puede que algunas sobren o estén mal. Pero te lo paso porque entre todos seguro que aprendemos más rápido :D

Saludos.
Código: Seleccionar todo
#include <iostream>
#include <SDL>
#include <GL>
#include <GL>
using namespace std;


float ftime = 0;


//estructura creada para guardar la anchura y altura de la textura
struct OGL_Surface {
    GLuint texture;
    float x, y;
    int w, h;
} surf;

float angle;

//copypaste de nehe, modificado para OGL_Surface
/* function to load in bitmap as a GL texture */
int LoadGLTextures( )
{
    /* Status indicator */
    int Status = false;

    /* Create storage space for the texture */
    SDL_Surface *TextureImage[1];

    /* Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit */
    if ( ( TextureImage[0] = SDL_LoadBMP( "crate.bmp" ) ) )
        {

            surf.w = TextureImage[0]->w;
            surf.h = TextureImage[0]->h;
       /* Set the status to true */
       Status = true;

       /* Create The Texture */
       glGenTextures( 1, &surf.texture );

       /* Load in texture 1 */
       /* Typical Texture Generation Using Data From The Bitmap */
       glBindTexture( GL_TEXTURE_2D, surf.texture );

       /* Generate The Texture */
       glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage[0]->w,
           TextureImage[0]->h, 0, GL_BGR,
           GL_UNSIGNED_BYTE, TextureImage[0]->pixels );
      
       /* Nearest Filtering */
       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
              GL_NEAREST );
       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
              GL_NEAREST );
        }

    /* Free up any memory we may have used */
    if ( TextureImage[0] )
       SDL_FreeSurface( TextureImage[0] );

    return Status;
}

//copypaste, la mayoria no se para que sirve
void initGL() {
    if (!LoadGLTextures()) {
        cerr << "no se han cargado las imagenes" << endl;
        return;
    }

    glEnable(GL_TEXTURE_2D);
    glShadeModel(GL_SMOOTH);
    glClearColor( 1.0f, 0.0f, 0.0f, 0.0f );
    glClearDepth( 1.0f );
    glEnable( GL_DEPTH_TEST );
    glDepthFunc( GL_LEQUAL );
    glBlendFunc( GL_ONE, GL_ONE );
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
    glLineWidth(4.0);

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   //¡¡ESTO ES LO QUE HACE QUE TRABAJE EN 2D!!
   glOrtho(0.0, 640.0, 0.0, 480.0, -6.0, 6.0);
      
}



void draw() {
   glMatrixMode(GL_MODELVIEW);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   //se borra el buffer de color y profundidad
   glLoadIdentity();                           //nos situamos en (0,0,0) mirando hacia -z
   
   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //rellena //GL_LINE pinta solo las lineas
   
   glPushMatrix(); //guardamos la matriz de posicion
   glTranslatef(250.0f, 150.0f, -5.0f); // se mueve la camara o el mundo
   //si lo piensas con ejes locales el orden es normal
   //si lo piensas con ejes 0,0,0 , el orden es inverso, tipo algebra lineal (matrices)

        glDisable(GL_TEXTURE_2D);
   glRotatef(angle, 0.0f, 0.0f, 1.0f);
        //imprimimos el triangulo
   glBegin(GL_TRIANGLES);
      glColor3f(1.0f, 0.0f, 0.0f);
      glVertex3f(200.0f, 0.0f, 0.0f);
      glColor3f(0.0f, 1.0f, 0.0f);   
      glVertex3f(-200.0f, 0.0f, 0.0f);
      glColor3f(0.0f, 0.0f, 1.0f);   
      glVertex3f(0.0f, 200.0f, 0.0f);
      glColor3f(1.0f, 1.0f, 1.0f);
   glEnd();
   glPopMatrix(); //cargamos la matriz de posicion
   //glLoadIdentity(); //como se ha guardado la matriz al principio de todo, cargar tiene el mismo resultado que hacer un LoadIdentity

        //imprimimos la textura
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, surf.texture);
   glBegin(GL_QUADS);
      glNormal3f(0.0f, 0.0f, 1.0f);
      glTexCoord2f(0.5f, 0.5f); glVertex3f(surf.x, surf.y , -1.0f);
      glTexCoord2f(0.5f, 1.0f); glVertex3f(surf.x, surf.y-float(surf.h), -1.0f);
      glTexCoord2f(1.0f, 1.0f); glVertex3f(surf.x+surf.w, surf.y-float(surf.h), -1.0f);
      glTexCoord2f(1.0f, 0.5f); glVertex3f(surf.x+surf.w, surf.y, -1.0f);
   glEnd();

   SDL_GL_SwapBuffers(); //flip del doble buffer
}


int main() {
   if (SDL_Init(SDL_INIT_VIDEO) == -1)  cout << "no se ha iniciado SDL" << endl;
   
   SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16,
      SDL_OPENGL | SDL_GL_DOUBLEBUFFER |
      SDL_HWPALETTE | SDL_HWSURFACE | SDL_HWACCEL);
   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_DEPTH_SIZE, 24);
   SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
   
   if (screen == NULL) cout << "No se ha iniciado la ventana OpeGL" << endl;
   initGL();
   
   surf.y = surf.x = 100;
   int vx = 0;
   int vy = 0;

   bool exit = false;
   int tics = SDL_GetTicks();
   
   while (not exit) {
      
      int tnow = SDL_GetTicks();
      ftime = (tnow-tics)/1000.0f;
      tics = tnow;

      draw();
   
      SDL_Event event;
      while (SDL_PollEvent(&event)) {
         switch (event.type) {
            case SDL_QUIT:
               exit = true;
            break;
            case SDL_KEYDOWN:
               if (event.key.keysym.sym == SDLK_DOWN)
                  vy = -100;
               if (event.key.keysym.sym == SDLK_UP)
                  vy = +100;
               if (event.key.keysym.sym == SDLK_LEFT) {
                  vx = -100;
                  surf.w = -abs(surf.w);
               }
               if (event.key.keysym.sym == SDLK_RIGHT) {
                  vx = +100;
                  surf.w = abs(surf.w);
               }
               if (event.key.keysym.sym == SDLK_ESCAPE)
                  exit = true;
            break;
            case SDL_KEYUP:
               if (event.key.keysym.sym == SDLK_DOWN)
                  vy = 0;
               if (event.key.keysym.sym == SDLK_UP)
                  vy = 0;
               if (event.key.keysym.sym == SDLK_LEFT)
                  vx = 0;
               if (event.key.keysym.sym == SDLK_RIGHT)
                  vx = 0;
            break;
         }
      }   
      surf.x += vx*ftime;
      surf.y += vy*ftime;
      angle += ftime*100;
   }
   
   SDL_Quit();
}


Se compila con g++ archivo.cpp -o ejecutable -lSDL -lGL

PD: no he explicado lo de como dibujar la textura porque estoy muy mal de tiempo, intentaré hacerlo otro día. De mientras intenta comprender el código (lo de que solo salga un cuarto de la imagen ayuda).
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

Notapor Juanxo » Dom Sep 27, 2009 1:08 am

Buenas:

Siento deciros chicos, que es una pena que no entendais bien el inglés, más que nada porque casi todos los nombres de funciones y parámetros se explican casi solos.

Aparte de esto, quisiera comentar un par de cosillas del código de endaramiz:

en initGL() comentas que glOrtho es la que se encarga de lo de 2D, pero existe una modificación de esta que es gluOrtho2D que se olvida de los dos últimos parámetros y hace que trabajes en 2D (es lo mismo que establecer los dos parametros del final a 0.

en la función draw, no hace falta que cambies cada vez que dibujas el modo de la matriz a GL_MODELVIEW, con que lo hagas una vez vale.
Como consecuencia de esto, lo de loadIdentity(que carga la matriz identidad para las transformaciones) también sobraría.

Creo, y solo creo, que no es necesario que hagas lo de glEnable/Disable(GL_TEXTURE2D) puesto que entre esas llamadas no les haces ningún cambio. Estas llamadas activan/desactivan el uso de las texturas nada más, no las dibuja ni nada parecido.

la función glBindTexture establece la textura a utilizar, pero como solo hay una, y no cambia, no hace falta que la llames cada vez que dibujas.

Y ya por último, no hay que establecer los atributos de OpenGL lo de SDL_GL_SetAttribute antes de crear la pantalla, o da igual el orden?

Por cierto, que hace la Función Normal3f()??

@lacabra: ahora estoy traduciendo making games with pygames, pero cuando termine, si esque el tiempo me lo permite, puedo intentar traducir los tutoriales que comento Meldron, que están muy bien.

Un saludo a todos
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor endaramiz » Dom Sep 27, 2009 12:25 pm

Es cierto, algunas no son necesarias llamarlas cada vez. Voy a tener que mirar para que sirve cada cosa exactamente. Aunque algunas como la de elegir la textura, son útiles para cuando se quiera expandir el código.
Lo del glOrtho en 3D creo que es interesante porque la tercera coordenada se puede utilizar como capa y así no hace falta imprimir en orden. Por ejemplo, si la tercera coordenada del translate del triángulo se cambia a -0.5, pasa a pintarse delante de la textura ya que está activado el test de profundidad.

Normal3f() se me olvidó borrarla, la utilicé cuando estuve haciendo pruebas de iluminación.

Saludos.
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

Notapor endaramiz » Lun Sep 28, 2009 4:07 pm

Como bien dije antes, intentaré explicar como va lo imprimir una textura (imagen). Aunque seguramente alguien lo pueda hacer mejor que yo. Estoy aprendiendo y a lo mejor me equivoco.

Código: Seleccionar todo
    glBindTexture(GL_TEXTURE_2D, surf.texture);
    glBegin(GL_QUADS);
      glTexCoord2f(0.5f, 0.5f); glVertex3f(surf.x, surf.y , -1.0f);
      glTexCoord2f(0.5f, 1.0f); glVertex3f(surf.x, surf.y-float(surf.h), -1.0f);
      glTexCoord2f(1.0f, 1.0f); glVertex3f(surf.x+surf.w, surf.y-float(surf.h), -1.0f);
      glTexCoord2f(1.0f, 0.5f); glVertex3f(surf.x+surf.w, surf.y, -1.0f);
    glEnd();

En las dos primeras líneas se le dice a OpenGL que se va a dibujar un cuadrado utilizando la textura surf.texture.
Luego vienen 4 pares de instrucciones. Cada par corresponde a un vértice del cuadrado.
Con la primera instrucción decimos a qué parte de la textura corresponde el vértice. (0f, 0f) corresponde a la parte superior izquierda y (1f, 1f) corresponde a la inferior derecha. En nuestro caso, como se cogen algunos valores intermedios, solo se imprime el cuarto inferior derecho de la imagen.
Con la segunda instrucción, le decimos en qué posición de la pantalla queremos que vaya el vértice del cuadrado.

Los vértices no hace falta que estén a la distancia que realmente mide la imagen, hará un reescalado y/o flip automático si hace falta.

Si no te queda claro (es posible con mis explicaciones xD), prueba a cambiar los valores.

Saludos.
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

Notapor lacabra25 » Mar Sep 29, 2009 6:12 am

Meldron escribió:Bueno estuve trabajando con el codigo que escribiste y tal como esta, a mi no me compila con el gcc. Hay un par de cosas que no entiendo, por ejemplo porque incluis dos veces el mismo archivo en el caso de <SDL> y de <GL>?
Igualmente la declaracion correcta, por lo menos para que a mi me funcione es GL/gl.h, si usamos GNU/Linux. Despues lo compilo y funciona, pero igualmente fijate esto:

Código: Seleccionar todo
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_DEPTH_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
pantalla= SDL_SetVideoMode(500, 550, 24, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_OPENGLBLIT);


Cuando creas el contexto para OpenGL con el SDL_GL_SetAttribute ya especificas el doblebuffer, asi que no hace falta que en SDL_SetVideoMode pongas SDL_DOUBLEBUF, el SDL_OPENGLBLIT esta deprecated y no tiene sentido porque la parte grafica la va a hacer OpenGL no SDL(en caso contrario no vale la pena usar OpenGL). El SDL_HWSURFACE tampoco va porque OpenGL usa directamente la placa de video (si es que existe y esta configurada). Por ultimo fijate que para cada color especificas 8 bits y 8 bits mas para el alpha, osea en total tu profundidad de color es 32, sin embargo en SDL_SetVideoMode pones 24. Asi que directamente quedaria como:

Código: Seleccionar todo
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_DEPTH_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_SetVideoMode(500, 550, 32, SDL_OPENGL);

que ya especifica que vas a usar OpenGL.

Por otra parte, al tutorial en español de
Código: Seleccionar todo
http://unsitioweb.com/videojuegos
, usalo para la parte teorica, y compara el codigo del mismo con el de
Código: Seleccionar todo
http://anomtech.uuuq.com/Tutorials.php
que esta en SDL/OpenGL.

En cuanto al error que te sigue apareciendo, la verdad me confunde bastante, sobre todo el hecho de que hayas podido compilar ese codigo y funcionara(yo lo tuve que modificar para que compile), asi que podrias decirnos que compilador usaste y que distribucion tenes.

Saludos.


Pues en realidad no incluyo dos veces el mismo archivo, sino ke son <GL> y <GL> y <SDL> y el otro ke en una respuesta anterior recomendaron ke usara para ke los tipos de OpenGL fuesen multiplataforma, es decir, son diferentes includes, pero al poner el codigo en el foro borra a partir de la / inclullendo la propia barra, con lo ke parece ke se incluye dos veces lo mismo.

Lo del contexto con blit de SDL ya lo he modificado, pero en el momento ke peque el codigo aun no lo hbia modificado, y lo del doble buffer y el hardware de video, pues no lo pense, la costumbre de ponerlos practicamente siempre en SDL. De lo de profundidad de 24 en vez de 32 ni me fije, tendre que cambiarlo. Y uso la distribucion Ubuntu en su version 9.04 y como compilador, como no podia ser de otra forma Gcc.

Gracias a todos por la ayuda, y voy a seguir leyendo y trabajando con el codigo a ver si consigo poco a poco aprender a usar OpenGL.


P.D.: si tuvieses tiempo para traducirlo seria genial, gracias.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor lacabra25 » Mar Sep 29, 2009 3:28 pm

Juanxo escribió:Buenas lacabra:

Googleando un poco he visto un par de posibles soluciones, que no se si te funcionarán:

Primera opción:

En el directorio /etc/modprobe.d deberías tener algún archivo que pusiera algo de nvidia. Si no existe lo creas con nombre "nvidia" y dentro le pones:

options nvidia NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=33 NVreg_DeviceFileMode=0666

donde NVreg_DeviceFileGID es el identificador que tiene en tu ordenador el grupo "video".

Opción 2:

Cambiar el archivo /etc/udev/rules.d/40-video.rules (si no existe lo creas) y el archivo tiene que tener:

KERNEL=="nvidia*", GROUP="video", MODE="0666"


Supongo que después de esto tendrás que reiniciar.
Esta información no es super completa, pero yo la he encontrado googleando en 5 mins, si le dedicas más tiempo podrás asegurarte. Problema (para algunos) que casi todo ta en inglés.

Lo de cambiar el MODE a 0666 es para que lo pueda usar cualquier usuario, aunque esté fuera del grupo video


Entonces el problema de que me aparezca ese aviso al ejecutar el codigo compilado, ¿es solamente por el ejecutable no pertenecer al grupo de video que mencionas?, entonces cuando se ejecuta ¿no usa la tarjeta grafica sino funciona realizando todo por software, no? Y, aparte de la opcion de cambiar los permisos necesarios para acceder a la tarjeta grafica ¿tambien se podria ejecutar el programa en lugar de con los permisos normales de usuario, con algun permiso mas o algo que haga que se ejecute con permisos suficientes, no?
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Meldron » Mar Sep 29, 2009 6:28 pm

lacabra25, ahora entiendo el error de los includes(el foro lo borra, supongo que sera alguna cuestion de HTML) asi que te pido disculpas. Igualmente te recomiendo que directamente incluyas SDL_opengl.h, donde estan las declaraciones para OpenGL dependiendo el sistema operativo en donde se compila(por lo menos en GNU/Linux, Mac y Win), con lo cual sería multiplataforma. Asi que directamente solo tendrias que incluir lo siguiente:

SDL/SDL.h
SDL/SDL_opengl.h

Fijate que no declaro GL/gl.h porque de eso se encarga SDL_opengl.h (podes mirar el codigo fuente de SDL_opengl.h para ver como lo hace.)


Entonces el problema de que me aparezca ese aviso al ejecutar el codigo compilado, ¿es solamente por el ejecutable no pertenecer al grupo de video que mencionas?, entonces cuando se ejecuta ¿no usa la tarjeta grafica sino funciona realizando todo por software, no? Y, aparte de la opcion de cambiar los permisos necesarios para acceder a la tarjeta grafica ¿tambien se podria ejecutar el programa en lugar de con los permisos normales de usuario, con algun permiso mas o algo que haga que se ejecute con permisos suficientes, no?


Si el problema es que tu usuario no pertenece al grupo video (necesario para usar aceleracion 3d y acceder a la placa de video) entonces podrias probar con el comando:

gpasswd -a usuario video

(reemplazando "usuario" por el nombre correspodiente). Para lo cual necesitas ser root, o usar sudo. Sino como siempre podes ejecutar el programa como root directamente.

Saludos
Avatar de Usuario
Meldron
 
Mensajes: 20
Registrado: Jue Jun 04, 2009 6:04 pm
Ubicación: Cap. Fed.- Argentina

Notapor lacabra25 » Mar Sep 29, 2009 10:05 pm

No tienes por que disculparte, tal y como el foro muestra el codigo no podias saber que includes eran, debi de haberme fijado y haber intentado probar a separarlos con un espacio de la barra para ver si asi lo mostraba mejor, o haberlo comentado justo despues del codigo.

Sobre los includes, si SDL_opengl.h ya incluye GL/gl.h, entonces, como estoy incluyendo ademas GL/glu.h, en total quedarian los includes como:

Código: Seleccionar todo
#include <SDL>/*delante lleva SDL/*/
#include <SDL_opengl>/*delante lleva SDL/*/
#include <gl>/*delante lleva GL/*/
/*todos acaban con .h*/


¿O tambien la libreria glu la incluye SDL_opengl?
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Juanxo » Mar Sep 29, 2009 10:19 pm

buenas lacabra:

Para usar GLU, te vale con incluir <SDL> y <SDL_opengl>, y luego incluir GLu32.lib en el linker, todos con su respectiva .h
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Meldron » Mié Sep 30, 2009 12:48 am

lacabra25 escribió:No tienes por que disculparte, tal y como el foro muestra el codigo no podias saber que includes eran, debi de haberme fijado y haber intentado probar a separarlos con un espacio de la barra para ver si asi lo mostraba mejor, o haberlo comentado justo despues del codigo.

Sobre los includes, si SDL_opengl.h ya incluye GL/gl.h, entonces, como estoy incluyendo ademas GL/glu.h, en total quedarian los includes como:

Código: Seleccionar todo
#include <SDL>/*delante lleva SDL/*/
#include <SDL_opengl>/*delante lleva SDL/*/
#include <gl>/*delante lleva GL/*/
/*todos acaban con .h*/


¿O tambien la libreria glu la incluye SDL_opengl?


Efectivamente SDL_opengl.h incluye tanto a GL como a GLU, asi que no hace falta incluir GLU.
Eso si, cuando compilas con el gcc tenes que especificar todas las librerias, a ser:

-lSDL -lGL -lGLU y todas las demas que necesites.

El GLu32.lib que mencionó Juanxo es necesario cuando programas bajo WIndows. Hasta donde yo se, en Linux serian libGL.so y libGLU.so .
Suerte.
Avatar de Usuario
Meldron
 
Mensajes: 20
Registrado: Jue Jun 04, 2009 6:04 pm
Ubicación: Cap. Fed.- Argentina

Notapor Juanxo » Jue Oct 01, 2009 3:21 pm

buenas señores:

Trasteando un poco con los ejemplos de Anomalistic Technologies (los que posteo Meldron), me ha surgido una duda, y quería ver si alguno podía ayudarme:

En el tutorial de la habitación 3D, cuando explica como dibujar el suelo y el techo de la habitación hace una división de la profundidad (eje Z) del suelo ( que es 8) entre 2, ya que es la diferencia entre (1 y -1) que ha usado en el ortho.

Mi duda es, que no se cual queda mejor (más realista), ya que a mí la solución del tutorial me parece un poco alargada.

Os pego el código y una captura:

Código: Seleccionar todo
/*Código tutorial*/
      glBegin(GL_QUADS);
         glTexCoord2f(0, 0);
         glVertex3d(-200, 500, 4.0);

         glTexCoord2f(1200.f / FloorTexWidth, 0);
         glVertex3d(1000, 500, 4.0);

         glTexCoord2f(1200.f / FloorTexWidth, (8.f / 2.f * 600.f) / FloorTexHeight);
         glVertex3d(1000, 500,-4.0);
                       
                        /*Con lo de división me refiero a ese /2.0f */
         glTexCoord2f(0, (8.f / 2.f * 600.f) / FloorTexHeight);
         glVertex3d(-200, 500,-4.0);

         /* Ceiling. */
         glTexCoord2f(0, 0);
         glVertex3d(-200, 0, 4.0);

         glTexCoord2f(1200.f / FloorTexWidth, 0);
         glVertex3d(1000, 0, 4.0);

         glTexCoord2f(1200.f / FloorTexWidth, (8.f / 2.f * 600.f) / FloorTexHeight);
         glVertex3d(1000, 0,-4.0);

         glTexCoord2f(0, (8.f / 2.f * 600.f)  / FloorTexHeight);
         glVertex3d(-200, 0,-4.0);
      glEnd();


Código: Seleccionar todo
/*Mi código*/
      glBegin(GL_QUADS);

         /*Floor*/
         /*We need to translate the floor from a x-z surface onto a x-y surface *
          *We accomplish that using the depth of the floor (8 = 4 - (-4))*/

         glTexCoord2f(0.0, 0.0);
         glVertex3f(-200.0f, 600.0f, 4.0f);

         glTexCoord2f(1200.f / texturesArray[1].w, 0.0);
         glVertex3f(1000.0f, 600.0f, 4.0f);

         glTexCoord2f(1200.f / texturesArray[1].w, (8.0f*600.0f)/ texturesArray[1].h);
         glVertex3f(1000.0f, 600.0, -4.0f);

         glTexCoord2f(0.0, (8.0f* 600.0f)/ texturesArray[1].h);
         glVertex3f(-200.0f, 600.0, -4.0f);

         /*Roof*/
         glTexCoord2f(0.0, 0.0);
         glVertex3f(-200.0f, 0.0f, 4.0f);

         glTexCoord2f(1200.f / texturesArray[1].w, 0.0);
         glVertex3f(1000.0f, 0.0f, 4.0f);

         glTexCoord2f(1200.f / texturesArray[1].w, (8.0f*600.0f)/ texturesArray[1].h);
         glVertex3f(1000.0f, 0.0, -4.0f);

         glTexCoord2f(0.0, (8.0f* 600.0f)/ texturesArray[1].h);
         glVertex3f(-200.0f, 0.0, -4.0f);

      glEnd();


La única diferencia en cuanto a la lógica es la división que os mencionaba.

Adjunto una caputura de pantalla (el suelo es de mi manera, el techo de la manera del tutorial)

[img=http://img10.imageshack.us/img10/3753/habitacion3d.th.png]
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor lacabra25 » Sab Oct 03, 2009 10:54 am

Yo creo que queda mejor como lo has modificado, de la otra forma esa de dividiendo entre dos da una sensacion de que estuviese estirado.

Una duda, ¿que diferencia hay entre usar SwapBuffers(DevContex); o SwapBuffers();? Lo pregunto por que he visto ejemplos de OpenGL que usan la primera, pero a mi me funciona con la segunda, por lo que ya me supongo que las dos funcionan, pero no se cual es la diferencia entre una u otra.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Juanxo » Vie Oct 09, 2009 2:49 pm

He investigado un poco, y al parecer lo de devContex es específico de windows, que es la manera que tiene de identifcar con que dispositivo(device), en este caso la ventana, esta relacionado el programa

Un saludo
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)


Volver a Sobre las bibliotecas multimedia

¿Quién está conectado?

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