Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Color transparente

Iniciado por McBain, 13 de Junio de 2006, 01:40:29 PM

« anterior - próximo »

sés

Cita de: "zupervaca"
Yo no asumo nada, ¿has hecho rutinas graficas en asm en la epoca de ms-dos o en otras plataformas? una comprobacion era mucho mas lenta que usar operaciones para pintar una imagen con mascara de color.
En esa época del MS-DOS... ¿exactamente qué operación era más rápida que un TEST AL,AL?
Soy indeciso... ¿o no?

Jare

Cita de: "MA"Si encuentras algún hardware que SI soporte Alpha Blending y NO soporte Alpha Test, dejaré de escribir en estos foros para siempre...
¿Quieres uno? La S3 Virge. Aaaaadiooosss! ;)

De hecho, los drivers D3D de la S3 Virge *emulaban* Alpha Testing activando en su lugar Alpha Blending, lo que nos dio no pocos quebraderos de cabeza, porque los pixels transparentes por Alpha Testing no escriben en el ZBuffer, pero los transparentes por Blending si. Hablamos de 1997... en el 98 ya era infrecuente que juegos comerciales se molestasen en soportar la Virge. O sea que no es lo que se dice muy relevante.

A día de hoy se asume que el Alpha Testing existe y funciona realmente como debe, porque es muy útil y se usa en practicamente todos los motores gráficos.

zupervaca

CitarEn esa época del MS-DOS... ¿exactamente qué operación era más rápida que un TEST AL,AL?
Lo mas rapido en ms-dos para pintar imagenes con mascara es no comprobar nada, solo pintar lo necesario :P

No obstante pasate por esta web por ejemplo, hay muchas mas solo es cuestion de buscar en google: http://andercheran.upv.es/~amstrad/docs/sprites.html

sés

Cita de: "zupervaca"
CitarEn esa época del MS-DOS... ¿exactamente qué operación era más rápida que un TEST AL,AL?
Lo mas rapido en ms-dos para pintar imagenes con mascara es no comprobar nada, solo pintar lo necesario :P
Ya sé que se pueden utilizar sprites comprimidos para evitar esas comprobaciones, pero aquí se está hablando de usar un "color transparente".


Cita de: "zupervaca"una comprobacion era mucho mas lenta que usar operaciones para pintar una imagen con mascara de color
Ya que hablamos de usar un "color transparente" y de "máscaras de color" (nada de sprites comprimidos, precompilados, etc.), repito mi pregunta: ¿Qué operación utilizabas que fuese más rápida que un TEST?

Si, cómo tú mismo dices, usas "mascara de color", ¿cómo comprobabas esa máscara?
Soy indeciso... ¿o no?

MA]Mestre

Cita de: "zupervaca"Yo no asumo nada, ¿has hecho rutinas graficas en asm en la epoca de ms-dos o en otras plataformas? una comprobacion era mucho mas lenta que usar operaciones para pintar una imagen con mascara de color.

Pos va a ser que he hecho unas cuantas rutinas en la época de ms-dos... ...pero el haber hecho o estar haciendo, no da más fuerza ni más rigor ni más prestigio a mis palabras... por lo demás, espero la respuesta a la pregunta de sés.

MA]Mestre

Cita de: "[EX3"] todos los ejemplo tiran de Blending para hacer alphablending y asignacion de color transparente o Colorkey en la textura"

Para hacer alphablending es lógico tirar de blending. Nunca he dicho lo contratio. Ahora que para hacer un color transparente usen Blending, es una estupidez. Y me la pela que salga en los SDK de Microsoft, yo, como creo que deberiais tener todos, tengo mi criterio propio y critico todo lo que me parece una estupidez... por mucho MS que sea...

...por ejemplo, los ejemplos del SDK de DirectxShow de MS hacen servir la instrucción "goto"... ...que debo pensar sobre ello ? que es una estupidez ? o me sumo al carro ?

cual es la finalidad del Alpha Test ? cual es su proceso interno ? en que posicion de la cadena del pipeline esta situado ?

Ahora haceros las mismas preguntas para el Alpha Blending... ...y después con VUESTRO CRITERIO... responder si para hacer un pixel trasparente o no... se deberia usar una técnica o la otra...

Para el yogourth la cuchara, para las patatas el tenedor.

MA]Mestre

Cita de: "Jare"¿Quieres uno? La S3 Virge. Aaaaadiooosss! ;)

