Foros - Stratos

Programadores => Programación gráfica => Mensaje iniciado por: Marcee en 14 de Enero de 2006, 01:54:27 AM

Título: "sistema De Luces"
Publicado por: Marcee en 14 de Enero de 2006, 01:54:27 AM
 Hola, estoy trabajando con directx 7. Y hace unos dias estoy intentado algo que no me sale, ojala que uds me pueden ayudar.

Le paso a contar.

Estoy intenado hacer un sistema de noche en en mi juego 2D. Este sistema lo he realizado correctamente, la pantalla del juego se oscurese como yo quiero todo bien. Pero lo que no puedo realizar es que se oscurescan en distintas tonalidades dependiendo la parte de la pantalla. Lo que quedaria como un sistema de luces.

Osea lo que yo necesito es que se oscuresca la pantalla del juego  en diferentes tonalidades, por ejemplo que sea todo oscuro y donde se encuentra el personaje sea de un tono mas claro.

Desde ya muchas gracias, espero que me hayan entendido.

Chau.

Título: "sistema De Luces"
Publicado por: [EX3] en 14 de Enero de 2006, 05:10:37 AM
 Estas desarrollando el juego en DirectDraw o en Direct3D? Si estas utilizando la fuerza del hardware mediante Direct3D te seria facil mediante un sprite aplicandole alpha aditivo poder clarecer zonas de la pantalla, tal que este ejemplo:

(http://img486.imageshack.us/img486/2310/alphaaditivo8mh.th.jpg)

Con DirectDraw a secas te va a ser muy costoso tanto en cuestion de implementacion como en cuestion de rendimiento. Con D3D simplemente es montar un poligono con su textura y configurar 4 propiedades para hacer esto.

Salu2...
Título: "sistema De Luces"
Publicado por: Marcee en 14 de Enero de 2006, 06:28:28 AM
 lo estoy haciendo en direct draw :(
Título: "sistema De Luces"
Publicado por: Lord Trancos 2 en 14 de Enero de 2006, 12:18:13 PM
 En un modo de 8bits (con paleta de 256 colores), este tipo de cosas se podian conseguir simplemente con varias paletas y haciendo una transicion progresiva entre ellas.

En un modo de 16 o 32 bits, lo único que se me ocurre es tener varias copias de los tiles o pantallas que forman el escenario a diferentes horas del dia e ir mezclandolas sobre la copia que se use para dibujar. El "truco" estaria en mezclar un tile  diferente cada X ms (o un cacho de imagen), ya que si intentas hacerlo todo de golpe te pegara un paron el juego.
Título: "sistema De Luces"
Publicado por: nostromo en 14 de Enero de 2006, 05:56:08 PM
 Existe un juego con codigo fuente liberado que utilizaba ese tipo de efectos, aqui te dejo el link a un port del codigo con la libreria SDL.

Abuse-SDL

El juego original para MS-DOS se llama Abuse y se publico en 1996. Utilizaba iluminación dinamica con modos de 8bits de color. Con 8bits y por tanto una paleta de 256 colores la técnica para conseguir esto se basa en "tablas de traducción"(o look-up tables). Esta técnica es la misma que utilizaba el Doom para conseguir algo de iluminacion con 256 colores.

Con 8 bits

Digamos que tienes una paleta original de 256 colores y 32 niveles de luminosidad.
Pues necesitas una tabla de 32*256 elementos de 8bits. Llamemosla T. :-)
Cada vez que vas a pintar con luminosidad l un color c haces: nuevo_color = T[l*256+c]
l = 31 es la paleta original, l=0 es con luminosidad 0(es decir, muy oscuro :) )

Es decir esta tabla traduce colores de iluminación normal(paleta original) a colores con iluminación más oscura, y estos colores más oscuros estan todos en la misma paleta original.

Lo "dificil" es calcular la tabla de traducción:

Para cada color c de la paleta original con su (R,G,B) tenemos 32 niveles de lum.
  Para cada nivel de lum. l de 0 a 31
       
       (R2,G2,B2) = CalculaLuminosidad(R,G,B,l)   Buscamos el valor R2,G2,B2 del nuevo color segun lum. l
                                                                              seria algo asi: R2=(R/32.)*l; G2=(G/32.)*l; .....

       c2 = BuscaColorMásParecido(R2,G2,B2)   Busca el color más parecido en la paleta original
       T[l*256+c] = c2


Una vez tienes todo esto, el hacer luces se haria con mapas de luz, es decir, Sprites cuyos pixeles son niveles de luz(las l anteriores).
Los mapas de luz los situas donde te de la gana como con los sprites. Seria algo similar a esto:


