UV mapping does not work (for me) [SOLVED]
Closed this issue · 2 comments
The UV mapping for meshes does not work for me. The following code should, as far as I can see, show a square with a checkered pattern in blue and yellow. Instead, I just get a yellow square.
The UV mapping feature is not documented in the kiss3d documentation, and there is no example in the code examples, so I may have made a mistake in my code; in this case, please advise the correct code.
Note that the code outputs the UV texture to uvmap.png
.
By all means use this program (as corrected, if required) as an extra example in the crate.
extern crate image;
extern crate kiss3d;
extern crate nalgebra as na;
use crate::image::{GenericImage, Pixel};
use kiss3d::camera::{Camera, FirstPerson};
use kiss3d::light::Light;
use kiss3d::planar_camera::PlanarCamera;
use kiss3d::post_processing::PostProcessingEffect;
use kiss3d::resource::Texture;
use kiss3d::resource::{Mesh, TextureManager};
use kiss3d::window::{State, Window};
use na::Vector3;
use std::cell::RefCell;
use std::rc::Rc;
/** main program */
fn main() {
let mut window = Window::new("kiss3d test");
let mut state = AppState::new();
state.generate_scene(&mut window);
window.render_loop(state)
}
const UV_SIZE: u16 = 256;
/** state of the application */
struct AppState {
camera: FirstPerson,
frame_count: u32,
}
impl AppState {
fn new() -> Self {
let eye = na::Point3::new(2.0, 2.0, -10.0);
let at = na::Point3::new(2.0, 2.0, 0.0);
let mut camera = FirstPerson::new(eye.into(), at.into());
camera.set_up_axis(Vector3::new(0.0, 1.0, 0.0));
Self {
frame_count: 0,
camera,
}
}
fn generate_scene(&mut self, window: &mut Window) {
let mut group = window.add_group();
let mesh = self.make_mesh();
let mut c = group.add_mesh(Rc::new(RefCell::new(mesh)), Vector3::new(1.0, 1.0, 1.0));
let texture = self.make_texture();
c.set_texture(texture);
c.enable_backface_culling(true);
window.set_light(Light::StickToCamera);
}
fn make_mesh(&mut self) -> Mesh {
let mut uvs: Vec<na::Point2<f32>> = vec![];
let mut mesh_points: Vec<na::Point3<f32>> = vec![];
let mut mesh_triangles: Vec<na::Point3<u16>> = vec![];
for i in 0..5u16 {
for j in 0..5u16 {
let n = i * 5u16 + j;
mesh_points.push(na::Point3::new(i as f32, j as f32, 0.0));
uvs.push(na::Point2::new(
(i * UV_SIZE) as f32 / 4.0,
(j * UV_SIZE) as f32 / 4.0,
));
if i != 4 && j != 4 {
mesh_triangles.push(na::Point3::new(n, n + 1, n + 6));
mesh_triangles.push(na::Point3::new(n, n + 6, n + 5));
}
}
}
Mesh::new(mesh_points, mesh_triangles, None, Some(uvs), false)
}
fn make_texture(&mut self) -> Rc<Texture> {
let mut image = image::DynamicImage::new_rgb8(UV_SIZE as u32, UV_SIZE as u32);
for x in 0..UV_SIZE {
for y in 0..UV_SIZE {
let pixel_colour = if (x / 32) % 2 == (y / 32) % 2 {
&[255, 255, 127, 255]
} else {
&[0, 0, 127, 255]
};
image.put_pixel(x as u32, y as u32, *image::Rgba::from_slice(pixel_colour));
}
}
image.save("uvmap.png").unwrap();
let mut tm = TextureManager::new();
tm.add_image(image, "groundmesh")
}
}
impl State for AppState {
/** `step` is called for each frame */
fn step(&mut self, _window: &mut Window) {
self.frame_count += 1;
}
/** return the camera and other data for the display */
fn cameras_and_effect(
&mut self,
) -> (
Option<&mut dyn Camera>,
Option<&mut dyn PlanarCamera>,
Option<&mut dyn PostProcessingEffect>,
) {
(Some(&mut self.camera), None, None)
}
}
[package]
name = "kiss3d-window-test"
version = "0.1.0"
authors = ["martin <m.e@acm.org>"]
edition = "2018"
[dependencies]
ansi_term = "0.12.1"
image = "0.22.5"
kiss3d = "0.23.0"
nalgebra = "0.20.0"
I have tried using the github version of kiss3d, with the same issue.
kiss3d = { git = "https://github.com/sebcrozet/kiss3d" }
nalgebra = "0.21.0"
OK found the issue. The values in the UV map should have the range 0..1 but I assumed that the range was (0..n-1) where n was the dimension of my UV map (UV_SIZE in the above code i.e. 256).