- Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmathrender_server.lua
More file actions
Latest commit
182 lines (130 loc) · 5.99 KB
/
Copy pathmathrender_server.lua
File metadata and controls
182 lines (130 loc) · 5.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
-- Created by The_GTA. If you use this please mention my name somewhere.
-- Script to create a render buffer out of a scene.
localstring=string;
localfunctionto_color_item(a, r, g, b)
returnstring.char(b) ..string.char(g) ..string.char(r) ..string.char(a);
end
localfunctioncolor_idx(x, y, width)
return ( ( y*width ) +x ) +1;
end
-- Creates a backbuffer which is a string of bytes that can have certain dimensions.
-- Can be merged using table.concat to be fed to texture engines.
localfunctioncreate_backbuffer( width, height, alphaClear, redClear, greenClear, blueClear )
localbbuf= {};
localitems= {};
localclear_color=to_color_item(alphaClear, redClear, greenClear, blueClear);
fory=0,height-1,1do
forx=0,width-1,1do
localcolor_idx=color_idx(x, y, width);
items[color_idx] =clear_color;
end
end
bbuf.width=width;
bbuf.height=height;
bbuf.items=items;
returnbbuf;
end
-- Sets the color of a single pixel on the backbuffer, if possible.
localfunctionset_pixel_on_bbuf(bbuf, xpos, ypos, alpha, red, green, blue)
localwidth=bbuf.width;
localheight=bbuf.height;
localypos_int=math.floor(ypos);
if ( ypos_int<1 ) or ( ypos_int>height ) then
returnfalse;
end
localxpos_int=math.floor(xpos);
if ( xpos_int<1 ) or ( xpos_int>width ) then
returnfalse;
end
localcidx=color_idx(xpos_int, ypos_int, width);
bbuf.items[cidx] =to_color_item(alpha, red, green, blue);
returntrue;
end
-- Draws a 2d plane, which resides in screen space, on the backbuffer.
-- The plane can be of any form, like a square or triangle.
localfunctiondraw_plane_on_bbuf(bbuf, plane, doDebug)
-- plane is expected to be in screen coordinates.
localscreenPlane=createPlane2D(0, 0, bbuf.width, 0, 0, bbuf.height);
-- Uncomment this to have triangle planes.
--plane.addSupremumPolynomeU( 1, -1 );
localu_inter, v_inter=plane.intersectPlane2D(screenPlane, doDebug);
ifnot ( u_inter ) then
returnfalse;
end
-- Go through each valid u coordinate and draw all the associated v coordinates.
localnum_drawn_pixels=0;
localnum_skipped_pixels=0;
form,ninipairs(u_inter) do
localmin_v=n.interval.min;
localmax_v=n.interval.max;
localmin_u=n.min_poly.minInterval(min_v, max_v);
localmax_u=n.max_poly.maxInterval(min_v, max_v);
localdiff_u= ( max_u-min_u );
localdiff_v= ( max_v-min_v );
localdiff_v_pixels=math.ceil(diff_v*bbuf.height);
localstart_x, start_y=screenPlane.transformPoint( min_u, min_v );
start_y=math.floor(start_y);
fory=0,diff_v_pixels-1,1do
localabs_y= ( start_y+y );
localabs_v= ( abs_y/bbuf.height );
-- Since we know the dimensions of the to-be-drawn surface we can process by scan-lines.
localblock_min_u=n.min_poly.evaluate( abs_v );
localblock_max_u=n.max_poly.evaluate( abs_v );
localblock_diff_u= ( block_max_u-block_min_u );
localblock_diff_u_pixels= ( block_diff_u*bbuf.width );
localblock_start_x=math.floor( block_min_u*bbuf.width );
forx=0,block_diff_u_pixels-1,1do
localabs_x= ( block_start_x+x );
localabs_u= ( abs_x/bbuf.width );
-- Idea: you could look up inside of a texture for each (abs_u, abs_v) tuple and load the real color.
-- This way we could draw real textured polygons.
set_pixel_on_bbuf(bbuf, abs_x, abs_y, 255, 100, 100, 100);
num_drawn_pixels=num_drawn_pixels+1;
end
end
end
returntrue, num_drawn_pixels, num_skipped_pixels;
end
-- It is actually undocumented, but plain pixels have two unsigned shorts that define the
-- size of the image at the tail.
localfunctionnum_to_ushort_bytes(num)
localinteger=math.floor(num);
locallower= ( integer%256 );
localupper=math.floor( integer/256 ) %256;
returnstring.char(lower, upper);
end
-- Some test planes that reside in screen space.
localtest_planes= {
createPlane2D(10, 10, 300, 10, 0, 50),
createPlane2D(400, 400, 100, 100, 100, -100),
createPlane2D(800, 800, -150, -100, 10, 50),
createPlane2D(0, 300, 150, 0, 0, 100)
};
-- Draws a backbuffer and sends it in "plain" format to all clients.
addCommandHandler("send_bbuf", function()
localbbuf=create_backbuffer(640, 480, 255, 255, 0, 50);
localdoDebug=false;
localtime_start=getTickCount();
form,ninipairs(test_planes) do
localgotToDraw, numDrawn, numSkipped=draw_plane_on_bbuf(bbuf, n, doDebug);
if ( gotToDraw ) and ( doDebug ) then
outputDebugString( "drawn " ..numDrawn.." pixels (skipped " ..numSkipped..")" );
end
end
localtime_end=getTickCount();
localms_diff= ( time_end-time_start );
outputDebugString( "render time: " ..ms_diff.."ms" );
localbbuf_width_ushort=num_to_ushort_bytes( bbuf.width );
localbbuf_height_ushort=num_to_ushort_bytes( bbuf.height );
localpixels_str=table.concat(bbuf.items);
localbbuf_string=
pixels_str..
( bbuf_width_ushort..
bbuf_height_ushort );
localplayers=getElementsByType("player");
form,ninipairs(players) do
triggerClientEvent(n, "onServerTransmitImage", root, bbuf_string);
end
outputDebugString("sent backbuffer to clients");
end
);