~luyu/comp5411-rendering-project

eedaa8e3f3dc5705284180284b396787b82d3a58 — Luyu Cheng a month ago ddb12f0 main
feat: give more textures
M src/render/mod.rs => src/render/mod.rs +38 -16
@@ 1,4 1,5 @@
use cgmath::Matrix4;
use cgmath::Point3;
use cgmath::SquareMatrix;
use cgmath::Vector3;
use std::cell::Cell;


@@ 66,11 67,13 @@ pub fn render(world_map: Rc<WorldMap>) -> Result<(), JsValue> {
    let program = gl::link_program(&context, &vert_shader, &frag_shader)?;
    context.use_program(Some(&program));

    let cube = model::Model::cube();
    let building_cube = model::Model::cube(1, 4, 3);
    let grass_cube = model::Model::cube(5, 5, 5);
    let road_cube = model::Model::cube(6, 6, 6);

    if cfg!(debug_assertions) {
        cube.debug();
        web_sys::console::log_1(&format!("Model validation: {:?}", cube.check()).into());
        building_cube.debug();
        web_sys::console::log_1(&format!("Model validation: {:?}", building_cube.check()).into());
    }

    let model_uniform_location = gl::get_uniform_location!(context, program, "model")?;


@@ 90,25 93,25 @@ pub fn render(world_map: Rc<WorldMap>) -> Result<(), JsValue> {
    let texture_coordinates_buffer = gl::prepare_buffer!(
        context,
        WebGl2RenderingContext::ARRAY_BUFFER,
        cube.texture_coordinates,
        building_cube.texture_coordinates,
        Float32Array
    );
    let position_buffer = gl::prepare_buffer!(
        context,
        WebGl2RenderingContext::ARRAY_BUFFER,
        cube.vertices,
        building_cube.vertices,
        Float32Array
    );
    let normal_buffer = gl::prepare_buffer!(
        context,
        WebGl2RenderingContext::ARRAY_BUFFER,
        cube.normals,
        building_cube.normals,
        Float32Array
    );
    let index_buffer = gl::prepare_buffer!(
        context,
        WebGl2RenderingContext::ELEMENT_ARRAY_BUFFER,
        cube.indices,
        building_cube.indices,
        Uint16Array
    );



@@ 169,9 172,12 @@ pub fn render(world_map: Rc<WorldMap>) -> Result<(), JsValue> {
    let drag_mode = Rc::new(Cell::new(DragMode::None));
    // The camera setup.
    let model = Rc::new(Cell::new(cgmath::Matrix4::identity()));
    let view = Rc::new(Cell::new(Matrix4::from_translation(cgmath::Vector3::new(
        0.0, -8.0, -48.0,
    ))));
    let view = Matrix4::look_at_rh(
        Point3::new(0.0, 20.0, -48.0),
        Point3::new(0.0, 0.0, 0.0),
        Vector3::unit_y(),
    );
    let view = Rc::new(Cell::new(view));
    {
        let drag_mode = drag_mode.clone();
        let closure = Closure::wrap(Box::new(move |event: web_sys::PointerEvent| {


@@ 294,13 300,29 @@ pub fn render(world_map: Rc<WorldMap>) -> Result<(), JsValue> {

            let half_width = world_map.tile.len_of(ndarray::Axis(0)) as f32 / 2.0;
            let half_height = world_map.tile.len_of(ndarray::Axis(1)) as f32 / 2.0;
            for ((i, j), num_cubes) in world_map.tile.indexed_iter() {
                if *num_cubes == 0 {
                    continue;
                }
            for ((i, j), cube_type) in world_map.tile.indexed_iter() {
                // We will scale the cube to half its size.
                let scale = Matrix4::from_scale(0.5);
                for k in 0..*num_cubes {
                let mut scale = Matrix4::from_scale(0.5);
                let (cube, height) = match *cube_type {
                    WorldMap::BUILDING => (&building_cube, 3),
                    WorldMap::GRASS => (&grass_cube, 1),
                    WorldMap::ROAD => {
                        let s = Matrix4::<f32>::from_nonuniform_scale(1.0, 1.1, 1.0);
                        scale = s * scale;
                        (&road_cube, 1)
                    }
                    _ => continue,
                };
                context.bind_buffer(WebGl2RenderingContext::ARRAY_BUFFER, Some(&texture_coordinates_buffer));
                unsafe {
                    let array_buffer_view = js_sys::Float32Array::view(&cube.texture_coordinates);
                    context.buffer_data_with_array_buffer_view(
                        WebGl2RenderingContext::ARRAY_BUFFER,
                        &array_buffer_view,
                        WebGl2RenderingContext::DYNAMIC_DRAW,
                    );
                }
                for k in 0..height {
                    // Then we will translate it to the right position.
                    let translation = Matrix4::from_translation(Vector3::new(
                        i as f32 - half_width,

M src/render/model.rs => src/render/model.rs +14 -4
@@ 5,8 5,12 @@ pub struct Model {
    pub texture_coordinates: Vec<f32>,
}

fn use_texture(x: f32, y: f32) -> [f32; 8] {
    [x + 0.25, y, x + 0.25, y + 0.25, x, y, x, y + 0.25]
}

impl Model {
    pub fn cube() -> Model {
    pub fn cube(x_texture: u32, y_texture: u32, z_texture: u32) -> Model {
        let mut vertices = Vec::with_capacity(4 * 6 * 3);
        let mut normals = Vec::with_capacity(4 * 6 * 3);
        let mut indices = Vec::with_capacity(6 * 6);


@@ 45,13 49,19 @@ impl Model {
            // Generate texture coordinates for the face.
            match axis0 {
                0 => {
                    texture_coordinates.extend_from_slice(&[1.0, 0.0, 1.0, 0.5, 0.5, 0.0, 0.5, 0.5]);
                    let x = (x_texture % 4) as f32 * 0.25;
                    let y = (x_texture / 4) as f32 * 0.25;
                    texture_coordinates.extend_from_slice(&use_texture(x, y));
                }
                1 => {
                    texture_coordinates.extend_from_slice(&[0.5, 0.5, 0.5, 1.0, 1.0, 0.5, 1.0, 1.0]);
                    let x = (y_texture % 4) as f32 * 0.25;
                    let y = (y_texture / 4) as f32 * 0.25;
                    texture_coordinates.extend_from_slice(&use_texture(x, y));
                }
                2 => {
                    texture_coordinates.extend_from_slice(&[0.5, 0.0, 0.5, 0.5, 1.0, 0.0, 1.0, 0.5]);
                    let x = (z_texture % 4) as f32 * 0.25;
                    let y = (z_texture / 4) as f32 * 0.25;
                    texture_coordinates.extend_from_slice(&use_texture(x, y));
                }
                _ => (),
            }

M src/render/shader.vert => src/render/shader.vert +2 -2
@@ 25,8 25,8 @@ void main() {
    vTextureCoord = textureCoord;

    // Compute the lighing effect.
    vec3 ambientLight = vec3(0.3, 0.3, 0.3);
    vec3 directionalLightColor = vec3(1.0, 1.0, 1.0);
    vec3 ambientLight = vec3(0.5, 0.5, 0.5);
    vec3 directionalLightColor = vec3(0.8, 0.8, 0.8);
    vec3 directionalVector = normalize(vec3(0.85, 0.8, 0.75));
    vec4 transformedNormal = normalMatrix * vec4(normal, 1.0);
    float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0);

M src/render/texture.png => src/render/texture.png +0 -0
M src/wfc/mod.rs => src/wfc/mod.rs +4 -4
@@ 54,10 54,10 @@ pub fn generate() -> Result<WorldMap, String> {
                for tile_row in 0..3 {
                    for tile_col in 0..3 {
                        let height = match tile[tile_row][tile_col] {
                            '@' => 5,
                            '.' => 1,
                            '-' => 2,
                            '=' => 3,
                            '@' => WorldMap::BUILDING,
                            '.' => WorldMap::GRASS,
                            '-' => WorldMap::ROAD,
                            '=' => WorldMap::ROAD,
                            _ => 0,
                        };
                        let x = (col + 6) * 3 + tile_col as isize;

M src/world.rs => src/world.rs +4 -0
@@ 15,4 15,8 @@ impl WorldMap {
        }
        WorldMap { tile }
    }

    pub const GRASS: u32 = 3;
    pub const ROAD: u32 = 4;
    pub const BUILDING: u32 = 5;
}