Newsgroups: comp.graphics.algorithms Path: usenet.ee.pdx.edu!cs.uoregon.edu!sgiblab!swrinde!cs.utexas.edu!uunet!pipex!uknet!dmu.ac.uk!se1ap From: se1ap@dmu.ac.uk (Alan Parker) Subject: Texture Mapping again! Message-ID: <1994Feb7.115343.13939@dmu.ac.uk> Sender: news@dmu.ac.uk (Usenet News Management) Nntp-Posting-Host: aether.cms.dmu.ac.uk Organization: De Montfort University, Leicester, UK Date: Mon, 7 Feb 1994 11:53:43 GMT Lines: 269 ' ' Texture Mapping example. ' Maps 4 sided picture onto a 4 sided polygon. ' ' Written in GFA basic version 2 ' ' By Alan Parker (E-Mail: se1ap@dmu.ac.uk) ' On 1/2/94 ' ' This texture mapping method was 'borrowed' from Ben of Chaos. ' I've no idea who originally thought of this method. ' ' There's not many detailed comments, I've already done my best when I ' explained the algorithm before and nobody understood it, now it's up to you! ' ' Note: All variables with % after them are Integers, all other are Reals. ' Y co-ords go from top(0) to bottom(199) of the screen. ' 'picture' refers to the original bitmapped picture. ' 'polygon' refers to the polygon drawn on screen. ' The picture to be mapped must be in the top,left (0,0) corner of the ' screen. ' This is not a perspective map, but you would only have to modify the ' scan convertor to generate the picture x,y points depending on the ' z co-ords of the polygon. The texture mapping routine would stay the ' same. ' I've half managed to do a perspective map, but it's still bugged! ' It will be posted when (if?) I manage to get it working... ' ********************************************* ' ST specific code. ' Find screen address ' Screen_base%=Xbios(2) !ST specific call, get screen base address ' ' Set screen address and set to low resolution Void Xbios(5,L:Screen_base%,L:Screen_base%,W:0) ' ' Load in the picture to be texture mapped (must be in top,left of screen) Bload "d:\texturem.dem\tmap_pic.pi1",Screen_base%-34 ' ' ********************************************* ' General Texture Mapping code. ' Machine independent, probably :-) ' ' Variables and arrays. ' Dim Left_table%(400,2),Right_table%(400,2) ! Scan converter tables for polygon ' ' p.s - replace both the 400 values above with your max screen height in pixels ' Dim Poly_points(3,1) ! Array for polygon co-ords, 4 pairs(x,y) co-ords ' P_width%=96 !original picture width in pixels P_height%=96 !original picture height in pixels ' Min_y%=32767 !set initial smallest y co-ord of polygon after rotation Max_y%=0 !set initial largest y co-ord of polygon after rotation ' ' Main program ' @Get_polygon_points !get initial polygon points from DATA statements into array @Find_small_large_y !determine the smallest and the largest y-coord in the poly ' ' Send polygon points to the scan converter X1%=Poly_points(0,0) Y1%=Poly_points(0,1) X2%=Poly_points(1,0) Y2%=Poly_points(1,1) @Scan_convert(X1%,Y1%,X2%,Y2%,"top") !scan top of picture X1%=Poly_points(2,0) Y1%=Poly_points(2,1) @Scan_convert(X2%,Y2%,X1%,Y1%,"right") !scan right of picture X2%=Poly_points(3,0) Y2%=Poly_points(3,1) @Scan_convert(X1%,Y1%,X2%,Y2%,"bottom") !scan bottom of picture X1%=Poly_points(0,0) Y1%=Poly_points(0,1) @Scan_convert(X2%,Y2%,X1%,Y1%,"left") !scan left of picture ' ' Do the actual texture mapping @Texture_map End ' ' ************************************************************* ' ' Procedures ' Procedure Get_polygon_points Restore Polygon_points ! start of un-rotated polygon co-ords ' For Count%=0 To 3 Read Poly_points(Count%,0) ! read x xo-ord Read Poly_points(Count%,1) ! read y co-ord Next Count% Return ' Procedure Find_small_large_y For Count%=0 To 3 Y_coord%=Poly_points(Count%,1) ' If Y_coord%Max_y% ! is this the new highest y co-ord? Max_y%=Y_coord% ! Yes... Endif Next Count% Return ' ' This is the actual mapping routine. ' It takes the co-ords that have been calcualted by the scan converter ' and 'traces' accross the original picture in between them looking at the ' pixel colour and then plotting a pixel in that colour in the current position ' within the polygon. ' Procedure Texture_map ' For Y%=Min_y% To Max_y% Poly_x1%=Left_table%(Y%,0) !get left polygon x P_x1=Left_table%(Y%,1) !get left picture x P_y1=Left_table%(Y%,2) !get left picture y ' Poly_x2%=Right_table%(Y%,0) !get right polygon x P_x2=Right_table%(Y%,1) !get right picture x P_y2=Right_table%(Y%,2) !get right picture y Line_width%=Poly_x2%-Poly_x1% !what is the width of this polygon line Inc Line_width% !QUICK fix so it doesn't do divide by zero ' Px_add=(P_x2-P_x1)/Line_width% !'squash' picture x_dist into polygon x_dist Py_add=(P_y2-P_y1)/Line_width% !'squash' picture y_dist into polygon x_dist ' For X%=Poly_x1% To Poly_x2% Col%=Point(P_x1,P_y1) ! get colour of pixel at current pos in picture ' Color Col% ! set draw colour to the determined colour Plot X%,Y% ! plot the pixel in the correct colour Add P_x1,Px_add ! move x picture co-ord Add P_y1,Py_add ! move y picture co-ord Next X% ' Next Y% Return ' ' This procedure calculates the x points for the left side of the polygon ' It also calculates the x,y co-ords of the picture for the left side of the ' polygon. ' Procedure Scan_left_side(X1%,X2%,Y_top%,Line_height%,P_side$) Inc Line_height% ! No divide by zero X_add=(X2%-X1%)/Line_height% ' If P_side$="top" Px=P_width% Py=0 Px_add=-P_width%/Line_height% Py_add=0 Endif If P_side$="right" Px=P_width% Py=P_height% Px_add=0 Py_add=-P_height%/Line_height% Endif If P_side$="bottom" Px=0 Py=P_height% Px_add=P_width%/Line_height% Py_add=0 Endif If P_side$="left" Px=0 Py=0 Px_add=0 Py_add=P_height%/Line_height% Endif ' X=X1% For Y%=0 To Line_height% Left_table%(Y_top%+Y%,0)=X !polygon x Left_table%(Y_top%+Y%,1)=Px !picture x Left_table%(Y_top%+Y%,2)=Py !picture y Add X,X_add !Next polygon x Add Px,Px_add !Next picture x Add Py,Py_add !Next picture y Next Y% Return ' ' This procedure calculates the x points for the right side of the polygon ' It also calculates the x,y co-ords of the picture for the right side of the ' polygon. ' Procedure Scan_right_side(X1%,X2%,Y_top%,Line_height%,P_side$) Inc Line_height% ! No divide by zero X_add=(X2%-X1%)/Line_height% ' If P_side$="top" Px=0 Py=0 Px_add=P_width%/Line_height% Py_add=0 Endif If P_side$="right" Px=P_width% Py=0 Px_add=0 Py_add=P_height%/Line_height% Endif If P_side$="bottom" Px=P_width% Py=P_height% Px_add=-P_width%/Line_height% Py_add=0 Endif If P_side$="left" Px=0 Py=P_height% Px_add=0 Py_add=-P_height%/Line_height% Endif X=X1% For Y%=0 To Line_height% Right_table%(Y_top%+Y%,0)=X !polygon x Right_table%(Y_top%+Y%,1)=Px !picture x Right_table%(Y_top%+Y%,2)=Py !picture y Add X,X_add !Next polygon x Add Px,Px_add !Next picture x Add Py,Py_add !Next picture y Next Y% Return ' ' The procedure takes lines as defined by x1,y1,x2,y2. ' It also takes a string telling it which side of the picture we are mapping ' The strings are top,right,bottom,left. ' This routine decides which 'side' of the polygon the line is on, and then ' calls the apropriate routine. ' Procedure Scan_convert(X1%,Y1%,X2%,Y2%,P_side$) If Y2%