De hecho, los drivers D3D de la S3 Virge *emulaban* Alpha Testing activando en su lugar Alpha Blending, lo que nos dio no pocos quebraderos de cabeza, porque los pixels transparentes por Alpha Testing no escriben en el ZBuffer, pero los transparentes por Blending si. Hablamos de 1997... en el 98 ya era infrecuente que juegos comerciales se molestasen en soportar la Virge. O sea que no es lo que se dice muy relevante.

A día de hoy se asume que el Alpha Testing existe y funciona realmente como debe, porque es muy útil y se usa en practicamente todos los motores gráficos.

Qua adios más entusiasta.  :lol:

He estado buscando las Specs Técnicas de la S3 Virge, no las he econtrado... pero sin ellas y sin dudar de tu palabra, dire que:

a) OpenGL desde su primera version 1992-1997 soporta Alpha Test y Alpha Blending ( no con todas las combinaciones de ahora ).

b) OpenGL, nunca ha especificado que estas opciones son dependientes del hardware. Que raro, no ? Pq DirectX en su documentación del SDK del summer 2003 si lo pone ? lo pone en el SDK actual ?  :wink:

c) La S3 Virge no soportaba OpenGL entonces ? aun que varias personas de S3 por entonces tomaban parte y voto en las reuniones de la ARB ? :roll:

d) Que es más complicado desde el punto de vista técnico ? implementar un Alpha Test o un Alpha Blending ? Cual de las dos técnicas es más rápido de computar ?

senior wapo

estooo.... todas las funciones de OpenGL estarán implementadas siempre en un driver bien hecho, el problema es que lo que no esté soportado por hardware lo estará por software y será probablemente inutilizable en tiempo real a efectos prácticos.

sobre tus preguntas:

b) Opengl fuerza todo a estar presente mediante fallback software si no fuese posible por hard. DirectX no obliga a nada ya que entiende que una implementación software podría ser poco util. Lo suyo es que la aplicación consulte y utilice solo las funciones implementadas por hard si requiere velocidad. (familia GetCaps en DX y GetInteger()+bases de datos basadas en vendor string en OpenGL).

c) Soportase OpenGL o no, era la época negra de la programación OpenGL en windows (y si me apuras de DX también, pero de OpenGL mejor ni hablar). Dejémoslo correr :D

d) Por software, alpha test es potencialmente más rápido al ser simplemente una comparación. Blending implica hacer una mezcla de color (por ejemplo una media ponderada mediante alpha de la textura).

 alpha test:  if (framebuffer[x,y].alpha > texel.alpha) then framebuffer[x,y] = texel
 blending:  framebuffer[x,y].pixel = framebuffer[x,y].pixel * (1-texel.alpha) + texel.pixel * texel.alpha


Es pseudocódigo y asume que tu alpha test es MAYORQUE y blending es el INVSRCALPHA para destino y SRCALPHA para origen. Es sólo un ejemplo de complejidad no una comparativa del mismo resultado con diferente método.

zupervaca

Veamos ¿por que tengo que defender lo que dice la documentacion de direct3d? El que contradiga a la documentacion que busque el informacion y la ponga aqui y pierda su tiempo, ya estoy cansado de que como lo digo yo esta mal o es mentira, asi que buscar vosotros la informacion para decir que lo que yo digo y la pone la documentacion de direct3d sobre alpha testing es mentira, yo paso de perder tiempo en demostrar algo que esta mas que claro, pero como siempre lo que decis vosotros tiene que ir a misa.

Editado: No habia leido todos los posts, para ses con el rollu del test que creo que no sabe muy bien lo que esta diciendo, veamos, el test se puede ejecutar muy rapido pero lo que es el jnz, jz, etc NO, mas rapido que este sistema es tener un bitmap de color y otro bitmap de mascara, despues con un AND y un OR se hace todo lo necesario para pintar una imagen transparente, eso si es mas rapido que el TEST y su SALTO, ademas es como se ha hecho toda la vida, espero que te haya quedado claro y si no busca en google como hacer mascara de color con estas dos instrucciones en google.

_Grey

no lo pude resistir... POST MADE IN STRATOS! lo hice...

La que podéis montar por una cuestión de colorkey....

No puedo evitar sumarme a la bronca, en la era MSDOS, si color del pixel del  sprite a "dibujar" == a colorkey, pues no se pinta!!! que porras mascaras!! modernos mas que modernos!! :mrgreen:

