Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | pmbaty | 1 | #version 140 |
2 | #extension GL_ARB_explicit_attrib_location : require |
||
3 | |||
4 | // Input, output variables |
||
5 | // ======================= |
||
6 | |||
7 | in vec3 v_frag_pos; |
||
8 | in vec3 v_normal; |
||
9 | in vec2 v_tex_coord; |
||
10 | |||
11 | // this is actually an integer palette index. We define it as a float to allow opengl to |
||
12 | // interpolate the value across each face. |
||
13 | in float v_color; |
||
14 | |||
15 | // 256 color mode, so each calculated color is a palette index. |
||
16 | out uint out_palette_index; |
||
17 | |||
18 | // Uniform variables |
||
19 | // ================= |
||
20 | |||
21 | // colour_buffer is an image which contains the current content of the framebuffer |
||
22 | uniform usampler2D u_colour_buffer; |
||
23 | uniform uint u_viewport_height; |
||
24 | |||
25 | uniform vec4 u_clip_planes[6]; |
||
26 | uniform int u_clip_plane_count = 0; |
||
27 | |||
28 | uniform uint u_material_flags; |
||
29 | uniform mat2x3 u_material_uv_transform; |
||
30 | uniform usampler2D u_material_texture_pixelmap; |
||
31 | uniform uint u_material_texture_enabled; |
||
32 | |||
33 | // material_blend_table is a 256x256 image which encodes 256 values of blending between new color and current color in framebuffer |
||
34 | uniform uint u_material_blend_enabled = 0u; |
||
35 | uniform usampler2D u_material_blend_table; |
||
36 | |||
37 | // material_shade_table is a 256px-wide image which encodes material_shade_table_height lit shades for each color |
||
38 | uniform usampler2D u_material_shade_table; |
||
39 | |||
40 | // how many lit shades are in the material_shade_table |
||
41 | uniform uint u_material_shade_table_height; |
||
42 | |||
43 | // For non-textured materials, defines the starting palette index |
||
44 | uniform uint u_material_index_base; |
||
45 | // For non-textured materials, defines the range of lit shades |
||
46 | uniform uint u_material_index_range; |
||
47 | |||
48 | // material_flags values |
||
49 | const uint BR_MATF_LIGHT = 1u; |
||
50 | const uint BR_MATF_PRELIT = 2u; |
||
51 | |||
52 | void main(void) { |
||
53 | |||
54 | for(int i = 0; i < u_clip_plane_count; i++) { |
||
55 | // calculate signed plane-vertex distance |
||
56 | vec4 v4 = vec4(v_frag_pos.xyz, 1); |
||
57 | float d = dot(u_clip_planes[i], v4); |
||
58 | if (d < 0) { |
||
59 | discard; |
||
60 | } |
||
61 | } |
||
62 | |||
63 | if (u_material_texture_enabled == 0u) { |
||
64 | // force palette index, no texture lookup |
||
65 | out_palette_index = u_material_index_base; |
||
66 | |||
67 | if ((u_material_flags & BR_MATF_LIGHT) != 0u) { |
||
68 | // TODO: lighting calculations based on https://rr2000.cwaboard.co.uk/R4/BRENDER/TEBK_43.HTM#0 |
||
69 | } |
||
70 | } |
||
71 | else { |
||
72 | // calculate texture uv coordinates |
||
73 | vec2 sample_coord = vec3(v_tex_coord.xy, 1) * u_material_uv_transform; |
||
74 | uint texel = texture(u_material_texture_pixelmap, sample_coord.xy).r; |
||
75 | |||
76 | // color 0 is always transparent |
||
77 | if (texel == 0u) { |
||
78 | discard; |
||
79 | } |
||
80 | |||
81 | if ((u_material_flags & BR_MATF_LIGHT) != 0u) { |
||
82 | if ((u_material_flags & BR_MATF_PRELIT) != 0u) { |
||
83 | // BR_MATF_PRELIT means the light value comes from the vertex color attribute |
||
84 | uint calculated_lit_value = uint(v_color) / u_material_shade_table_height; |
||
85 | out_palette_index = texelFetch(u_material_shade_table, ivec2(texel, calculated_lit_value), 0).r; |
||
86 | } else { |
||
87 | // TODO: lighting calculations based on https://rr2000.cwaboard.co.uk/R4/BRENDER/TEBK_43.HTM#0 |
||
88 | uint calculated_lit_value = 0u; |
||
89 | out_palette_index = texelFetch(u_material_shade_table, ivec2(texel, calculated_lit_value), 0).r; |
||
90 | } |
||
91 | } else { |
||
92 | // no lighting |
||
93 | out_palette_index = texel; |
||
94 | } |
||
95 | } |
||
96 | |||
97 | if (u_material_blend_enabled == 1u) { |
||
98 | // u_colour_buffer is upside down from opengl perspective. We need to sample it upside down. |
||
99 | uint current_framebuffer_color = texelFetch(u_colour_buffer, ivec2(gl_FragCoord.x, u_viewport_height - gl_FragCoord.y), 0).r; |
||
100 | out_palette_index = texelFetch(u_material_blend_table, ivec2(out_palette_index, current_framebuffer_color), 0).r; |
||
101 | } |
||
102 | |||
103 | // HACK: Pick another black color instead of palette index 0 so we can detect which pixels have been drawn this frame in FlushBuffers |
||
104 | if (out_palette_index == 0u) { |
||
105 | out_palette_index = 240u; |
||
106 | } |
||
107 | } |