Pequeño motor 3D

Hola. Ahora que queda poco para que llegue la gp2x, se me ha ocurrido que ya que la consola no tiene aceleración 3D, no vendria mal hacer un software que utilizando uno de los procesadores, hiciese de aceleradora.

Como no dispongo de nada (ni tengo la consola, ni tengo las herramientas de programación, por no tener, no he programado siquiera para gp32, a pesar de tenerla...) pues ando trabajando desde visual C haciendo digamos, la funcion de dibujado de triangulos.

Para ello, empleo numeros enteros solo y externamente necsita únicamente de dos funciones: GetPixel y PutPixel.

De momento lo que llevo hecho, es capaz de dibujar una lista de triangulos en los que se detallan los vertices de la siguiente manera:

int x,y,z: // coordenadas espaciales
unsigned color; // color RGBA
int tx,ty; // coordenadas de textura

Las coordenadas de texturas, se suprimen en caso de no emplearse textura (la funcion de dibujado recibe una serie de flags, entre ellos el que indica si se debe utilizar textura.

La funcion de dibujado de triangulos, admite tres modos de operar: lista de triangulos, triagle fan (lista de vertices donde el primero referencia el centro del objeto) y triangle strip (lista de vertices que concatena una serie de triangulos).

Se pueden dibujar triangulos solidos o 'wired'.

La funcion es capaz de dibujar triangulos con o sin texturas, con iluminación gouraud, usando transparencias y translucidez (canal alpha), usando Buffer Z.

El color del triangulo se combina con el color de pixel de la textura, de tal forma que si el valor de un componente supera 0x80 (un componente de RGBA varia desde 0 a 0xff), la luz se mezcla de forma que crea lo que se conoce como iluminacion especular (que el objeto toma el color de la luz). Si el valor es inferior, se produce una atenuacion del color de la textura de forma que se oscurece. De esta forma tan sencilla, se controla la iluminacion.

La translucided se lleva a cabo sin usar un buffer alpha: se toma el color del antiguo pixel de pantalla y se usa el color alpha del pixel a dibujar como factor para mezclar ambos colores.

En la imagen de ejemplo, se pueden ver, arriba, 3 triangulos texturados mediante el metodo fan (si, la textura es una rejilla cutre de 3x3 pixeles :p).

Abajo, se aprecia otros tres triangulos dibujados mediante metodo strip y superpuesto, otro triangulo sin textura, en el que se aprecia el efecto translucidez.

Observar en la esquina superior izquierda del triangle strip, el tono azulado que demuestra el uso de luz especular y tambien del gouraud (los pixeles de textura de esa zona, son amarillos y solo cuando nos acercamos a los otros vertices, que tienen luz blanca, el color de la textura va ganando fuerza (observar los degradados)

Si observais el triangulo que se pinta con translucidez, el vertice superior es de color verde, mientras el inferior izquierdo es azul semitransparente y el inferior derecho azul-solido. Se aprecian tanto los degradados de color, como los desgradados translucidos en la imagen.


En fin, esto es lo que llevo hasta ahora hecho y sobre temas como numero de poligonos por segundo, etc, no me pregunteis que no lo se, ya que eso habra que verlo in situ, en su momento.

Adjuntos

en gp32spain ya hay un proyecto de motor 3d, que ya esta bastante avanzado, si conoces bien el tema, podrias contactar con A.r.R.c.H.E.r. por si te interesa colaborar.

puedes ver los progresos en este hilo:

http://www.gp32spain.com/foros/showthread.php?s=&threadid=23281

se está haciendo un juego 3d tipo wipeout, pero a la vez se esta diseñando el motor grafico para futuros desarrollos
Esp3tek escribió:en gp32spain ya hay un proyecto de motor 3d, que ya esta bastante avanzado, si conoces bien el tema, podrias contactar con A.r.R.c.H.E.r. por si te interesa colaborar.

puedes ver los progresos en este hilo:

http://www.gp32spain.com/foros/showthread.php?s=&threadid=23281

se está haciendo un juego 3d tipo wipeout, pero a la vez se esta diseñando el motor grafico para futuros desarrollos



Sip, recuerdo de haber leido algo por esos foros (estoy registrado desde hace tiempo, aunque yo gp32 la tengo como algo secundario, aunque eso puede cambiar dentro de poco).

Ayer, siguiendo un tutorial de esa pagina, instalé el entorno de programacion bajo SDL. Aunque yo nunca he programado con las SDL y desconozco bastante cosas de gp32 (muchísimas), no me costó mucho modificar uno de los ejemplos para añadirle las rutinas que he creado y ahí ando, optimizando algunas cosas para ganar la maxima velocidad posible.

Me he bajado el ejemplo de 'Wipeout' de A.r.R.c.H.E.r y aunque es un buen trabajo teniendo en cuenta las limitaciones de la maquina, los poligonos no son texturados ni se emplea iluminacion gouraud o transparencias.

En esto es en lo que estoy trabajando yo, desde C, en un trabajo que seguramente sea paralelo al de otros, pero yo creo que es mejor idea hacerlo así al principio.

De momento tengo un pequeño ejemplo rulando en gp32 donde aparece un circulo grande texturado y en rotacion, con todas las opciones de rasterizacion activas (buffer Z de 32 bits, alpha blendig, transparencias e iluminacion gouraud), junto con otros dos circulos no texturados translucidos que recorren la pantalla a una velocidad de 1000 triangulos segundo (los triangulos son grandes y hay que tener en cuenta que las medidas que se usan en tarjetas de video, difieren mucho (creo que suelen llamar poligono a un grupo de 15 pixeles))

Puede parecer poco, pero no es la gp32 precisamente para la que estoy pensando el tema, y todavia me quedan algunos truquitos para intentar acelerar al maximo el tema.

Incluso si fracaso en este cometido por falta de potencia de las consolas, siempre puedo recurrir a la rasterizacion de poligonos texturados sin iluminacion, o poligonos sin texturizar (con rutinas especializadas) para ganar mas velocidad. O darle otros usos, claro.

De momento estoy dando los primeros pasos y no quiero 'incordiar' a nadie bombardeandole con preguntas (por ejemplo [+risas]) y salvo que reciba alguna invitacion por parte de alguien, prefiero mantenerme al margen hasta que tenga algo interesante que ofrecer ;)

Por supuesto, si desarrollo algo interesante, todos los fuentes estaran disponibles bajo licencia GPL. Es lo que me gusta de esta scene, que aquí ciertos elementos que en PS2 promueven la scene simplemente, para sacar partido economico... aqui no existe porque la plataforma es completamente open source ;)
El engine de Archer cuenta con texturas actualmente y se mueve igual de rapido que sin ellas, pero eso si, no tiene iluminacion de ningun tipo.