Desde aquel post de MA]Mestre, en que decía que respondíamos como si lo supiéramos todo... me esperaba algo así... :?

Pasando al tema del post: McBain no pones mucha información... pero supongo que estarás dibujando a base de polígonos, usando Direct3D... mas que nada por que ya no existe DirectDraw :mrgreen: ,a estas alturas muchos usan blending... mas que nada por todos hemos ido a las 3D antes que ninguna otra cosa, por que molan mas hay que reconocerlo, los que saben algo mas y bucean por la documentación descubren al alphatest, pero como sigue haciendo falta un valor de alfa, pues siguen tirando de blending... mas que nada para aprovechar y usar ese valor para transparencias de todo tipo....

Y después de esto están los que saben mas aun, y usan colorKey por que AUN funciona. Con la desaparición de DirectDraw, y la necesidad de hacer gráficas 2D a trabes de Direct3D se a ido perdiendo, pero esta ahí, la respuesta de MA]Mestre es correcta, y ni siquiera yo pensaba en la posibilidad de usar colorKey a estas alturas con Direct3D :oops:

Por otro lado con el segundo msg de McBain es evidente que no usa polígonos para dibujar sus sprites.... que me lol, aun esta leyendo alguien!?¿!?!? MacBain si ves la documentación veras que StretchRect no es lo que necesitas, de hecho la solución de zupervaca no te funciona por que entiende que usas poligonos para dibujar tus sprites!!!!

PD.: Si, el tamaño es a propósito :mrgreen:

Ruben

[offtopic]
te voy a pasar la factura del oftalmologo...
[/offtopic]

zupervaca

Citarla respuesta de MA]Mestre es correcta, y ni siquiera yo pensaba en la posibilidad de usar colorKey a estas alturas con Direct3D
Ni tu ni nadie por la sencilla razon de que el alpha testing descarta pixels con el problema de que no suaviza los bordes como hace el alpha blending, es decir, veras que donde comienza la zona transparente de la imagen habra un corte en seco, en cambio con alpha blending esto no sucede ya que hace un suavizado ya que todos los pixels se tienen en cuenta, no se si me explico bien, pero a estas alturas tener imagenes con bordes cuadriculados no pega mucho con modernidad.

[EX3]

Cita de: "MAMestre"]Para hacer alphablending es lógico tirar de blending. Nunca he dicho lo contratio. Ahora que para hacer un color transparente usen Blending, es una estupidez. Y me la pela que salga en los SDK de Microsoft, yo, como creo que deberiais tener todos, tengo mi criterio propio y critico todo lo que me parece una estupidez... por mucho MS que sea...
Yo no estoy hablando especificamente de alphablending aunque lo haya mencionado, estoy hablando que los tutoriales basicos que encuentras en internet fuera del SDK o webs de M$ que te enseñan a usar el colorkey de una textura lo hacen por medio de Blending y no de AlphaTest y tiene su 'logica y razon'. Sobre criterio, estoy totalmente deacuerdo contigo, solo que mi criterio en estos casos actua mas sobre compatibilidad que sobre 'el metodo correcto y mas eficiente', prefiero que mis programas garanticen que van a funcionar en cualquier equipo a encontrarme luego que por usar 'el metodo correcto y mas eficiente' no lleguen a funcionar en otros equipos por que el hardware no soporta esa feature ;) Esto me recuerda a las incontables features que tenia DirectDraw (no Direct3D7) como uso de canal alpha o el zbuffer cuando no existia tarjeta alguna que soportase features como esa en algo que no fuera 3D :lol: Vale que el AlphaTest a dia de hoy es dificil encontrar una tarjeta que no lo soporte pero sigue teniendo su 'logica y razon' de por que no se usa tanto como el Blending.

Cita de: "MAMestre"]...por ejemplo, los ejemplos del SDK de DirectxShow de MS hacen servir la instrucción "goto"... ...que debo pensar sobre ello ? que es una estupidez ? o me sumo al carro ?
Perdon!?? :lol: Reconozco que no he mirado todos los tutoriales del SDK sobre DirectShow pero los pocos que he visto jamas he visto un Goto :P No osbtante dime que tutorial es que le eche un ojo, que no me extrañaria encontrame algo asi xD