Para cada pixel
 l = MapaLuz[sx,sy]   // mapa de luz niveles de 0 a 31
 c = Sprite[ox,oy]   // nuestro bicho
 c2 = T[l*256+c]    // traducción de color
 Pantalla[ sx , sy ] = c2  // pintamos en pantalla


Con esta tecnica se pueden crear efectos de transparencias facilmente. Es más, como la tabla ocupa 32*256=8Kb y se utiliza constantemente será bastante rapido ya que estará almacenada en cache.

En 24bits:
Para el tema de 24bits de color el sistema seria similar solo que esta vez hacen falta 3 traducciones una por cada componente de color. Tendrias la tabla para R, para G y para B. Y harias la traducción de esta forma:
R2 = TR[ R + l*256 ]
G2 = TG[ G + l*256 ]
B2 = TB[ B + l*256 ]

donde R,G,B son los componentes del pixel del sprite y l como siempre el nivel de luminosidad

y donde la tabla TR se pre calcularia asi TR[R + l*256] = (R/32.) * l   y asi para la tabla de verde (TG) y la del azul( TB). asumo que l va de 0 a 31.
La tecnica para hacer luces dinamicas seria la misma que en 8 bits: mapas de luz con niveles de luminosidad.

En fin, espero que te sirvan algunas ideas ó que decidas hacerlo mediante direct3d u opengl.

Un saludo
Título: "sistema De Luces"
Publicado por: Marcee en 14 de Enero de 2006, 07:30:16 PM
 pero lo que me decis funciona para windows ?:S:S
Título: "sistema De Luces"
Publicado por: senior wapo en 14 de Enero de 2006, 10:00:16 PM
 Claro que funcionan, tu haces un lock de la superficie a oscurecer/iluminar, modificas los pixels y luego un unlock. Listo para copiar.

Lo suyo es que cuando cambia la iluminación de la escena modifiques las imagenes que usas para componer la escena sobre copias de dichas superficies y luego sean esas copias modificadas las que uses para la pantalla. No hagas las modificaciones cada frame, solo cuando cambie la iluminación general.
Título: "sistema De Luces"
Publicado por: [EX3] en 14 de Enero de 2006, 10:00:22 PM
 Siendo con SDL hasta para linux y MacOS incluso entre otras muchas plataformas. No existen algorritmos fijos para una plataforma, solo soportes y SDL es multiplataforma e incluso podria serte mas sencillo de programar con el que con DirectDraw.

Salu2...
Título: "sistema De Luces"
Publicado por: Leanz en 14 de Enero de 2006, 11:56:29 PM
 Hola, yo estoy trabajadno con marce...y paso a explicar mas detalladamente....


Anteayer me puso a ver este tema, y bueno logre un efecto de iluminacion, lockeando(Espero q exista:P) las surfaces, tomando el array y multiplicando el valor de los pixels selectivamente con un algoritmo q produce un degrade zonal, el tema de esta manera es la velocidad, los fps se van al tacho de basura y se tilda el juego como dijieron arriba...Mi pregunta es si ustedes conocen una manera mas eficaz.
Título: "sistema De Luces"
Publicado por: senior wapo en 15 de Enero de 2006, 12:29:21 AM
 Hombre, revisa los cuellos de botella tipicos, a saber:

1. Usa superficies en memoria de sistema, no de video. Leer/escribir de memoria de video es leeeento.
2. No apliques esos calculos en cada frame. Precalcula el área una vez y luego la vuelcas en cada frame hasta que cambie (cache de imágenes, vamos).
3. Revisa esas multiplicaciones, que sea en punto fijo (enteros, no coma flotante)  y combina 2 en 1. Vamos, que estas multiplicando valores de 8 bits, el resultado no ocupará más que 16 bits en el peor de los casos. En una variable de 32bits te caben 2 multiplicaciones:

 0xFF * 0x16   y 0xE5 * 0x23 -->  0x00FF00E5 * 0x00160023 y luego desempaquetas...

4. No copies la pantalla entera en cada frame, sino solo las partes que cambian de un frame al siguiente. usa dirty rectangles o micro-tile arrays (googlea).
Título: "sistema De Luces"
Publicado por: Marcee en 15 de Enero de 2006, 02:07:15 AM
 Estamos desarrollandolo en visual basic, y no somos muy expertos en el tema si pudieras darnos un tips mas claros te lo agradeceriamos.

Si hay una dll en un lenguaje mas veloz que emule esta acción nos gustaria saberlo tambien.

Muchas gracias.
Título: "sistema De Luces"
Publicado por: [EX3] en 15 de Enero de 2006, 03:57:08 AM
 
Cita de: "Marcee"Estamos desarrollandolo en visual basic, y no somos muy expertos en el tema si pudieras darnos un tips mas claros te lo agradeceriamos.

