This chapter explains the surface attributes of polygons on Sega Saturn.
For polygons, "Sort" indicates the reference position to determine the display order of each polygon, "Front and back attributes" specify whether to display one side or both sides of the polygon, and a two-dimensional picture ( There are elements such as "textures" that paste bitmap data).
These are collectively called "polygon surface attributes."
By specifying the surface attributes of polygons, you can add various expressions to polygons that were previously just pictures.
●Attribute dataATTR attribute_label[]={ ATTRIBUTE(Plane,Sort,Texture,Color,Gouraund,Mode,Dir,Option), ...................... };
Note) The ATTRIBUTE macro is defined in “sl_def.h”.
Plane: Indicates whether it is a single-sided polygon or a double-sided polygon (front and back attributes) Sort: Indicates the representative point of the positional relationship of polygons (Z sort) Texture: Indicates the texture name (No.) Color: Indicates the color data Gouraud: Indicates the address of the Gouraud shading table Mode: Indicates the polygon drawing mode (various mode settings) Dir: Indicates the state of polygons and textures Option: Indicates other functions (option settings)
macro | Contents |
---|---|
Single_Plane | One-sided display of polygons |
Dual_Plane | Double-sided display of polygons |
/*------------------------------------------------ ----------------------*/ /* Rotation of Single Plane Polygon */ /*------------------------------------------------ ----------------------*/ #include "sgl.h" extern PDATA PD_PLANE; void ss_main(void) { static ANGLE ang[XYZ]; static FIXED pos[XYZ]; slInitSystem(TV_320x224,NULL,1); slPrint("Sample program 7.2" , slLocate(6,2)); ang[X] = ang[Y] = ang[Z] = DEGtoANG(0.0); pos[X] = toFIXED( 0.0); pos[Y] = toFIXED( 0.0); pos[Z] = toFIXED(170.0); while(-1){ slPushMatrix(); { slTranslate(pos[X] , pos[Y] , pos[Z]); slRotX(ang[X]); slRotY(ang[Y]); slRotZ(ang[Z]); ang[Y] += DEGtoANG(2.0); slPutPolygon(&PD_PLANE); } slPopMatrix(); slSynch(); } }
#include "sgl.h" POINT point_PLANE[] = { POStoFIXED(-20.0, -20.0, 0.0), POStoFIXED( 20.0, -20.0, 0.0), POStoFIXED( 20.0, 20.0, 0.0), POStoFIXED(-20.0, 20.0, 0.0), }; POLYGON polygon_PLANE[] = { NORMAL(0.0,0.0,1.0), VERTICES(0,1,2,3), }; ATTR attribute_PLANE[] = { ATTRIBUTE(Single_Plane,SORT_CEN,No_Texture,C_RGB(31,31,0),No_Gouraud,MESHoff,sprPolygon,No_Option), }; PDATA PD_PLANE = { point_PLANE , sizeof(point_PLANE)/sizeof(POINT) , polygon_PLANE , sizeof(polygon_PLANE)/sizeof(POLYGON) , attribute_PLANE };
macro | Contents |
---|---|
SORT_MIN | Set the vertex on the polygon closest to the camera as the representative point |
SORT_CEN | Set the center point of the polygon as the representative point |
SORT_MAX | Set the point farthest from the camera as the representative point |
SORT_BFR | Displayed in front of the polygon registered just before |
< Figure 7-1 Representative points of Z sort>
“SORT_BFR” is a special specification and is used when you want to display one polygon above (in front of) another polygon. Specifically, the display position of a polygon with “SORT_BFR” specified will be immediately in front of the polygon registered immediately before that polygon. However, this specification only becomes meaningful when you want to use two polygons as a group, so it is not usually used.
Due to its nature, the Z-sort method includes the possibility that the context may become incorrect depending on how representative points are taken. Take a look at the following example.
< Figure 7-2 Differences in context due to representative points>
If you specify the representative point as shown in the figure above, the actual screen will look like the figure below.
< Figure 7-3 Actual screen>
texture mapping | |||
For Sega Saturn | For general CG | ||
of texture | stakeout | It is possible to paste one texture to one polygon. | A single texture can be pasted across multiple polygons. |
deformation | The texture is also transformed according to the shape of the polygon. | The texture will be clipped to the shape of the polygon. |
< Figure 7-5 Characteristics of texture 1>
Textures in general CG can be pasted across multiple polygons, but in the case of Sega Saturn, one texture is pasted in correspondence to one polygon. If you want to paste a texture that spans two or more polygons, you need to divide the texture according to each polygon as shown in Figure 7-5.
< Figure 7-6 Texture characteristics 2>
< Figure 7-7 Texture distortion>
Now, let's take a look at the sample program (Listing 7-4).
A single polygon with a texture attached rotates around the Y axis.
Here, we will register two textures in advance.
One is a picture of [SONIC] (size: 64 x 64 pixels), and the other is the "AM2" mark (size: 64 x 32 pixels).
/*------------------------------------------------ ----------------------*/ /* Polygon & Texture */ /*------------------------------------------------ ----------------------*/ #include "sgl.h" extern PDATA PD_PLANE; extern TEXTURE tex_sample[]; extern PICTURE pic_sample[]; #define max_texture 2 void set_texture(PICTURE *pcptr , Uint32 NbPicture) { TEXTURE *txptr; for(; NbPicture--> 0; pcptr++){ txptr = tex_sample + pcptr-> texno; slDMACopy((void *)pcptr->pcsrc, (void *)(SpriteVRAM + ((txptr-> (CGadr)<< 3)), (Uint32)((txptr-> Hsize * txptr-> Vsize * 4) >> (pcptr-> cmode))); } } void ss_main(void) { static ANGLE ang[XYZ]; static FIXED pos[XYZ]; slInitSystem(TV_320x224,tex_sample,1); set_texture(pic_sample,max_texture); slPrint("Sample program 7.4" , slLocate(9,2)); ang[X] = ang[Y] = ang[Z] = DEGtoANG(0.0); pos[X] = toFIXED( 0.0); pos[Y] = toFIXED( 0.0); pos[Z] = toFIXED(170.0); while(-1){ slPushMatrix(); { slTranslate(pos[X] , pos[Y] , pos[Z]); slRotX(ang[X]); slRotY(ang[Y]); slRotZ(ang[Z]); ang[Y] += DEGtoANG(2.0); slPutPolygon(&PD_PLANE); } slPopMatrix(); slSynch(); } }
First, pay attention to line 29.
This is an initialization routine that has been used implicitly until now, but the second parameter is different from before. Specify a pointer to the texture table to be passed to SGL here. (The actual table is defined in “texture.c”. See Listing 7-5 .) Up until now, we had not used textures, so we had assigned “NULL”.
Line 30 transfers the texture data to V-RAM.
This texture data transfer can be performed at any time after initialization, so techniques such as redrawing textures during the game can be easily performed.
The 12th line and subsequent lines are the actual texture data transfer routine.
Here, we receive the start address of the texture table and the number of registered textures. The “slDMACopy” function on line 18 uses DMA to transfer data at high speed.
The first parameter of this function is the transfer source address, the second parameter is the transfer destination address, and the third parameter is the transfer size.
Next, let's look at the texture data.
#include "sgl.h" /********************************/ /* Texture Data */ /********************************/ TEXDAT sonic_64x64[]={ /* Texture data 1 */ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, : : Omitted: }; TEXDAT am2_64x32[]={ /* Texture data 2 */ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, : : Omitted: }; TEXTURE tex_sample[]={ /* Table to be passed to SGL */ TEXDEF(64,64,0), TEXDEF(64,32,64*64*1), }; PICTURE pic_sample[]={ /* VRAM transfer table */ PICDEF(0,COL_32K,sonic_64x64), PICDEF(1,COL_32K,am2_64x32), };
The part written by the TEXTURE macro is the texture table passed to SGL.
Set the size (width x height) of each texture and the offset value from the start address of the actual texture data.
Finally, the PICTURE macro part becomes the table for VRAM transfer.
Set the texture number, color mode, and pointer to texture data.
Now, last but not least, let's take a look at the attributes of the polygon data.
#include "sgl.h" #define PN_SONIC 0 #define PN_AM2 1 POINT point_plane[] = { POStoFIXED(-40.0 , -40.0 , 0.0) , POStoFIXED( 40.0 , -40.0 , 0.0) , POStoFIXED( 40.0 , 40.0 , 0.0) , POStoFIXED(-40.0 , 40.0 , 0.0) }; POLYGON polygon_plane[] = { NORMAL(0.0,0.0,1.0), VERTICES(0 , 1 , 2 , 3) }; ATTR attribute_plane[] = { ATTRIBUTE(Single_Plane, SORT_CEN, PN_SONIC, No_Palet, No_Gouraud, CL32KRGB|MESHoff, sprNoflip, No_Option), }; PDATA PD_PLANE = { point_plane , sizeof(point_plane)/sizeof(POINT), polygon_plane, sizeof(polygon_plane)/sizeof(POLYGON), attribute_plane };
flat shading | Gouro shading |
---|
/*------------------------------------------------ ----------------------*/ /* Gouraud Shading */ /*------------------------------------------------ ----------------------*/ #include "sgl.h" extern PDATA PD_CUBE; #define GRoffsetTBL(r,g,b) (((b & 0x1f)<< 0) | ((g & 0x1f)<< 5) | (r & 0x1f)) #define VRAMaddr (SpriteVRAM+0x70000) static Uint16 GRdata[6][4] = { { GRoffsetTBL( 0,-16,-16) , GRoffsetTBL( 0,-16,-16) , GRoffsetTBL( 0,-16,-16) , GRoffsetTBL(-16, 15, 0) } , { GRoffsetTBL( 0,-16,-16) , GRoffsetTBL( 0,-16,-16) , GRoffsetTBL(-16, 15, 0) , GRoffsetTBL( 0,-16,-16) } , { GRoffsetTBL(-16, 15, 0) , GRoffsetTBL( 0,-16,-16) , GRoffsetTBL( 0,-16,-16) , GRoffsetTBL( 0,-16,-16) } , { GRoffsetTBL( 0,-16,-16) , GRoffsetTBL(-16, 15, 0) , GRoffsetTBL( 0,-16,-16) , GRoffsetTBL( 0,-16,-16) } , { GRoffsetTBL( 0,-16,-16) , GRoffsetTBL(-16, 15, 0) , GRoffsetTBL( 0,-16,-16) , GRoffsetTBL( 0,-16,-16) } , { GRoffsetTBL(-16, 15, 0) , GRoffsetTBL( 0,-16,-16) , GRoffsetTBL( 0,-16,-16) , GRoffsetTBL( 0,-16,-16) } }; void ss_main(void) { static ANGLE ang[XYZ]; static FIXED pos[XYZ]; slInitSystem(TV_320x224,NULL,1); slPrint("Sample program 7.6" , slLocate(9,2)); ang[X] = DEGtoANG(30.0); ang[Y] = DEGtoANG( 0.0); ang[Z] = DEGtoANG( 0.0); pos[X] = toFIXED( 0.0); pos[Y] = toFIXED( 0.0); pos[Z] = toFIXED(200.0); slDMACopy(GRdata,(void *)VRAMaddr,sizeof(GRdata)); while(-1){ slPushMatrix(); { slTranslate(pos[X] , pos[Y] , pos[Z]); slRotX(ang[X]); slRotY(ang[Y]); slRotZ(ang[Z]); slPutPolygon(&PD_CUBE); } slPopMatrix(); ang[Y] += DEGtoANG(1.0); slSynch(); } }
Now let's take a look at the attributes.
#include "sgl.h" #define GRaddr 0xe000 static POINT point_CUBE[] = { POStoFIXED(-20.0 , -20.0 , 20.0) , POStoFIXED( 20.0 , -20.0 , 20.0) , POStoFIXED( 20.0 , 20.0 , 20.0) , POStoFIXED(-20.0 , 20.0 , 20.0) , POStoFIXED(-20.0 , -20.0 , -20.0) , POStoFIXED( 20.0 , -20.0 , -20.0) , POStoFIXED( 20.0 , 20.0 , -20.0) , POStoFIXED(-20.0 , 20.0 , -20.0) }; static POLYGON polygon_CUBE[] = { NORMAL( 0.0 , 0.0 , 1.0), VERTICES(0 , 1 , 2 , 3), NORMAL(-1.0 , 0.0 , 0.0), VERTICES(4 , 0 , 3 , 7), NORMAL( 0.0 , 0.0 ,-1.0), VERTICES(5 , 4 , 7 , 6), NORMAL( 1.0 , 0.0 , 0.0), VERTICES(1 , 5 , 6 , 2), NORMAL( 0.0 ,-1.0 , 0.0), VERTICES(4 , 5 , 1 , 0), NORMAL( 0.0 , 1.0 , 0.0), VERTICES(3 , 2 , 6 , 7) }; static ATTR attribute_CUBE[] = { ATTRIBUTE(Single_Plane, SORT_MIN, No_Texture, C_RGB(31,16,31), GRaddr, MESHoff|CL_Gouraud, sprPolygon,No_Option), ATTRIBUTE(Single_Plane, SORT_MIN, No_Texture, C_RGB(31,16,31), GRaddr+1, MESHoff|CL_Gouraud, sprPolygon,No_Option), ATTRIBUTE(Single_Plane, SORT_MIN, No_Texture, C_RGB(31,16,31), GRaddr+2, MESHoff|CL_Gouraud, sprPolygon,No_Option), ATTRIBUTE(Single_Plane, SORT_MIN, No_Texture, C_RGB(31,16,31), GRaddr+3, MESHoff|CL_Gouraud, sprPolygon,No_Option), ATTRIBUTE(Single_Plane, SORT_MIN, No_Texture, C_RGB(31,16,31), GRaddr+4, MESHoff|CL_Gouraud, sprPolygon,No_Option), ATTRIBUTE(Single_Plane, SORT_MIN, No_Texture, C_RGB(31,16,31), GRaddr+5, MESHoff|CL_Gouraud, sprPolygon,No_Option), }; PDATA PD_CUBE = { point_CUBE , sizeof(point_CUBE)/sizeof(POINT), polygon_CUBE , sizeof(polygon_CUBE)/sizeof(POLYGON) , attribute_CUBE };
Please also pay attention to the 6th parameter “Mode”.
When using Gouraud shading, “CL_Gouraud” must be specified here. If you do not use Gouraud shading, please specify the macro "No_Gouraud" for the fifth parameter "Gouraud".
group | macro | Content |
---|---|---|
[1] | No_Window | Not subject to Window restrictions (default) |
Window_In | Display inside Window | |
Window_Out | Display outside the window | |
[2] | MESHoff | Normal display (default) |
MESHon | Display as mesh | |
[3] | ECdis | Disable EndCode |
ECenb | Enable EndCode (default) | |
[4] | SPdis | Also display transparent pixels (default) |
SPenb | Do not display transparent pixels | |
[5] | CL16Bnk | 16-color color bank mode (default) |
CL16Look | 16 color lookup table | |
CL64Bnk | 64 color color bank mode | |
CL128Bnk | 128 color color bank mode | |
CL256Bnk | 256 color color bank mode | |
CL32KRGB | 32768 colors RGB mode | |
[6] | CL_Replace | Overwrite (standard) mode (default) |
CL_Shadow | shadow mode | |
CL_Half | half brightness mode | |
CL_Trans | Translucent mode | |
CL_Gouraud | gouraud shading mode | |
[7] | HSSon | Use high speed shrink |
HSSoff | Do not use high speed shrink (default) | |
[8] | MSBon | Set MSB when writing to frame buffer |
MSBoff | Do not set MSB when writing to frame buffer (default) |
Group [5] is for specifying the color mode of the texture, so if you do not use the texture, be sure to set it to the default (“CL_16Bnk” or do not specify it). If you specify any other mode here, the polygons will not be displayed.
As exceptions to group [6], “CL_Gouraud |- CL_Half” and “CL_Gouraud |- CL_Trans” can be used. Please use it when you want to use semi-bright Gouraud shading or semi-transparent Gouraud shading.
If you use Gouraud shading, you need to set “CL_Gouraud” here as well as setting the 5th parameter.
When using semi-brightness, semi-transparent, and Gouraud shading, only RGB direct mode is supported for polygons and 32768-color RGB mode for textures. Please note that other settings will not display correctly.
macro | Contents |
---|---|
sprNoflip | Display texture normally |
sprHflip | Flip the texture horizontally |
sprVflip | Flip the texture vertically |
sprHVflip | Flip the texture vertically and horizontally |
sprPolygon | display polygons |
sprPolyLine | display polyline |
sprLine | Displays a straight line using the first two points |
macro | Contents |
---|---|
UseLight | Perform light source calculations |
Use Palette | Indicates that polygon colors are in palette format |
UseNearClip | If the 4 vertices go outside the screen specified by slWindowClipLevel, they will not be displayed. |
UseDepth | Calculate depth cue with parallel light source |
UseGouraud | Performs light source calculation using real-time Gouraud (valid only with slPutPolygonX) |
functional type | function name | parameters | function |
---|---|---|---|
void | slDMACopy | Src,dst,cnt | Block transfer using CPU DMA |