scene.org File Archive

File download

<root>­/­mirrors­/­hornet­/­code­/­3d­/­trifill­/­texmap/bastxmap.txt

File size:
8 601 bytes (8.40K)
File date:
2006-08-20 23:09:36
Download count:
all-time: 881

Preview

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%<Min_y%   ! is this the new lowest y co-ord?
      Min_y%=Y_coord%    ! Yes...
    Endif
    '
    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%<Y1%
    Swap X1%,X2%  ! swap these variable round so we always scan from top to...
    Swap Y1%,Y2%  ! ... bottom
    Line_height%=Y2%-Y1%
    @Scan_left_side(X1%,X2%,Y1%,Line_height%,P_side$)
  Else
    Line_height%=Y2%-Y1%
    @Scan_right_side(X1%,X2%,Y1%,Line_height%,P_side$)
  Endif
Return
'
' The points for the polygon.
' These points in the form x,y define the shape of a four sided polygon
' rotated 45 degrees. These are 2d points that would normally come from a 3d
' routine after perspective had been applied.
' The points must be defines clockwise....
'
Polygon_points:
Data 100,100
Data 150,150
Data 100,200
Data 50,150
'
' an alternative polygon to try
'
' Polygon_points:
Data 100,100
Data 150,100
Data 200,100
Data 50,100