Cita de: "MAMestre"]Ahora haceros las mismas preguntas para el Alpha Blending... ...y después con VUESTRO CRITERIO... responder si para hacer un pixel trasparente o no... se deberia usar una técnica o la otra...
Y digo yo, no es un poco estupida toda esta cuestion que estas formando con el AlphaTest? No has pensado que luego McBain querra aplicar AlphaBlending? Para que vas a implementar AlphaTest y Blending cuando con Blending cubres las dos necesidades? Ahi tienes la 'logica y razon' de por que se usa y recomienda Blending y no AlphaTest en la mayoria de tutoriales de toda la red.

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

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

Jare

Cita de: "MAMestre"]b) OpenGL, nunca ha especificado que estas opciones son dependientes del hardware
[...]
d) Que es más complicado desde el punto de vista técnico ? implementar un Alpha Test o un Alpha Blending ? Cual de las dos técnicas es más rápido de computar ?
Puedes creerme, yo sí he tenido en mis manos las especificaciones de la Virge bit a bit y registro a registro. Y sobre todo, he trabajado con ella.

Ya han explicado que la especificación de OpenGL exige un fallback software que, aunque funcional, probablemente no de el rendimiento exigido. Alpha Test en general es más rápido de ejecutar que un blend, pero alpha test en software será más lento que blend por hardware. :P Como dice zuper, el test genera bordes "duros" que pueden quedar muy feos, pero el blending tiene su propio conjunto de problemas: ordenación y multipass son los más clásicos. El tercer problema clásico (y el que más quebraderos de cabeza me dio en su momento) es el hecho de que con blending, los texel transparentes también escriben en el ZBuffer.

Hoy en día lo del ZBuffer se suele resolver activando blending Y testing a la vez, aunque suelen quedar unas babas un poco feas alrededor del gráfico. Lo de la ordenación se puede abordar o bien exigiendo una PowerVR (juas), o usando algún truco sucio como el de Tom Forsyth de hacer una pasada con alpha y otra con blending sin escribir la Z. Esto último no funciona bien en todos los casos, pero cuando lo hace parece de verdad.

McBain

Antes nada, decir que gracias por todos que os habeis interesado en contestarme. Siento no haber contestado antes, pero es que ayer estaba de examenes. No me imaginaba que el tema del color keying diera tanto que hablar.
He hecho una serie de cambios en el código, antes trabajaba con Offscreen Plain Surfaces, y segun he leído en los mensajes he de trabajar con Textures, también segun lo que he leído, he de trabajar con el D3DXSPRITE.
Respecto a mi código, quizás es un poco raro (y se podrían mejorar muchas cosas supongo, tengo la manía de hacer la implementación de algunos métodos dentro del fichero *.h para que sean inline). Se tratan de dos clases una llamada Graphic y otra llamada Sprite. La primera se encarga de inicializar D3D, el Device, y D3DXSPRITE (en un método llamado Init). Esta es friend de Sprite, y cuando termina el método Init pone el valor del miembro engine (static) de Sprite a this (he hecho para no tener que pasar el device siempre como parametro). En cuanto a la clase sprite, esta se encargaría de cargar una imagen del disco duro y ponerla en pantalla, siendo el color transparente por ejemplo el rosa chillón (algo que tal vez se cambia a un color por parametro).
Aqui esta el  código:

Graphic.h

#pragma once


#define GFULL   D3DFMT_X8R8G8B8
#define GWINDOW D3DFMT_UNKNOWN

class Graphic
{
friend class Sprite;
public:
Graphic(void);
bool Init(HWND hWnd,bool Windowed,int sizeX,int sizeY,D3DFORMAT Format=D3DFMT_UNKNOWN);
void Release(void);
void Clear(D3DCOLOR Color)
{
pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET,Color, 1.0f, 0 );
}
void Render(void)
{
HRESULT hr;
pd3dSprite->End();
pd3dDevice->EndScene();
//if(backbuffer)
//{
// backbuffer->Release();
// backbuffer=NULL;
//}
hr=pd3dDevice->Present(NULL,NULL,NULL,NULL);
if(FAILED(hr)) ::OutputDebugString("ERROR: Present");
}
D3DFORMAT Format(void) const
{
return format;
}
void Prepare(void)
{
HRESULT hr;

//hr=pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&backbuffer);

hr = pd3dDevice->BeginScene();
if(FAILED(hr)) ::OutputDebugString("ERROR: Begin Scene");
pd3dSprite->Begin(D3DXSPRITE_ALPHABLEND);
}
~Graphic(void);
private:
LPDIRECT3D9 pD3D;
LPDIRECT3DDEVICE9 pd3dDevice;
LPDIRECT3DSURFACE9 backbuffer;
LPD3DXSPRITE pd3dSprite;
D3DFORMAT format;
int SizeX,SizeY;
};


