void polygon3d(BITMAP *bmp, int type, BITMAP *texture, int vc, V3D *vtx[]);
void polygon3d_f(BITMAP *bmp, int type, BITMAP *texture, int vc, V3D_f *vtx[]);
Dibuja pol�gonos 3d en el bitmap especificado, usando el modo de render
especificado. A diferencia de la funci�n polygon(), estas rutinas no
soportan figuras c�ncavas o con intersecciones, y no pueden dibujar sobre
bitmaps de pantalla en modo-X ( si quiere escribir c�digo en modo-X,
dibuja en un bitmap de memoria y c�pialo a la pantalla). El ancho y alto
del bitmap de la textura debe ser un m�ltiplo de dos, pero puede ser
diferente, ejemplo: una textura 64x16 est� bien, pero una de 17x3 no. El
par�metro que cuenta los v�rtices (vc) debe ser seguido por un array que
contiene el n�mero apropiado de punteros a estructuras vertex:
polygon3d() usa la estructura de punto fijo V3D, mientras que
polygon3d_f() usa la estructura coma flotante V3D_f. Estas son definidas
as�:
El c�mo se almacenan los datos de los v�rtices depende del modo de render:typedef struct V3D { fixed x, y, z; - posici�n fixed u, v; - coordenadas de la textura int c; - color } V3D; typedef struct V3D_f { float x, y, z; - posici�n float u, v; - coordenadas de la textura int c; - color } V3D_f;
Los valores x e y especifican la posici�n del v�rtice en coordenadas de pantalla 2d.
El valor z s�lo es necesario cuando use correcci�n de perspectiva en las texturas, y especifica la profundidad del punto usando coordenadas del mundo 3d.
Las coordenadas u y v s�lo son necesarias cuando use texturas, y especifican la posici�n del punto en el bitmap de la textura que se corresponde con el v�rtice indicado. El plano de la textura es un plano infinito con el bitmap repetido sobre toda la superficie, y la imagen del pol�gono resultante en este plano rellenar� el pol�gono cuando se dibuje en pantalla.
Nos referimos a pixels en el plano de la textura como texels. Cada texel es un bloque, n� s�lo un punto, y los n�meros enteros de u y v se refieren a la esquina superior izquierda del texel. Esto tiene varias implicaciones. Si quiere dibujar un pol�gono rectangular y aplicar una textura de 32x32 sobre �l, debe usar las coordenadas de textura (0,0), (0,32), (32,32) y (32,0), asumiendo que los v�rtices son especificados en �rden antihorario. La textura ser� aplicada perfectamente sobre el pol�gono. No obstante, note que si ajustamos u=32, la �ltima columna de texels que se ver�n en la pantalla ser�n los que est�n en u=31, y lo mismo ocurre para v. Esto es porque las coordenadas se refieren a la esquina superior izquierda de los texels. En efecto, las coordenadas de textura por la derecha y por abajo son exclusivas.
Aqu� hay otro punto interesante. Si tiene dos pol�gonos juntos que comparten dos v�rtices (como las dos partes de una pieza de cart�n doblada), y quiere aplicar sobre ellos una textura cont�nua, los valores u y v de los v�rtices que est�n en la junta ser�n iguales para ambos pol�gonos. Por ejemplo, si ambos son rectangulares, un pol�gono usar� (0,0), (0,32), (32,32) y (32,0), y el otro usar� (32,0), (32,32), (64,32) y (64,0). Esto aplicar� la textura perfectamente.
Por supuesto puede usar n�meros con decimales para u y v indicando puntos que est�n parcialmente en un texel. Adem�s, dado que el plano de la textura es infinito, puede especificar valores mayores que el tama�o de la textura. Esto puede ser usado para repetir la textura varias veces sobre el pol�gono.
El valor c especifica el color del v�rtice, y es interpretado de forma diferente por los modos de render.
El par�metro type especifica el modo de render, y puede ser cualquiera de los siguientes:
POLYTYPE_FLAT:
Un simple pol�gono con sombreado plano, que toma el color del valor c
del primer v�rtice. Este tipo de pol�gono es afectado por la funci�n
drawing_mode(), por lo que puede ser usado para renderizar pol�gonos
transparentes o XOR.
POLYTYPE_GCOL:
Un pol�gono con un color de sombreado goraud. Los colores de cada
v�rtice son tomados del valor c, e interpolados a trav�s del pol�gono.
Esto es muy r�pido, pero s�lo funcionar� en modos de 256 colores si su
paleta tiene un suave gradiente de colores. En modos truecolor
interpreta el color como valor empaquetado en formato directo de
hardware producido por la funci�n makecol().
POLYTYPE_GRGB:
Un pol�gono con sombreado goraud que interpola tripletes RGB en vez de
un solo color. En modos de 256 colores usa la tabla global rgb_map
para convertir el resultado a color de 8 bits, por lo que s�lo puede
ser usado despu�s de que haya creado una tabla de mapa de colores. Los
colores para cada v�rtice son tomados del valor c, que es interpretado
como un triplete RGB de 24 bits (0xFF0000 es rojo, 0x00FF00 es verde y
0x0000FF es azul).
POLYTYPE_ATEX:
Un pol�gono con textura af�n. Esto dibuja la textura a trav�s del
pol�gono con una simple interpolaci�n 2d lineal, que es r�pida pero
matem�ticamente incorrecta. Puede estar bien si el pol�gono es peque�o
o plano hacia la c�mara, pero como no cuenta con la acortaci�n de
perspectiva, puede producir extra�os artefactos movidos en la textura.
Para ver lo que quiero decir, ejecuta test.exe y mire lo que pasa con
el test polygon3d() cuando hace un zoom muy cerca del cubo.
POLYTYPE_PTEX:
Un pol�gono texturizado con correcci�n de perspectiva. Esto usa el
valor z de la estructura del v�rtice as� como las coordenadas u/v, por
lo que las texturas se ven correctamente independientemente del �ngulo
de visualizaci�n. Ya que esto envuelve c�lculos de divisi�n en al
bucle interior de la texturizaci�n, este modo es mucho m�s lento que
POLYTYPE_ATEX, y usa coma flotante, por lo que ser� muy lento en
cualquier cosa peor que un Pentium (incluso con una FPU, un 486 no es
capaz de mezclar divisi�n de coma flotante con otras operaciones de
enteros tal y como puede hacer un Pentium).
POLYTYPE_ATEX_MASK:
POLYTYPE_PTEX_MASK:
Como POLYTYPE_ATEX and POLYTYPE_PTEX, pero los pixels a cero de la
textura son ignorados, permitiendo que la textura sea transparente.
POLYTYPE_ATEX_LIT:
POLYTYPE_PTEX_LIT:
Como POLYTYPE_ATEX y POLYTYPE_PTEX, pero la tabla global color_map
(para modos de 256 colores) o la funci�n de fundido (para modos
truecolor no-MMX) es usada para fundir la textura con el nivel de luz
tomado del valor c en la estructura del v�rtice. �Esto s�lo puede ser
usado despu�s de que haya creado una tabla de mapa de color o
funciones de fundido!
POLYTYPE_ATEX_MASK_LIT:
POLYTYPE_PTEX_MASK_LIT:
Como POLYTYPE_ATEX_LIT y POLYTYPE_PTEX_LIT, pero los pixels a cero de
la textura son ignorados, permitiendo que la textura sea transparente.
POLYTYPE_ATEX_TRANS:
POLYTYPE_PTEX_TRANS:
Renderiza texturas transl�cidas. Son aplicables todas las reglas
generales de dibujado transl�cido. No obstante, estos modos tienen una
limitaci�n: s�lo funcionan con bitmaps en memoria o con memoria de
v�deo lineal (no con video por bancos). Ni si quiera lo intente en
estos casos, ya que las funciones no realizan chequeos y su programa
morir� horriblemente (o como m�nimo dibujar� mal las cosas).
POLYTYPE_ATEX_MASK_TRANS:
POLYTYPE_PTEX_MASK_TRANS:
Como POLYTYPE_ATEX_TRANS y POLYTYPE_PTEX_TRANS, pero los pixels a
cero de la textura son ignorados.
Si el bit CPU_MMX de la variable global cpu_capabilities est� activado, las rutinas GRGB y *LIT truecolor ser�n optimizadas usando instrucciones MMX. Si el bit CPU_3DNOW est� activado, las rutinas truecolor PTEX*LIT tomar�n ventaja de la extensi�n de CPU 3DNow!.
Usar rutinas MMX para *LIT tiene un efecto secundario: normalmente (sin MMX), estas rutinas usan las funciones de fundido y otras funciones de luz, creadas con set_trans_blender() o set_blender_mode(). Las versiones MMX s�lo usan el valor RGB que se pasa a set_trans_blender() y hacen la interpolaci�n lineal internamente. Por esta raz�n, un nuevo conjundo de funciones de fundido que se pasa a set_blender_mode() es ignorado.
Relacionado con: triangle3d, quad3d, polygon, clip3d, cpu_capabilities.void triangle3d(BITMAP *bmp, int type, BITMAP *tex, V3D *v1, *v2, *v3);
Relacionado con: polygon3d, quad3d, triangle.void quad3d(BITMAP *bmp, int type, BITMAP *tex, V3D *v1, *v2, *v3, *v4);
Relacionado con: polygon3d, triangle3d.int clip3d_f(int type, float min_z, float max_z, int vc, V3D_f *vtx[], V3D_f *vout[], V3D_f *vtmp[], int out[]);
Relacionado con: polygon3d, clip3d.int clip3d(int type, fixed min_z, fixed max_z, int vc, V3D *vtx[], V3D *vout[], V3D *vtmp[], int out[]);
Relacionado con: polygon3d, clip3d_f.
Un Z-buffer almacena la profundidad de cada pixel dibujado en una pantalla. Cuando un objeto 3d es renderizado, la profundidad de cada pixel es comparada con el valor ya almacenado en el Z-buffer: si el pixel es m�s cercano se dibuja, en caso contrario se ignora.
No hace falta ordenar los pol�gonos. No obstante, sigue siendo �til ignorar los pol�gonos que no est�n de cara a la c�mara, ya que as� se previene la comparaci�n de muchos pol�gonos ocultos contra el Z-buffer. El render mediante Z-buffer es el �nico algoritmo soportado por Allegro que resuelve directamente la intersecci�n entre figuras (mire por ejemplo exzbuf.c). El precio que hay que pagar son unas rutinas m�s complejas (y m�s lentas).
Los pol�gonos con Z-buffer son por dise�o una extensi�n de los estilos de render normales POLYTYPE_*. S�lo hay que hacer una OR entre POLYTYPE y el valor POLYTYPE_ZBUF, y las rutinas normales como polygon3d(), polygon3d_f(), quad3d(), etc, renderizar�n pol�gonos con Z-buffer.
Ejemplo:
polygon3d(bmp, POLYTYPE_ATEX | POLYTYPE_ZBUF, tex, vc, vtx);
Por supuesto, las coordenadas z deben ser v�lidas sin importar el estilo de render.
El procedimiento de render con Z-buffer parece un render con doble buffer. Deber�a seguir los siguientes pasos: crear el Z-buffer al comienzo de su programa y hacer que la librer�a lo use mediante set_zbuffer(). Entonces, por cada frame, borre el Z-buffer y dibuje pol�gonos con POLYTYPE_* | POLYTYPE_ZBUF para finalmente destruir el Z-buffer al finalizar su programa.
Notas sobre los renders con Z-buffer:
Relacionado con: create_sub_zbuffer, set_zbuffer, clear_zbuffer, destroy_zbuffer.ZBUFFER *create_sub_zbuffer(ZBUFFER *parent, int x, int y, int width, int height);
Cuando dibuje con z-buffer en un bitmap, la esquina superior izquierda del bitmap siempre est� alineada con la esquina superior izquierda del z-buffer actual. Por lo que esta funci�n es �til principalmente si quiere dibujar en un sub-bitmap y usar el �rea correspondiente del z-buffer. En otros casos, ej, si quiere dibujar en un sub-bitmap de la pantalla (y no en otras partes de la pantalla), normalmente querr� crear un z-buffer normal (no un sub-z-buffer) del tama�o de la pantalla. No necesita crear un z-buffer del tama�o de la pantalla virtual y entonces un sub-z-buffer de �ste.
Relacionado con: create_zbuffer, create_sub_bitmap, destroy_zbuffer.void set_zbuffer(ZBUFFER *zbuf);
Relacionado con: create_zbuffer, clear_zbuffer, destroy_zbuffer.void clear_zbuffer(ZBUFFER *zbuf, float z);
Relacionado con: create_zbuffer, set_zbuffer, destroy_zbuffer.void destroy_zbuffer(ZBUFFER *zbuf);
Relacionado con: create_zbuffer, set_zbuffer, clear_zbuffer.
Allegro provee dos m�todos simples para quitar caras ocultas:
El render de escenas sigue los siguientes pasos aproxim�damente:
Por cada linea horizontal del �rea de visualizaci�n se usa una lista ordenada de bordes para saber qu� pol�gonos "est�n dentro" y cu�les est�n cerca. Se usa coherencia vertical - la lista de bordes es ordenada a partir de la anterior - no cambiar� mucho. Las rutinas de render de escenas usan las mismas rutinas de bajo nivel que polygon3d().
Notas del render de escena:
El render con Z-buffer tambi�n funciona con el render de escenas. Puede ser �til si tiene algunos pol�gonos que se interseccionan, pero la mayor�a de los pol�gonos pueden ser renderizados sin problemas usando el algoritmo normal de ordenado de scanlines. Igual que antes: simplemente haga una OR del POLYTIPE con POLYTYPE_ZBUF. Adem�s, tiene que limpiar el z-buffer al comienzo del frame. Ejemplo:
clear_scene(buffer); if (some_polys_are_zbuf) clear_zbuffer(0.); while (polygons) { ... if (this_poly_is_zbuf) type |= POLYTYPE_ZBUF; scene_polygon3d(type, tex, vc, vtx); } render_scene();
int create_scene(int nedge, int npoly);
Reserva memoria para una escena, nedge y npoly son sus estimaciones de
cu�ntas aristas y pol�gonos renderizar� (no puede salirse del l�mite que
especifica aqu�). Si usa los mismos valores en llamadas sucesivas, el
espacio ser� reusado (no nuevos malloc()).
La memoria reservada es algo menor que 150 * (nedge + npoly) bytes. Devuelve cero con �xito, o negativo si no se pudo reservar la memoria.
Relacionado con: create_zbuffer, scene_polygon3d, render_scene, clear_scene, destroy_scene, scene_gap.void clear_scene(BITMAP *bmp);
Relacionado con: create_scene, scene_polygon3d, render_scene, destroy_scene, scene_gap.void destroy_scene();
Relacionado con: create_scene, scene_polygon3d, clear_scene, render_scene, scene_gap.int scene_polygon3d(int type, BITMAP *texture, int vc, V3D *vtx[]);
Los argumentos son iguales que para polygon3d(), excepto por el par�metro de bitmap que falta. Se usar� el que indic� mediante clear_scene().
A diferencia de polygon3d(), los pol�gonos pueden ser c�ncavos o estar interseccionados. Las figuras que penetran en otras pueden salir bien, pero no son manejadas realmente por este c�digo.
Note que s�lo se almacena un puntero a la textura, por lo que deber�a mantenerla en memoria hasta render_scene(), donde ser� usada.
Ya que el estilo FLAT es implementado con la funci�n de bajo nivel hline(), el estilo FLAT est� sujeto a DRAW_MODE. Todos los modos son v�lidos. Junto con el pol�gono, el modo ser� almacenado para el momento del render, y tambi�n otras variables relacionadas (puntero al mapa de color, puntero al patron, ancla, valores de blending).
El valor de los bits CPU_MMX y CPU_3DNOW de la variable global cpu_capabilities afectar� la elecci�n de la rutina de bajo nivel en ensamblador que ser� usada por render_scene() con este pol�gono.
Devuelve cero con �xito o negativo si no ser� renderizado debido a que falta la rutina de render apropiada.
Relacionado con: cpu_capabilities, create_scene, clear_scene, render_scene, destroy_scene, polygon3d.void render_scene();
Note que entre clear_scene() y render_scene() no deber�a modificar el rect�ngulo de recorte del bitmap destino. Por razones de velocidad, deber�a ajustar el rect�ngulo de recorte al m�nimo.
Tenga en cuenta tambi�n que las texturas pasadas a scene_polygon3d() son almacenadas como punteros y ser�n usadas en render_scene().
Relacionado con: create_scene, clear_scene, destroy_scene, scene_gap, scene_polygon3d.extern float scene_gap;
El valor por defecto significa que si los valores 1/z (en espacio proyectado) difieren s�lo en 1/100 (uno por ciento), ser�n considerados iguales y el eje x de los planos ser� usado para saber qu� plano est� acerc�ndose mientras nos movemos hacia la derecha.
Valores mayores significan m�rgenes menores, e incrementan la posibilidad de confundir planos/bordes realmente adyacentes. Valores menores significan m�rgenes mayores, e incrementan la posibilidad de confundir un pol�gono cercano con uno adyacejte. El valor de 100 est� cercano a lo m�s �ptimo. No obstante, el valor optimo oscila con diferentes resoluciones, y puede ser dependiente de la aplicaci�n. Est� aqu� para que lo pueda ajustar al m�ximo.
Relacionado con: create_scene, clear_scene, destroy_scene, render_scene, scene_polygon3d.