Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Leer El Color De Un Pixel En Direct Graphics

Iniciado por [EX3], 05 de Agosto de 2003, 03:22:42 AM

« anterior - próximo »

[EX3]

 Nas:

Me estoy comiendo la cabeza buscando la forma de leer el color de un pixel de una textura almacenada en memoria con las DirectX8. En DirectDraw habia una funcion que te devolvia el codigo del color del pixel (GetPixel()), pero en Direct Graphics no he encontrado ninguna funcion similar.

¿Alguien puede explicarme de forma clara como puedo leer un pixel de una textura en Direct Graphics?

Gracias.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

BeRSeRKeR

 Lo que necesitas es bloquear la textura (IDirect3DTexture8) con el método LockRect que tiene la siguiente definición:

HRESULT LockRect(
 UINT Level,
 D3DLOCKED_RECT* pLockedRect,
 CONST RECT* pRect,
 DWORD Flags
);


En ella, pLockedRect contiene un miembro llamado pBits que es un puntero al comienzo de la superficie, es decir, apunta al primer pixel. Con él ya puedes recorrer toda la textura y modificarla si quieres.

Una vez que hayas modificado tu textura, no se te olvide llamar al método UnlockRect.

Mírate la ayuda de DirectX para más información.

Saludos
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

[EX3]

 A ver, ke hace tiempo ke esto no lo he tocado. Segun me has dicho pBits es el puntero al primer pixel de la superficie, eso kiere decir que pBits devuelve el color del primer pixel? Si es asi, me devuelve un valor incorrecto al del color leido.

Para leer correctamente los pixeles no habra que utilizar algun array? Si es asi podrias explicarme como, por ke en el sdk no he visto ningun ejemplo que lo haga y de internet baje un ejemplo un tanto extraño que me ha liado mas aun  :(

Gracias.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Zaelsius

Cita de: "[EX3"] Segun me has dicho pBits es el puntero al primer pixel de la superficie, eso kiere decir que pBits devuelve el color del primer pixel?
...
Para leer correctamente los pixeles no habra que utilizar algun array? Si es asi podrias explicarme como...
Creo que deberías repasar un poco el tema de punteros en C++ :rolleyes:  ... no tiene sentido que te pelees con DirectX si aun no dominas lo suficiente el lenguaje.

Veamos, el puntero devuelto marca el comienzo del área de memoria donde está almacenada la textura. Por eso el puntero apunta al primer píxel. Si incrementas el puntero accederás al 2º píxel, etc. Aun así, debes tener en cuenta cosas como el formato de la textura(una vez en memoria, ya que puede ser diferente al formato que tenia en el archivo), y que tampoco se puede recorrer linealmente de principio a fin toda la textura(mira la documentación de LockRect() y D3DLOCKED_RECT para saber a que me refiero).

Hope this helps  :P  

[EX3]

 
CitarCreo que deberías repasar un poco el tema de punteros en C++  :rolleyes:  ... no tiene sentido que te pelees con DirectX si aun no dominas lo suficiente el lenguaje.
xD quien ha hablado de C++?, yo de siempre he programado en VB!, weno, tampoco lo dije  ^_^  (al menos en este post, claro). Siempre dais por sentado ke todo el mundo trabajamos en C++, algunos somos mu perros para meternos a ello  :D

Weno, lo de los punteros hace tiempo ke no lo toco (el mismo ke no toco C++, usease mucho  :( ) pero si recuerdo vagamente ke son direcciones a zonas de memoria. Me imagino ke el incremento seria algo como la coordenada X de la textura y si Pitch es el ancho de la textura, cuando X = Pitch seria igual que Y = 1, mas o menos, no? Yo mi problema es ke veo pBits y no veo claramente como sacarle la informacion del pixel, por eso pregunte lo del array, eske en el ejemplo ke mencione (akel ke me lio mas aun) hacian una cosa como esta:
Dim pData As D3DLOCKED_RECT
Dim pxArr() As Byte

       'we can now play around with the stuff in pData
       ReDim pxArr(pData.Pitch * 128) As Byte 'enough bytes
       If Not (DXCopyMemory(pxArr(0), ByVal pData.pBits, pData.Pitch * 128) = D3D_OK) Then Debug.Print "COPY TO ARRAY FAILED"
Va por buen camino esto o no tiene nada ke ver???

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

BeRSeRKeR

 En el SDK de DX de C++ tienes varios ejemplos que utilizan LockRect. Por ejemplo existe uno llamado "DotProduct3" que genera un normal map "on the fly" por lo que pilla la textura, la bloquea y la rellena. Supongo que tendrá su equivalente en la parte de Visual Basic del SDK (la cual no tengo instalada). Así que tal vez ese ejemplo te pueda ayudar.

Suerte
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

fiero

www.videopanoramas.com Videopanoramas 3D player

Zaelsius

 No quiero ser pesao... pero usar VB con DX es "mu malo"  :P
No comprendo como te puede dar pereza aprender C++, y no DirectX...  :huh:

Yo tambien di mis primeros pasos con DX con VB5, y me bastó un mes para darme cuenta que no valia la pena romperme la cabeza con VB... casi me atrevería a decir que es más fácil/sencillo usar C++ para estos temas..

Sobre la información de pixel: si tienes una textura de 32 bits, pues cada pixel ocupa 4 bytes(32 / 8 = 4), un byte para cada componente de color -Alpha,Red,Green,Blue(el orden puede cambiar). Si tienes una textura de 16 bits pues obviamente la estructura cambia, normalmente se tienen 5 bits para cada componente y en algunas tarjetas uno de ellos tiene 6. Es decir: RGB -> 555 ó 565 , etc...

Yo considero este tema demasiado "complejo" como para afrontarlo desde VB, no porque no se pueda, sino pq si eres capaz de usar DX adecuadamente y afrontar esta clase de problemas, tb serás totalmente capaz de hacerlo desde  C++.


synchrnzr

 
Citar¿Pero en VB existen los punteros?

Hace ya tiempo (años :P) eché una mano a una compi de la Uni con un programa que estaba haciendo en VB y creo recordar que los hay. A lo mejor no salen con esa palabra, pero algo hay que es lo mismo, seguro :)