Graphic.cpp

#include "Engine.h"

Graphic::Graphic(void)
{
pD3D=NULL;
pd3dDevice=NULL;
backbuffer=NULL;
pd3dSprite=NULL;
SizeX=SizeY=0;
ZeroMemory(&format,sizeof(D3DFORMAT));
}

Graphic::~Graphic(void)
{
Release();
}

void Graphic::Release(void)
{
if(pD3D)
{
if(pd3dDevice)
{
if(pd3dSprite)
{
pd3dSprite->Release();
pd3dSprite=NULL;
}
pd3dDevice->Release();
pd3dDevice=NULL;
}
pD3D->Release();
pD3D=NULL;
}
}

bool Graphic::Init(HWND hWnd,bool Windowed,int sizeX,int sizeY,D3DFORMAT Format)
{
HRESULT hr;
D3DPRESENT_PARAMETERS d3dpp;

pD3D=Direct3DCreate9(D3D_SDK_VERSION);
if(!pD3D) return false;

ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = Windowed;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
format=((Windowed)?(D3DFMT_UNKNOWN):(Format));
d3dpp.BackBufferFormat = Format;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferHeight = sizeY;
d3dpp.BackBufferWidth = sizeX;
d3dpp.hDeviceWindow = hWnd;
SizeX=sizeX;
SizeY=sizeY;
hr = pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&pd3dDevice);
if(FAILED(hr))
{
Release();
return false;
}
hr = D3DXCreateSprite(pd3dDevice, &pd3dSprite);
if(FAILED(hr))
{
Release();
return false;
}
Sprite::engine=this;
Sprite::SizeX=sizeX;
Sprite::SizeY=sizeY;
return true;
}



Sprite.h

#pragma once

class Sprite
{
friend class Graphic;
public:
Sprite(void);
bool Load(const char * File);
void Release(void);
~Sprite(void);
void X(int nx)
{
x=nx;
};
int  X(void)  {return x;};
void Y(int ny)
{
y=ny;
};
int  Y(void)  {return y;};
int  Height(void)  {return height;};
int  Width (void)  {return width;};
void Draw(void)
{
//if(engine->backbuffer)
//{
engine->pd3dSprite->Draw(texture,&rect,&D3DXVECTOR3(width/2,height/2,0),&D3DXVECTOR3(x,y,0.0f),0xFFFFFFFF);
//}
}
static int SizeX,SizeY;
protected:
RECT rect;
int x,y;
int width;
int height;
LPDIRECT3DTEXTURE9 texture;
static Graphic *engine;
};


Sprite.cpp

#include "Engine.h"

int Sprite::SizeX=0;
int Sprite::SizeY=0;
Graphic * Sprite::engine =NULL;

Sprite::Sprite(void)
{
texture=NULL;
rect.bottom=0;
rect.left=0;
rect.right=0;
rect.top=0;
x=y=0;
width=height=0;
}

Sprite::~Sprite(void)
{
Release();
}

bool Sprite::Load(const char *File)
{
HRESULT hr;
D3DXIMAGE_INFO imageInfo;
hr = D3DXCreateTextureFromFileEx(Sprite::engine->pd3dDevice,File,D3DX_DEFAULT,
D3DX_DEFAULT,D3DX_DEFAULT,D3DUSAGE_RENDERTARGET ,D3DFMT_UNKNOWN,
D3DPOOL_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT,D3DCOLOR_XRGB(255,0,0),
&imageInfo,NULL,&texture);
if(FAILED(hr))
return false;
rect.top=0;
rect.left=0;
rect.right=imageInfo.Width;
rect.bottom=imageInfo.Height;
width=imageInfo.Width;
height=imageInfo.Height;

return true;
}

void Sprite::Release()
{
if(texture)
{
texture->Release();
texture=NULL;
}
}


Engine.h

#include <d3d9.h>
#include <d3dx9.h>

class Sprite;
class Graphic;

#include "Graphic.h"
#include "Sprite.h"






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.