Creeme, si entiendes algo del tema y lo que quieres es aprender lo mejor que puedes hacer es intentar colaborar con ellos. Una-i (programador conocidillo y que actualmente trabaja en Pyro Studios) les está echando una mano en ciertas cosas y en cuanto al renderizado basico esta todo muy currado. Podrias ahorrarte muchos dolores de cabeza estudiando su codigo y ademas podrias colaborar en la ampliacion de las librerias para añadir iluminacion si te interesa ese tema.

No pretendo meterme donde no me llaman, pero creo que como manera de aprender y ponerte a prueba es lo mejor. A parte de que toda ayuda es poca en proyectos de desarrollo libre como ese.

En cualquier caso... animo y suerte con la programacion para GP.
Mortimor escribió:El engine de Archer cuenta con texturas actualmente y se mueve igual de rapido que sin ellas, pero eso si, no tiene iluminacion de ningun tipo.

Creeme, si entiendes algo del tema y lo que quieres es aprender lo mejor que puedes hacer es intentar colaborar con ellos. Una-i (programador conocidillo y que actualmente trabaja en Pyro Studios) les está echando una mano en ciertas cosas y en cuanto al renderizado basico esta todo muy currado. Podrias ahorrarte muchos dolores de cabeza estudiando su codigo y ademas podrias colaborar en la ampliacion de las librerias para añadir iluminacion si te interesa ese tema.

No pretendo meterme donde no me llaman, pero creo que como manera de aprender y ponerte a prueba es lo mejor. A parte de que toda ayuda es poca en proyectos de desarrollo libre como ese.

En cualquier caso... animo y suerte con la programacion para GP.


Hummm, como digo arriba, uno no se puede presentar a una fiesta sin haber sido invitado ;).

Seguramente, ellos tengan mas avanzado el tema, pero no se, tampoco me preocupa pues en mi caso, no es cuestion de comerse el tarro haciendo algo, si no aplicar algo que conozco desde hace muchos años y que con la aparición de las aceleradoras graficas, dejó de ser util (de ahi que en menos de un día, tuviera hecha la rutina que describo al abrir este hilo, partiendo desde 0).

Ahora me estoy limitando a reducir calculos ya que la gp32 no es suficientemente potente para manejar tanta informacion por pixel usando algunos viejos truquillos ... pero tranquilo, que no me voy a comer desmasiado el tarro: desconozco por completo el codigo ASM de esta máquina y sus capacidades y solo me limito a optimizar el codigo en C. En todo caso, para mi tiene su valor y no me preocupa en absoluto que alguien pueda estar trabajando en algo similar o que incluso, lo supere (aunque yo no apunto a GP32 si no a su sucesora)
Entiendo que quieras ir por libre, de hecho yo lo hago ya que es dificil formar parte de un equipo cuando se trabaja por placer (no siempre hay ganas o tiempo).

