Demo or Die #01
28 февраля 1999 |
|
Demo-Building - Fill the triangle Gupo shading, texture mapping.
_________________________________________ (C) by Wolf / eTC / Scene Fill the triangle. Gouraud shading. Texture mapping. Based on the fact that the computer 3D-graphics all the 3D-objects in the main consist of elementary triangles in This article will describe the algorithm Fill a one-color triangle. Since on the Spectrum in normal mode (50fps), at each point can not be your color, we consider the triangle filled with white color. Take any triangle with points ABC. Where A.X - X coordinate of point A, and A.Y - Y coordinate of point A respectively, etc. Fill it will horizontal lines as This method is the fastest and easiest. First of all we need sort the points of the triangle ABC in Y coordinate in ascending order. Minimum Y coordinate of a point A, the maximum point C, and the average between the value point B. Now, knowing that it is necessary to pour triangle with horizontal lines of point A to point C, must be visually construct the triangle along the lines of (not flooding it), but not drawing it on screen, and maintaining a buffer for all three coordinates X sides forming a triangle. Ie we have two arrays edge1 [hgt_screen] and edge2 [hgt_screen], where hgt_screen - is the height of the screen. In these arrays and will be located coordinates X, and which must be connected horizontal lines between them. For simplicity and understanding, we will build a visual line by interpolation X coordinate. To do this, let us have interpolation procedure inter (x1, x2, len, buffer), where x1 - the first coordinate (from where), x2 - the second coordinate (where), len - count ichestvo steps, buffer - address of the buffer where procedure will be put interpolated values. For those who do not know what interpolation (in this case applies linear interpolation) - a finding function values corresponding intermediate values of the argument, which are absent in the table (this way we at the institute told). Well, if you explain the "fingers", then here's an example of interpolation: X1 = 3 X2 = 9 len = 3 With such initial values, interpolation values are as follows 3,6,9. Here you even mathematical Formula: K = (1-step) * X1 + step * X2 where K - the missing intermediate value, step - a step that should vary in the range [0 ... 1], and X1 and X2 - the initial and final importance respectively. Here's an example to ASME: ;++++++++++++++++++++++++++++++++++++++; ; INTERPOLATIONS; ,; ; Best idea: Wolf / eTc / ScEnE; ; Perfect code: Devil / eTc / sCeNE; ,; ; HL = BUFFER; ; E = LEN OF BUFFER; ; B = X1; ; A = X2; ;++++++++++++++++++++++++++++++++++++++; INTER LD HX, B CP B LD C, A LD D, A LD A, # 04 JR NC, INTER6 LD A, # 05 LD D, B LD B, C INTER6 LD (INTER5), A LD (INCDEC), A LD A, D SUB B LD B, HX CP E JR C, INTER0 JR Z, INTER0 INTER3 LD C, A DEC E LD D, E LD (HL), B INTER4 SUB E JR NC, INTER5 INC L INC L LD (HL), B ADD A, C DEC D RET Z INTER5 INC B JR INTER4 RET INTER0 INC A LD C, A LD D, E LD A, E INTER1 SUB C JR NC, INTER2 ADD A, E INCDEC INC B INTER2 LD (HL), B INC L INC L DEC D JR NZ, INTER1 RET Thus, we construct a visual line triangles (only the coordinates of X) in Arrays: {For understanding, in Pascal} procedure visual_draw; begin inter (A.x, C.x, abs (A.y-C.y), edge1); inter (A.x, B.x, abs (A.y-B.y), edge2); inter (B.x, C.x, abs (B.y-C.y), edge2 + abs (A.y-B.y)); end; {For those who do not know the function abs () - is the module number} Interpolate these coordinates, we have two arrays with coordinates X-s all three sides of a triangle. And in one array one side and the other two the other side. Now we have nothing left to do how to write a procedure for constructing horizontal line. We call it Hline (x1, x2, y), where x1 and x2 - horizontal coordinates of the line, and y - actual y coordinate of the line. And then "fill in the" triangle horizontal lines, the following cycle: y: = A.y; for cycle: = 1 to abs (C.y-A.y) do begin Hline (edge1 [cycle], edge2 [cycle], y); inc (y); end; That's all, now if you've got it, you know how to fill what or triangles color. And now I'll fill algorithm the same triangle on Gouraud. Guro - A linear interpolation of illumination the image face on the screen. To do this we need to create more Two arrays color1 [hgt_screen] and color2 [hgt_screen], which will store interpolation values of illumination. A also assign each point of the triangle intensity of illumination (Ac, Bc, Cc, where c - the intensity of light). That is a process for filling the boundary array for a triangle of Guro, she such a same as for casting triangle with color, but with adding interpolation illumination: procedure visual_draw_gouround; begin inter (A.x, C.x, abs (A.y-C.y), edge1); inter (A.x, B.x, abs (A.y-B.y), edge2); inter (B.x, C.x, abs (B.y-C.y), edge2 + abs (A.y-B.y)); inter (A.c, C.c, abs (A.y-C.y), color1); inter (A.c, B.c, abs (A.y-B.y), color2); inter (B.c, C.c, abs (B.y-C.y), color2 + abs (A.y-B.y)); end; Having the procedure for constructing horizontal line with a linear interpolated color Hline_gouround (x1, x2, c1, c2, y), where x1 and x2 - primary and the final value of the horizontal coordinates, and c1 and c2 - initial and the final color, we will write a procedure Fill the triangle on the lighting model Guro: y: = A.y; for cycle: = 1 to abs (C.y-A.y) do begin Hline_gouround (edge1 [cycle], edge2 [cycle], color1 [cycle], color2 [cycle], y); inc (y); end; With the same success here can also "Trailer" and texture mapping, but It is necessary for each point of the triangle assign texture coordinates (u, v), where u - X coordinate in the texture, and v - Y coordinate in the texture. Well, still, and four array to create. edge1u [hgt_screen]; edge1v [hgt_screen]; edge2u [hgt_screen]; edge2v [hgt_screen]; Then the procedure for visualization Textured triangle will look as follows: procedure visual_draw_texture; begin inter (A.x, C.x, abs (A.y-C.y), edge1); inter (A.x, B.x, abs (A.y-B.y), edge2); inter (B.x, C.x, abs (B.y-C.y), edge2 + abs (A.y-B.y)); inter (A.u, C.u, abs (A.y-C.y), edge1u); inter (A.u, B.u, abs (A.y-B.y), edge2u); inter (B.u, C.u, abs (B.y-C.y), edge2u + abs (A.y-B.y)); inter (A.v, C.v, abs (A.y-C.y), edge1v); inter (A.v, B.v, abs (A.y-B.y), edge2v); inter (B.v, C.v, abs (B.y-C.y), edge2v + abs (A.y-B.y)); end; And now remains only to write procedure for filling the triangle necessary texture, but for this we still need a procedure for constructing horizontal lines with color values from the texture Hline_texture (x1, x2, u1, v1, u2, v2, y), where x1 and x2 - primary and the final value of the horizontal coordinates, u1 and u2 - the initial and final X value in the texture, v1 and v2 - primary and the final value of Y and the coordinate y, which indicates where the output horizontal line on the screen. And here is the procedure for filling: y: = A.y; for cycle: = 1 to abs (C.y-A.y) do begin Hline_texture (edge1 [cycle], edge2 [cycle], edge1u [cycle], edge2u [cycle], edge1v [cycle], edge2v [cycle], y); inc (y); end; Of course in this article, I did not describe optimization methods for these procedures (this will in the next issue), but still I would like to say a few words. Given that on the Spectrum - Guro, texture mapping, etc. done with by "chunks" 4 * 4, one can see that Textures "chunks" very "big" does not There are (as the "chankovky" screen is size 64 * 48). From this it follows that it is better all have the texture memory addresses multiple of 256 (# c000, # c100, # c200 ...). I do it this way: org 25000 call init ... start: halt call action ... jp start org ($ -1) / 256 * 256 +256 texture1 incbin "morda" This is to ensure that you interpolated not only coordinates texture, and immediately address them. Senior byte of the address would be consistent coordinate Y, and the low byte of the X coordinate texture. And then interpolate senior and junior addresses texture clipboard, you already have absolute addresses. That's like until all for today. If I somehow not correctly put it, or you any questions, write to me on such addresses: 2:4635 / 8.18 or scence@usa.net. __________________________________________
Other articles:
Similar articles:
В этот день... 21 November