Si hay una dll en un lenguaje mas veloz que emule esta acción nos gustaria saberlo tambien.
Entonces ya has dicho suficiente. Si estais programando en VB 6.0 y con DirectDraw olvidaros de calcular las iluminaciones por pixel en tiempo real por que es imposible lograr buenos resultados en cuanto a rendimiento en este lenguaje. Vuestras dos soluciones: Direct3D, ya sea el 7 o el 8 (yo os recomiendo el 8 por multiples ventajas a la hora de programar frente al 7) aprovechando la aceleracion por hardware y desarrollarlo mediante poligonos y texturas, o la dx_lib32 (mirar en mi firma), una libreria que os podria solucionar mucho la vida en VB a la hora de desarrollar un juego. El ejemplo que os plantee arriba esta desarrollado en VB 6.0 con la dx_lib32 y os aseguro que es sencillisimo de hacer. Actualmente me encuentro terminando la documentacion y los tutoriales de la nueva version de dicha libreria, la version 2.0, que sin duda esta mas optimizada y mas completa respecto a la version actual que encontrareis en la pagina, la version 1.03, pero para empezar yo creo que os basta de sobra para ver por encima las funciones y la sencillez de su uso y los resultados que ofrece ;)

Salu2...
Título: "sistema De Luces"
Publicado por: Marcee en 15 de Enero de 2006, 04:35:35 AM
 No hay una dll para directdraw? En otro lenguaje que no sea visual?
Título: "sistema De Luces"
Publicado por: [EX3] en 16 de Enero de 2006, 04:39:11 AM
 Realmente te merece la pena una dll solo para eso pudiendo tener una dll que ofrezca de todo? . . . No se tu, pero puestos a usar una dll, mejor una para todo que 20, no?

DirectDraw no esta preparado del todo para trabajar temas como iluminacion dinamica en tiempo real (juegos como el Abuse que trabajan con DDraw utilizan si no recuerdo mal graficos precalculados), y ya puestos menos a un en un lenguaje lento e interpretado como es Visual Basic. Alternativas mejores sin duda son Direct3D, sobre todo la version 8 en la que con menos codigo incluso puedes hacer las mismas cosas que en DirectDraw usando el doble de llamadas, y este (DDraw) sin aprovechar la potencia de la tarjeta grafica.

La clase grafica de la dx_lib32 esta implementada con Direct Graphics (o Direct3D8) y por medio de simples llamadas puedes hacerte ciertos efectos de iluminacion con suma facilidad ya sea pintando un poligono con degradado de blanco a negro incrementado el valor de opacidad de la figura mediante el canal alfa del color, o utilizando graficos que representen focos de luz o destellos aplicando un efecto de opacidad aditiva, que es el ejemplo que os he mostrado antes en la captura y este es todo su codigo:
Option Explicit

Dim m_GFX As dx_GFX_class 'Variable objeto que apunta a la clase grafica.
Dim m_Input As dx_Input_class 'Variable objeto que apunta a la clase de funciones de entrada.

Dim Render As Boolean 'Variable que controlara la ejecucion del bucle principal.
Dim Backg As Long, Light As Long 'Variables que almacenaran los identificadores de los graficos en memoria.

Private Sub Form_Load()
Me.Show

'Creamos la instancia de las clases de la libreria:
Set m_GFX = New dx_GFX_class
Set m_Input = New dx_Input_class

'Inicializamos la clase grafica y configuramos el modo de video a modo ventana:
Call m_GFX.Init(Me.hWnd, 640, 480, 32, True, False, False)

'Inicializamos la clase de funciones de entrada, donde se encuentran las rutinas para leer
'la entrada del teclado y el raton:
Call m_Input.Init(Me.hWnd)

'Cargamos los graficos en memoria:
Backg = m_GFX.MAP_Load(App.Path & "\abadia.jpg", 0)
Light = m_GFX.MAP_Load(App.Path & "\luz.png", 0)

Render = True

'Bucle principal del programa:
Do While Render
   'Si pulsamos la tecla escape o el boton izquierdo del raton salimos del bucle:
   If m_Input.Key(Key_Escape) Or m_Input.Mouse.Left_Button Then Render = False
   
   'Pintamos el fondo con el primer grafico con algo de oscuridad:
   Call m_GFX.DRAW_MapEx(Backg, 0, 0, 0, m_GFX.Screen.Width, m_GFX.Screen.Height, 0, Blendop_Color, m_GFX.ARGB_Set(255, 128, 128, 128), Mirror_None, Filter_Bilinear, False, 0, 0)
       
   'Pintamos el grafico que actuara como foco aplicandole la opcion de Opacidad Aditiva:
   Call m_GFX.DRAW_MapEx(Light, m_Input.Mouse.X, m_Input.Mouse.Y, 0, 0, 0, 0, Blendop_Aditive, m_GFX.ARGB_Set(255, 255, 255, 255), Mirror_None, Filter_Bilinear, True, 0, 0)
   
   'Procesamos todas las llamadas a la clase grafica y las mostramos en pantalla:
   Call m_GFX.Frame