En cuanto a lo de invitacion... :) ellos han pedido ayuda y siempre han estado abiertos a nuevas incorporaciones. En un principio no iban a tocar las texturas, pero luego se unio un tio que estaba mirando el tema y ahora van como si nada; tu pudes hacer lo mismo. :)
dos cositas:
1- olvida visualC... para desarrollar para GP2X necesitas SDL y funcionara con base a un linux, asi que te recomiendo un linux (ubuntu mismo estaria bien) y Kdevelop si te gusta un IDE grafico o 'motor' si te gusta un IDE texto. digo por ahorrar los maximos problemas futuros. yo estoy usando Kdevelop con soporte C++ y SDL, y ya he hecho un par de ejemplitos
2- usar rutinas de tan alto nivel como getpixel y putpixel en un motor 3D es simplemente una locura, y, no me interpretes mal, una perdida de tiempo. normalmente en un engine 3D la rutina de mas alto nivel que se use es 'drawHline' y 'drawHlinetext' y si acaso 'drawHlinetextblend'. que dibujan lineas horizontales con suavizado gouraud, lineas horizontales con textura, y lineas horizontales con suavizado gouraud, texturadas y mezcladas con canal alpha.

para terminar, hay un par de proyectillos que se llama TinyGL y TinySDGL que intentan (y por ejemplo TinySDGL ya lo consigue) proveer un engine OpenGL basico con poca ocupacion de memoria para GP2X y entornos embebidos

te recomiendo el wiki: wiki.gp2x.org

y por el momento haz las cosas en C a pelo e intenta que las rutinillas sean lo mas independientes (usen pocas variables globales) y cortas posibles... porque una vez que GP2X llegue a nuestras manos, lo mas seguro es que halla que dividir el flujo de proceso en 2 'threads' (uno por CPU) y no querras que ocurran interbloqueos y condiciones de carrera debido a usar variables globales que no vienen a cuento...
f5inet escribió:dos cositas:
1- olvida visualC... para desarrollar para GP2X necesitas SDL y funcionara con base a un linux, asi que te recomiendo un linux (ubuntu mismo estaria bien) y Kdevelop si te gusta un IDE grafico o 'motor' si te gusta un IDE texto. digo por ahorrar los maximos problemas futuros. yo estoy usando Kdevelop con soporte C++ y SDL, y ya he hecho un par de ejemplitos


Humm, VisualC solo lo he utilizado para construir la base de codigo.

f5inet escribió:2- usar rutinas de tan alto nivel como getpixel y putpixel en un motor 3D es simplemente una locura, y, no me interpretes mal, una perdida de tiempo. normalmente en un engine 3D la rutina de mas alto nivel que se use es 'drawHline' y 'drawHlinetext' y si acaso 'drawHlinetextblend'. que dibujan lineas horizontales con suavizado gouraud, lineas horizontales con textura, y lineas horizontales con suavizado gouraud, texturadas y mezcladas con canal alpha.


getpixel y putpixel los he usado solo con el codigo de VisualC para poder 'pintar' de forma rapida sin tener que complicarme la vida en algo, que al fin y al cabo, ya está hecho en plataformas PC y donde no me importa un carajo (por así decir) que se pierda tiempo ahí.

En gp32 estoy escribiendo directamente en la memoria de pantalla.

f5inet escribió:para terminar, hay un par de proyectillos que se llama TinyGL y TinySDGL que intentan (y por ejemplo TinySDGL ya lo consigue) proveer un engine OpenGL basico con poca ocupacion de memoria para GP2X y entornos embebidos

te recomiendo el wiki: wiki.gp2x.org


Gracias por la informacion. Lo de TynyGL y TinySDGL, supongo que tendrá los mismos (o peores) problemas a los que yo me estoy enfrentando...

f5inet escribió:y por el momento haz las cosas en C a pelo e intenta que las rutinillas sean lo mas independientes (usen pocas variables globales) y cortas posibles... porque una vez que GP2X llegue a nuestras manos, lo mas seguro es que halla que dividir el flujo de proceso en 2 'threads' (uno por CPU) y no querras que ocurran interbloqueos y condiciones de carrera debido a usar variables globales que no vienen a cuento...


Pues esto que dices, es interesante de verdad. Veamos, me estoy encontrando con un 'ligero' problema y es que, efectivamente, para poder realizar todo lo que me gustaría meter, la velocidad es demasiado lenta, por algún motivo.

En mis calculos internos lo mas 'duro' que usaba es una multiplicacion por un factor , acompañado por su correspondiente desplazamiento (divisor). Digamos que estoy utilizando coma fija en enteros con una proporcion 20:12, que se realizan la mayoria en los desplazamiento de Y (para ajustar cosas como la X correspondiente para cada lado, el color de iluminacion, la Z y la posicion de texturas.


Para intentar ganar velocidad, he utilizado algunas tablas y he observado que no se gana mucho la verdad.

Entonces he hecho la rutina mas basica que he podido, una que simplemente adapte la X y Z y escriba el color y he obtenido una tasa de 8000 poligonos por segundo (cada poligono de los mios, tendra alrededor de 1200 pixeles).

Pero luego he metido un contador para llevar la cuenta de pixeles dibujados en pantalla y por supuesto, tiene que ser una variable global y he aqui la sorpresa: el contador cae a solo 2666 poligonos por segundo, cuando una version bastante mas compleja (con test Z + los calculos necesarios + conversion de color de RBGA32 a BGR16) me da una tasa de 2000 poligonos por segundo. Mucha penalizacion de cache para algo tan sencillo (si declaro la variable como local, no me penaliza nada), aunque lo bueno es que me ha dado una idea de como debo trabajar.
7 respuestas