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 | } |