Loop

'Destruimos las instancias de las clases de la libreria:
Call m_GFX.Terminate
Call m_Input.Terminate

'Terminamos el programa:
End

End Sub

Private Sub Form_Unload(Cancel As Integer)
'Si cerramos la ventana salimos del bucle principal:
Render = False

End Sub

Y no me digas que esto es dificil. Casi toda la forma de programar con la libreria es asi de sencilla.

En serio, no os empeñeis en hacer algo "bruto" con DDraw por que solo seran quebraderos de cabeza, y si os empeñais mejor pasaros a C++, que al menos ahi obtendreis mas rendimiento que en VB.

Salu2...
Título: "sistema De Luces"
Publicado por: Loover en 16 de Enero de 2006, 11:15:47 AM
 ¿Usais Visual Basic y no estais usando la dx_lib32? ¡Fustigales [EX3]! O fustigate tu mismo por no hacer buena publicidad de tu peazo librería.

:D
Título: "sistema De Luces"
Publicado por: nostromo en 16 de Enero de 2006, 01:53:16 PM
 Solo unas puntualizaciones,

Abuse se hizo en MSDOS por lo tanto no esta hecho con DirectDraw, es curioso ver los requerimientos minimos que tenia:  un 486DX a 50 MHz.
Abuse en Wikipedia

Utilizan mapas de luz precalculados, pero estos mapas de luz se pueden mover/activar dinamicamente a cualquier punto del mapa en cualquier momento del juego(ejemplo: rafagas de luz por disparos etc...).

El rollo que solté unos post más arriba(con la técnica que se utiliza para hacer esto rapido) asumia que al final esto se implementaba con C y que el bucle más interno que renderizaba una linea de sprite(por ejemplo) se implementaba en ASM. Si se hace bien no tengo duda que sin tarjeta grafica 3d y con unos requerimientos pequeñisimos funciona perfectamente.

Creo que me equivoque asumiendo que nuestros amigos sabian o les interesaba C y ASM para hacer estas cosas. Mis disculpas.

Y muchos pensaran: "Y este calentamiento de cabeza en los tiempos que corren ¿para que?". Pues por un lado para ver como se hacian las cosas antes con poca maquina. Por otro lado todo depende de la maquina objetivo para la que queramos hacer las cosas, no todo el mundo tiene una tarjeta grafica 3d. Ademas estas técnicas nos permiten hacer cosas interesantes en los dispositivos que "no son tan rapidos" como un movil symbian, pocket pc, palm etc... ampliando nuestro mercado. Estos dispositivos no tan rapidos suelen tener minimo un procesador ARM a 100Mhz como poco y sin embargo veo algunos juegos/emuladores que no van todo lo rapido/fluidos que podrian ir.

Y dejando atrás la última reflexión, si lo que se quiere es hacer algo para las maquinas actuales pues desde luego es una buena inversión aprender DirectGraphics/OpenGl y olvidarnos de lo anterior.

Un saludo a todos.
Título: "sistema De Luces"
Publicado por: [EX3] en 17 de Enero de 2006, 02:22:03 AM
 
Cita de: "nostromo"Solo unas puntualizaciones,

Abuse se hizo en MSDOS por lo tanto no esta hecho con DirectDraw, es curioso ver los requerimientos minimos que tenia:  un 486DX a 50 MHz.
Abuse en Wikipedia
El Abuse que yo tengo es version Win32 con DirectDraw6 o 5 creo. No sabia que existia una version anterior aun :ph34r:

Cita de: "Loover"¿Usais Visual Basic y no estais usando la dx_lib32? ¡Fustigales [EX3]! O fustigate tu mismo por no hacer buena publicidad de tu peazo librería. :D
Te parece poca publicidad la que hago? :P No se, pero si estan empeñados en programar en Visual Basic que al menos echen un vistazo a la libreria, que de seguro les va a ahorrar mucho tiempo de desarrollo en multitud de cosas, sobre todo con la nueva version que esta a puntito de caer, y mas aun si son principiantes. Al menos asi veran resultados sin mucho esfuerzo, que eso anima en muchos casos.

Salu2...
Título: "sistema De Luces"
Publicado por: marcode en 17 de Enero de 2006, 10:05:00 AM
 DirectDraw7 permite usar paletas de color.

Puedes crear varias paletas con tonalidades mas oscuras y asociarlas a la surface cuando sea necesario con SetPalette.