sync

[EX3]

 BeRSeRKeR: En el sdk de DirectX para VB faltan mas de la mitdad de los ejemplos que vienen en C++, entre ellos el que tu mencionas  :(

ZaelSiuS: Llevo 2 años y medio trabajando con DirectX sobre VB (2 de ellos con Direct Draw) y estoy muy contento con los resultados que me esta dando, y no niego ke esos resultados sean inmensamente mejores en C++ (dios me libre de decir lo contrario xD), pero no voy a abandonar un proyecto con el ke llevo tanto tiempo para ahora pasarme a C++, un lenguaje donde ahora mismo no se hacer ni la mitad de las cosas que hago en VB.

No es que me de pereza aprender C++ (weno, un poco si  :P) pero como me apaño bien de momento con VB no veo ninguna razon, de momento, que haga migrar a C++. Ahora, eso no quita que yo no quiera aprender C++, es una tarea que llevo pendiente desde hace cierto tiempo.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

Juan Mellado

 [EX3], supongo que el código lo has tomado de este tutorial:
http://216.5.163.53/DirectX4VB/Tutorials/D...GR_Lesson14.asp
La verdad es que el tutorial es bastante completo (recomiendo ver la web completa), leélo con detenimiento y verás como contiene todo lo que te hace falta para tratar las texturas en memoria.

Por si te sirve, he comentado en español una parte:

Dim pData As D3DLOCKED_RECT, pxArr() As Byte

'Bloquea la textura (TexDMA es la textura, CreateTextureFromFile o lo que sea)
TexDMA.LockRect 0, pData, ByVal 0, 0

'Reserva memoria para copiar en ella la textura (128 = altura textura)
ReDim pxArr(pData.Pitch * 128) As Byte

'Copia la textura a la memoria reservada
DXCopyMemory pxArr(0), pData.pBits, pData.Pitch * 128

'Aquí ya puedes acceder a los pixels en memoria
For x = 0 To (pData.Pitch * 128) - 1 Step 4

'Modo lectura
  bRed = pxArr(x + 2)
  bGreen = pxArr(x + 1)
  bBlue = pxArr(x + 0)

'Modo escritura
  pxArr(x + 2) = bRed
  pxArr(x + 1) = bGreen
  pxArr(x + 0) = bBlue

Next x

'Copia desde la memoria a la textura
DXCopyMemory ByVal pData.pBits, pxArr(0), pData.Pitch * 128

'Libera la textura
TexDMA.UnlockRect 0

Eso sí, como dice Zaelsius (y el tutorial), depende del tamaño y el formato de la textura que estes utilizando. Este ejemplo utiliza una textura de 128 pixels de altura y un formato BGRX.

pxArr es un puntero al área de memoria en bytes, por lo que para ese formato:
pxArr(0) contiene el componente B del primer pixel
pxArr(1) contiene el componente G del primer pixel
pxArr(2) contiene el componente R del primer pixel
pxArr(3) contiene el componente X del primer pixel

pxArr(4) contiene el componente B del segundo pixel
pxArr(5) contiene el componente G del segundo pixel
....

El contenido de la memoria debe interpretarse en función del tamaño y formato de la textura, leete con calma el tutorial.

Citar
Me imagino ke el incremento seria algo como la coordenada X de la textura y si Pitch es el ancho de la textura, cuando X = Pitch seria igual que Y = 1, mas o menos, no?
Exacto.

Espero te sirva.
Saludos

[EX3]

 
Citar[EX3], supongo que el código lo has tomado de este tutorial:
http://216.5.163.53/DirectX4VB/Tutorials/D...GR_Lesson14.asp
Si señor, el mismo ^_^. La verdad, eske no he encontrado mas tutos como este por la red, asi ke poco tenia donde elegir jeje

CitarpxArr es un puntero al área de memoria en bytes, por lo que para ese formato:
pxArr(0) contiene el componente B del primer pixel
pxArr(1) contiene el componente G del primer pixel
pxArr(2) contiene el componente R del primer pixel
pxArr(3) contiene el componente X del primer pixel

pxArr(4) contiene el componente B del segundo pixel
pxArr(5) contiene el componente G del segundo pixel
....
Ahora si lo entiendo, en el caso de ser el formato XRGB (32Bits) son 4 bytes por pixel y en RGB(24 y 16 Bits) son 2 (al menos segun el ejemplo antes mencionado), ahi tenia el problema, ke no sabia como interpretar los datos de pxArr(), yo pensaba ke devolveria un valor unico como color. Ahora si llego a entender el funcionamiento del tutorial.

Muchas a gracias a todos por la ayuda  :lol:

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.