njin
Engine 2D gọn nhẹ để tự tay làm game theo ý mình. Vibe coding cũng ổn luôn
Loading...
Searching...
No Matches
Đồ họa 3D

Camera phối cảnh, hình khối SDF, model glTF, instancing, ánh sáng có bóng đổ, hạt, chọn vật bằng tia. Tiếp...

Classes

struct  njin::camera3d
 Camera phối cảnh cho begin_3d(). Tiếp...
struct  njin::light3d
 Ánh sáng chung của cảnh 3D: mặt trời (ánh sáng hướng), ánh sáng nền, bóng đổ của mặt trời và sương mù. Tiếp...
struct  njin::light3d_source
 Một đèn điểm hoặc đèn nón. Tiếp...
struct  njin::material3d
 Bề mặt của các hình 3D vẽ sau material3d_set(). Tiếp...
struct  njin::shape3d
 Một hình cơ bản vẽ bằng SDF (hàm khoảng cách có dấu), dùng với draw_shape3d(). Tiếp...
struct  njin::sdf_part
 Một phần của hình ghép SDF (draw_sdf_blend()): hình nón bo tròn nối a với b, bán kính ra ở a và rb ở b (bằng nhau là viên nang, a trùng b là hình cầu). Tiếp...
struct  njin::model_load_desc
 Cách model_load() nạp một phần của file glTF: bỏ hay chỉ giữ một số node, và gộp các mesh cùng vật liệu thành một. Tiếp...
struct  njin::mesh3d_data
 Một lưới tam giác do game tự dựng, cho model_create(): địa hình sinh theo seed, hình ghép lúc chạy. Tiếp...
struct  njin::skinned_mesh3d_data
 Một lưới có xương do game tự ghép lúc chạy, cho model_create_skinned(): nhân vật ghép từ nhiều mảnh (đầu, thân, tay, tóc...) theo một bộ gen, mà không xuất sẵn một file cho mỗi tổ hợp. Tiếp...
struct  njin::model_lod_desc
 Cách model_lod_build() làm các mức chi tiết (LOD) của một model. Tiếp...
struct  njin::transform3d
 Vị trí, hướng và tỉ lệ của một vật 3D. Tiếp...
struct  njin::model_material
 Vật liệu của một phần model: mỗi file glTF/OBJ có một hay nhiều vật liệu, mỗi mesh dùng một. Tiếp...
struct  njin::model_pose
 Tư thế của một model có xương khi vẽ: animation nào, ở giây thứ mấy, và (tùy chọn) trộn với animation thứ hai để chuyển mượt giữa hai động tác. Tiếp...
struct  njin::model_recolor
 Màu thay cho màu gốc của một vật liệu, chỉ trong một lần vẽ. Tiếp...
struct  njin::bone_pose3d
 Một xương ở một tư thế: vị trí và ba trục của nó trong không gian của model (trước transform của lần vẽ), như draw_model_anim() đặt nó. Tiếp...
struct  njin::ray3d
 Một tia trong thế giới 3D, dùng để chọn vật bằng chuột, bắn đạn, kiểm tra tầm nhìn. Tiếp...
struct  njin::ray3d_hit
 Kết quả khi tia chạm một vật. Tiếp...
struct  njin::fx3d
 Hiệu ứng cho các hình 3D vẽ sau fx3d_set(): nháy màu và tan biến, như njin::flash_fx và njin::dissolve_fx của sprite. Tiếp...
struct  njin::particles3d_desc
 Cách đặt một loạt hạt vào thế giới 3D, dùng với particles3d_spawn(). Tiếp...
struct  njin::model3d
 Component: một model vẽ tại njin::transform3d của entity, trong mọi lần vẽ 3D có camera3d::entities (engine thêm nó ở end_3d(), cùng các lệnh vẽ của game). Tiếp...
struct  njin::shape3d_render
 Component: một hình SDF (như draw_shape3d()) vẽ tại njin::transform3d của entity, trong mọi lần vẽ 3D có camera3d::entities. Tiếp...

Enumerations

enum  njin::light3d_kind { njin::light3d_point , njin::light3d_spot }
 Loại đèn của njin::light3d_source. Tiếp...
enum  njin::shape3d_kind {
  njin::shape3d_sphere , njin::shape3d_box , njin::shape3d_capsule , njin::shape3d_cylinder ,
  njin::shape3d_torus
}
 Loại hình của njin::shape3d. Tiếp...
enum  njin::mesh3d_kind {
  njin::mesh3d_cube , njin::mesh3d_sphere , njin::mesh3d_plane , njin::mesh3d_cylinder ,
  njin::mesh3d_sphere_low , njin::mesh3d_cylinder_low
}
 Hình lưới có sẵn để vẽ nhiều bản một lúc bằng draw_instanced3d(). Tiếp...

Các hàm

void njin::begin_3d (context &ctx, const camera3d &camera)
 Bắt đầu vẽ 3D qua camera.
void njin::begin_3d (context &ctx, const camera3d &camera, render_texture_handle target, rgba clear)
 Như begin_3d() nhưng vẽ lần 3D này vào render texture target thay vì lên màn hình: một con mắt thứ hai trong cùng frame (camera của một nhân vật, gương chiếu hậu).
void njin::end_3d (context &ctx)
 Kết thúc vẽ 3D và quay về vẽ 2D trong không gian thế giới.
void njin::light3d_set (context &ctx, const light3d &light)
 Đặt ánh sáng chung.
light3d njin::light3d_get (const context &ctx)
 Ánh sáng chung đang dùng.
void njin::light3d_add (context &ctx, const light3d_source &light)
 Thêm một đèn cho lần vẽ 3D đang mở.
void njin::material3d_set (context &ctx, const material3d &material)
 Đặt bề mặt cho các hình 3D vẽ sau lệnh này, đến lần gọi tiếp theo hoặc end_3d().
void njin::draw_cube3d (const context &ctx, vec3 center, vec3 size, rgba color)
 Vẽ hộp đặc, các cạnh song song với trục.
void njin::draw_sphere3d (const context &ctx, vec3 center, f32 radius, rgba color)
 Vẽ hình cầu đặc.
void njin::draw_plane3d (const context &ctx, vec3 center, vec2 size, rgba color)
 Vẽ mặt phẳng nằm ngang (song song mặt xz), mặt trên hướng +y.
void njin::draw_cylinder3d (const context &ctx, vec3 from, vec3 to, f32 radius, rgba color)
 Vẽ hình trụ đặc nối hai điểm (lưới tam giác).
void njin::draw_capsule3d (const context &ctx, vec3 from, vec3 to, f32 radius, rgba color)
 Vẽ viên nang (capsule) đặc bằng lưới tam giác: hình trụ nối hai điểm, hai đầu tròn.
void njin::draw_shape3d (const context &ctx, const shape3d &shape, rgba color)
 Vẽ một hình SDF mịn.
void njin::draw_sdf_blend (const context &ctx, const sdf_part *parts, u32 count, f32 blend, rgba color)
 Vẽ nhiều phần SDF hòa làm một khối liền (smooth min): chỗ hai phần gặp nhau được đắp đầy mượt thay vì gãy góc, như nặn bằng đất sét.
model_handle njin::model_load (context &ctx, const char *path)
 Nạp model 3D từ file glTF (.glb, .gltf) hoặc OBJ.
model_handle njin::model_load (context &ctx, const model_load_desc &desc)
 Nạp model như model_load(), với bộ lọc node và gộp mesh của desc.
void njin::model_unload (context &ctx, model_handle handle)
 Giải phóng model cùng các texture của nó.
model_handle njin::model_create (context &ctx, const mesh3d_data &mesh)
 Tạo model từ một lưới tam giác trong bộ nhớ, rồi dùng như model nạp từ file: draw_model(), draw_instanced3d(), model_material_set(), ray3d_model(), model_unload().
model_handle njin::model_create_skinned (context &ctx, const skinned_mesh3d_data &mesh)
 Tạo model có xương từ một lưới trong bộ nhớ, dùng bộ xương và animation của model khác (một thư viện clip nạp một lần cho mọi nhân vật).
i32 njin::model_lod_build (context &ctx, model_handle handle, const model_lod_desc &desc={})
 Tạo các mức chi tiết cho model: bản giản lược, ít tam giác hơn, được vẽ thay model khi nó nhỏ trên màn hình.
i32 njin::model_material_count (const context &ctx, model_handle handle)
 Số vật liệu của model.
i32 njin::model_material_find (const context &ctx, model_handle handle, const char *name)
 Tìm vật liệu theo tên đặt trong file glTF.
model_material njin::model_material_get (const context &ctx, model_handle handle, i32 index)
 Vật liệu thứ index của model.
void njin::model_material_set (context &ctx, model_handle handle, i32 index, const model_material &material)
 Đặt vật liệu thứ index của model, cho mọi lần vẽ sau đó.
void njin::draw_model (const context &ctx, model_handle handle, const transform3d &transform, rgba tint=colors::white)
 Vẽ model tại transform, với vật liệu của nó (model_material_set()).
i32 njin::model_anim_count (const context &ctx, model_handle handle)
 Số animation xương trong file của model (glTF có skin).
i32 njin::model_anim_find (const context &ctx, model_handle handle, const char *name)
 Tìm animation theo tên đặt trong Blender (tên action khi xuất glTF).
const char * njin::model_anim_name (const context &ctx, model_handle handle, i32 index)
 Tên của animation thứ index.
f32 njin::model_anim_duration (const context &ctx, model_handle handle, i32 index)
 Độ dài của animation thứ index, giây.
void njin::draw_model_anim (const context &ctx, model_handle handle, const transform3d &transform, const model_pose &pose, rgba tint=colors::white)
 Vẽ model có xương ở tư thế pose.
void njin::draw_model_anim (const context &ctx, model_handle handle, const transform3d &transform, const model_pose &pose, rgba tint, const model_recolor &recolor)
 Như draw_model_anim() ở trên, và vật liệu recolor.material mang màu recolor.color trong lần vẽ này.
void njin::draw_model_anim (const context &ctx, model_handle handle, const transform3d &transform, const model_pose &pose, rgba tint, const model_recolor *recolors, u32 count)
 Như draw_model_anim() ở trên, với nhiều vật liệu đổi màu một lúc: bảng màu riêng của một nhân vật (da, tóc, áo, quần) trên một model dùng chung.
i32 njin::model_bone_count (const context &ctx, model_handle handle)
 Số xương của model (0 nếu không có xương hay handle không hợp lệ).
const char * njin::model_bone_name (const context &ctx, model_handle handle, i32 bone)
 Tên một xương, như trong file glTF.
i32 njin::model_bone_find (const context &ctx, model_handle handle, const char *name)
 Tìm xương theo tên (so đúng cả chuỗi).
i32 njin::model_bone_parent (const context &ctx, model_handle handle, i32 bone)
 Xương cha của bone trong bộ xương, để đi lên chuỗi xương (IK: đùi, cẳng chân, bàn chân) hay biết xương nào nằm dưới xương nào.
bool njin::model_bone_bounds (const context &ctx, model_handle handle, i32 bone, bool children, vec3 *min, vec3 *max)
 Hộp bao phần da mà xương bone kéo mạnh nhất (cả các xương con nếu children), ở tư thế gốc trong file: theo các trục của model, tính từ gốc của xương.
i32 njin::model_bone_points (const context &ctx, model_handle handle, i32 bone, bool children, vec3 *out, i32 count)
 Các đỉnh của phần da đó (như model_bone_bounds()), cùng hệ trục: theo các trục của model ở tư thế gốc, tính từ gốc của xương.
i32 njin::model_morph_count (const context &ctx, model_handle handle)
 Số morph target (blend shape) của model: các target của glTF (biểu cảm mặt, cơ phồng, cửa mở), theo tên.
const char * njin::model_morph_name (const context &ctx, model_handle handle, i32 morph)
 Tên của morph thứ morph: tên trong extras.targetNames của file, hoặc "<tên mesh>.<số>" khi file không đặt tên.
i32 njin::model_morph_find (const context &ctx, model_handle handle, const char *name)
 Tìm morph theo tên (so đúng cả chuỗi).
i32 njin::model_morph_weights (const context &ctx, model_handle handle, const model_pose &pose, f32 *out, i32 count)
 Trọng số của mọi morph ở tư thế pose, đúng như lần vẽ sẽ dùng (mặc định, animation, rồi pose.morph_weights).
bone_pose3d njin::model_bone_pose (const context &ctx, model_handle handle, const model_pose &pose, i32 bone)
 Xương bone ở tư thế pose (cùng cách tính với draw_model_anim(), kể cả khi trộn hai animation), để gắn đồ vào tay, đặt vùng trúng đòn theo xương, hay biết bàn chân đang ở đâu.
ray3d njin::camera3d_ray (const context &ctx, const camera3d &camera, vec2 screen)
 Tia từ camera đi qua một điểm trên màn hình, để chọn vật dưới chuột: camera3d_ray(ctx, cam, mouse_pos(ctx)).
vec2 njin::camera3d_to_screen (const context &ctx, const camera3d &camera, vec3 point, bool *visible=nullptr)
 Vị trí trên màn hình của một điểm 3D, để đặt nhãn hay thanh máu trên đầu nhân vật.
ray3d_hit njin::ray3d_box (const ray3d &ray, vec3 center, vec3 size)
 Tia với hộp có các cạnh song song với trục.
ray3d_hit njin::ray3d_sphere (const ray3d &ray, vec3 center, f32 radius)
 Tia với hình cầu.
ray3d_hit njin::ray3d_plane (const ray3d &ray, vec3 point, vec3 normal)
 Tia với mặt phẳng vô hạn qua point, pháp tuyến normal.
ray3d_hit njin::ray3d_shape (const ray3d &ray, const shape3d &shape)
 Tia với một hình SDF, đúng như draw_shape3d() vẽ nó (kể cả khi xoay, bo góc).
ray3d_hit njin::ray3d_model (const context &ctx, const ray3d &ray, model_handle model, const transform3d &transform)
 Tia với từng tam giác của một model đặt tại transform, như draw_model() vẽ nó.
ray3d_hit njin::ray3d_model (const context &ctx, const ray3d &ray, model_handle model, const transform3d &transform, const model_pose &pose)
 Như bản trên, nhưng mesh có morph target được thử ở hình của pose: trọng số mặc định, animation và pose.morph_weights, đúng như draw_model_anim() vẽ nó (model_morph_weights()).
void njin::draw_instanced3d (const context &ctx, mesh3d_kind mesh, instance_buffer_handle buffer, u32 first, u32 count, shader_handle shader={})
 Vẽ count bản của một hình có sẵn bằng một lệnh vẽ, mỗi bản đặt theo dữ liệu của nó trong một bộ đệm instance (instance_buffer_create(), instance_buffer_upload(), như draw_instanced() của 2D).
void njin::draw_instanced3d (const context &ctx, model_handle model, instance_buffer_handle buffer, u32 first, u32 count, shader_handle shader={})
 Vẽ count bản của một model bằng một lệnh vẽ cho mỗi phần của model, cùng quy ước dữ liệu instance với bản trên.
void njin::draw_instanced3d (const context &ctx, model_handle model, instance_buffer_handle buffer, u32 first, u32 count, const model_pose &pose, shader_handle shader={})
 Như bản trên, với morph target theo pose (trọng số mặc định, animation và pose.morph_weights, như draw_model_anim()): mọi instance của lệnh này có cùng một hình đã morph.
void njin::fx3d_set (context &ctx, const fx3d &fx)
 Đặt hiệu ứng cho các hình 3D vẽ sau lệnh này, đến lần gọi tiếp theo hoặc end_3d().
void njin::particles3d_spawn (context &ctx, const particle_emitter &emitter, vec3 pos, i32 count, const particles3d_desc &desc={})
 Phát một loạt count hạt tại pos, dùng lại một emitter 2D: các mẫu njin::fx (explosion(), sparks(), dust()...) hay emitter tự cấu hình.
void njin::particles3d_clear (context &ctx)
 Xóa mọi hạt 3D đang bay, ví dụ khi đổi màn.
i32 njin::particles3d_count (const context &ctx)
 Số hạt 3D đang sống.

Các biến

constexpr i32 njin::light3d_max = 16
 Số đèn tối đa trong một lần vẽ 3D. Đèn thêm quá số này bị bỏ qua.
constexpr i32 njin::light3d_shadow_max = 4
 Số đèn điểm và đèn nón tối đa được đổ bóng trong một lần vẽ 3D.
constexpr u32 njin::sdf_blend_max = 32
 Số phần tối đa của một hình ghép SDF.

Mô tả chi tiết

Camera phối cảnh, hình khối SDF, model glTF, instancing, ánh sáng có bóng đổ, hạt, chọn vật bằng tia.

Thông tin về Enumeration Type

◆ light3d_kind

Loại đèn của njin::light3d_source.

Enumerator
light3d_point 

Đèn điểm: tỏa đều mọi hướng (bóng đèn, đuốc).

light3d_spot 

Đèn nón: chiếu theo direction trong một nón (đèn pin, đèn sân khấu).

◆ shape3d_kind

Loại hình của njin::shape3d.

Enumerator
shape3d_sphere 

Hình cầu: radius.

shape3d_box 

Hộp: size, bo cạnh theo rounding.

shape3d_capsule 

Viên nang dọc trục y: radius, height (cả hai đầu tròn).

shape3d_cylinder 

Hình trụ dọc trục y: radius, height, bo cạnh theo rounding.

shape3d_torus 

Hình xuyến nằm trên mặt xz: radius (tới tâm ống), thickness (bán kính ống).

◆ mesh3d_kind

Hình lưới có sẵn để vẽ nhiều bản một lúc bằng draw_instanced3d().

Enumerator
mesh3d_cube 

Hộp 1 x 1 x 1, tâm ở gốc.

mesh3d_sphere 

Cầu bán kính 1, tâm ở gốc.

mesh3d_plane 

Mặt 1 x 1 trên mặt xz, hướng lên +y.

mesh3d_cylinder 

Trụ bán kính 1, đáy ở gốc, cao 1 theo +y.

mesh3d_sphere_low 

Như mesh3d_sphere nhưng ít mặt (khoảng 100 tam giác, bản thường khoảng 3000): cho hàng nghìn vật nhỏ trên màn hình (đầu lính trong một đám đông, hạt khói), nơi bản mịn chỉ làm GPU vẽ thêm những cạnh không ai thấy.

mesh3d_cylinder_low 

Như mesh3d_cylinder nhưng 8 cạnh thay vì 48, cùng lý do.

Thông tin về hàm

◆ begin_3d() [1/2]

void njin::begin_3d ( context & ctx,
const camera3d & camera )

Bắt đầu vẽ 3D qua camera.

Kết thúc bằng end_3d().

Chỉ gọi trong phase_render. Giữa hai lệnh, các hàm draw_*3d và draw_model() vẽ có depth test, trên nền những gì đã vẽ trước đó trong frame. Tỉ lệ khung hình lấy theo screen_size(), nên virtual size vẫn đúng. Gọi lồng nhau hoặc gọi ngoài phase_render bị bỏ qua, kèm cảnh báo.

camera_shake() cũng rung camera này: shake_config::max_offset (pixel màn hình) thành góc lệch hướng nhìn, shake_config::max_angle thành góc nghiêng. Các hiệu ứng chung khác áp dụng cho 3D như cho 2D, không cần gì thêm: hitstop(), screen_flash(), post_fx_set() và camera_set_post_shader().

Các tham số
ctxContext của engine.
cameraCamera dùng cho lần vẽ này.

◆ begin_3d() [2/2]

void njin::begin_3d ( context & ctx,
const camera3d & camera,
render_texture_handle target,
rgba clear )

Như begin_3d() nhưng vẽ lần 3D này vào render texture target thay vì lên màn hình: một con mắt thứ hai trong cùng frame (camera của một nhân vật, gương chiếu hậu).

Xóa target bằng màu clear trước, tỉ lệ khung hình lấy theo kích thước của nó. Cũng chỉ gọi trong phase_render và kết thúc bằng end_3d(); nhiều lần như vậy trong một frame được, mỗi lần một lượt vẽ đầy đủ (kể cả bóng đổ nếu light3d_set() bật), nên tốn như vẽ cảnh thêm một lần.

camera_shake() không rung camera này, gizmo không vẽ vào đây, và độ sâu của nó không dùng cho post_fx::dof. Đèn (light3d_add()) phải thêm lại cho lần vẽ này. Ảnh trong render texture lưu ngược trục dọc như mọi render texture.

Các tham số
ctxContext của engine.
cameraCamera dùng cho lần vẽ này.
targetRender texture nhận ảnh. Handle không hợp lệ thì bỏ qua, kèm cảnh báo.
clearMàu xóa target trước khi vẽ.

◆ end_3d()

void njin::end_3d ( context & ctx)

Kết thúc vẽ 3D và quay về vẽ 2D trong không gian thế giới.

Không có begin_3d() tương ứng thì không làm gì. Nếu game quên gọi, engine tự đóng ở cuối phase_render và cảnh báo.

Các tham số
ctxContext của engine.

◆ light3d_set()

void njin::light3d_set ( context & ctx,
const light3d & light )

Đặt ánh sáng chung.

Có hiệu lực từ begin_3d() tiếp theo.

Các tham số
ctxContext của engine.
lightÁnh sáng mới.

◆ light3d_get()

light3d njin::light3d_get ( const context & ctx)

Ánh sáng chung đang dùng.

Các tham số
ctxContext của engine.
Giá trị trả về
Giá trị đặt bởi light3d_set(), hoặc mặc định của njin::light3d.

◆ light3d_add()

void njin::light3d_add ( context & ctx,
const light3d_source & light )

Thêm một đèn cho lần vẽ 3D đang mở.

Gọi mỗi frame, giữa begin_3d() và end_3d() (thứ tự với các lệnh vẽ không quan trọng: mọi đèn chiếu lên mọi hình của lần vẽ).

Các tham số
ctxContext của engine.
lightĐèn.

◆ material3d_set()

void njin::material3d_set ( context & ctx,
const material3d & material )

Đặt bề mặt cho các hình 3D vẽ sau lệnh này, đến lần gọi tiếp theo hoặc end_3d().

material3d_set(ctx, {}) là về mặc định. Chỉ shader có sẵn của engine dùng giá trị này.

Các tham số
ctxContext của engine.
materialBề mặt.

◆ draw_cube3d()

void njin::draw_cube3d ( const context & ctx,
vec3 center,
vec3 size,
rgba color )

Vẽ hộp đặc, các cạnh song song với trục.

Như mọi hàm vẽ 3D, chỉ có tác dụng giữa begin_3d() và end_3d(): lệnh vẽ được ghi lại và vẽ thật ở end_3d() (sau khi tính bóng đổ), theo đúng thứ tự gọi. Hình được chiếu sáng theo light3d_set(), light3d_add() và material3d_set(). Nếu game đã bật shader của mình bằng shader_begin(), hình vẽ bằng shader đó; engine đặt sẵn các uniform vec3 lightDir, lightColor, ambient, viewPos (vị trí camera), fogColor, uniform float fogDensity (sương như light3d_set()) và uniform int instanceFloats (0 khi không vẽ instanced) nếu shader khai báo chúng, và gắn các ảnh phụ đặt bằng shader_set_texture(). Attribute và các uniform mvp, matModel, matNormal, colDiffuse theo tên chuẩn của raylib. Vì hình vẽ ở end_3d(), uniform mà game đặt bằng shader_set_* lấy giá trị cuối cùng trước end_3d().

Các tham số
ctxContext của engine.
centerTâm hộp.
sizeKích thước theo x, y, z.
colorMàu.

◆ draw_sphere3d()

void njin::draw_sphere3d ( const context & ctx,
vec3 center,
f32 radius,
rgba color )

Vẽ hình cầu đặc.

Các tham số
ctxContext của engine.
centerTâm.
radiusBán kính.
colorMàu.

◆ draw_plane3d()

void njin::draw_plane3d ( const context & ctx,
vec3 center,
vec2 size,
rgba color )

Vẽ mặt phẳng nằm ngang (song song mặt xz), mặt trên hướng +y.

Các tham số
ctxContext của engine.
centerTâm.
sizeKích thước theo x và z.
colorMàu.

◆ draw_cylinder3d()

void njin::draw_cylinder3d ( const context & ctx,
vec3 from,
vec3 to,
f32 radius,
rgba color )

Vẽ hình trụ đặc nối hai điểm (lưới tam giác).

Dùng cho vệt đạn, dây, cột.

Các tham số
ctxContext của engine.
fromTâm đáy thứ nhất.
toTâm đáy thứ hai.
radiusBán kính.
colorMàu.

◆ draw_capsule3d()

void njin::draw_capsule3d ( const context & ctx,
vec3 from,
vec3 to,
f32 radius,
rgba color )

Vẽ viên nang (capsule) đặc bằng lưới tam giác: hình trụ nối hai điểm, hai đầu tròn.

Nối được hai điểm bất kỳ; cần viền tròn mịn khi nhìn gần thì dùng draw_shape3d() với njin::shape3d_capsule.

Các tham số
ctxContext của engine.
fromTâm nửa cầu thứ nhất.
toTâm nửa cầu thứ hai.
radiusBán kính.
colorMàu.

◆ draw_shape3d()

void njin::draw_shape3d ( const context & ctx,
const shape3d & shape,
rgba color )

Vẽ một hình SDF mịn.

Như các hình khác, chỉ có tác dụng giữa begin_3d() và end_3d(), theo material3d_set() và fx3d_set() lúc gọi. Luôn vẽ bằng shader của engine (shader của game bật bằng shader_begin() không áp dụng), và không dán ảnh.

// Nhân vật hình viên nang, bóng như nhựa, viền sáng xanh nhạt.
njin::material3d_set(ctx, {.specular = 0.6f, .shininess = 60.0f, .rim = {0.55f, 0.75f, 1.0f, 0.45f}});
njin::draw_shape3d(ctx, {.kind = njin::shape3d_capsule, .position = pos, .radius = 0.28f, .height = 0.9f},
void material3d_set(context &ctx, const material3d &material)
Đặt bề mặt cho các hình 3D vẽ sau lệnh này, đến lần gọi tiếp theo hoặc end_3d().
void draw_shape3d(const context &ctx, const shape3d &shape, rgba color)
Vẽ một hình SDF mịn.
@ shape3d_capsule
Viên nang dọc trục y: radius, height (cả hai đầu tròn).
Definition njin_3d.h:251
constexpr rgba blue
Xanh dương.
Definition _math.h:238
Các tham số
ctxContext của engine.
shapeHình.
colorMàu.

◆ draw_sdf_blend()

void njin::draw_sdf_blend ( const context & ctx,
const sdf_part * parts,
u32 count,
f32 blend,
rgba color )

Vẽ nhiều phần SDF hòa làm một khối liền (smooth min): chỗ hai phần gặp nhau được đắp đầy mượt thay vì gãy góc, như nặn bằng đất sét.

Nhân vật ghép từ đầu, cổ, thân và các đoạn tay chân, rồi đặt lại các phần mỗi frame theo tư thế, vẫn liền mạch khi cử động.

Như draw_shape3d(): tính trên từng điểm ảnh nên viền mịn ở mọi cỡ, nhận ánh sáng, đổ và nhận bóng, theo material3d_set() và fx3d_set() lúc gọi. Mỗi hình ghép là một lệnh vẽ; tốn theo số điểm ảnh nó phủ nhân số phần.

// Một cánh tay: bắp tay, cẳng tay, bàn tay nối liền.
const njin::sdf_part arm[] = {{.a = shoulder, .b = elbow, .ra = 0.05f, .rb = 0.04f},
{.a = elbow, .b = wrist, .ra = 0.04f, .rb = 0.03f},
{.a = wrist, .b = fingers, .ra = 0.035f, .rb = 0.02f}};
njin::draw_sdf_blend(ctx, arm, 3, 0.03f, clay);
void draw_sdf_blend(const context &ctx, const sdf_part *parts, u32 count, f32 blend, rgba color)
Vẽ nhiều phần SDF hòa làm một khối liền (smooth min): chỗ hai phần gặp nhau được đắp đầy mượt thay vì...
Một phần của hình ghép SDF (draw_sdf_blend()): hình nón bo tròn nối a với b, bán kính ra ở a và rb ở ...
Definition njin_3d.h:293
Các tham số
ctxContext của engine.
partsCác phần; được chép lại, không cần sống sau lệnh gọi.
countSố phần, 1 đến njin::sdf_blend_max (phần thừa bị bỏ, kèm cảnh báo).
blendĐộ mềm của chỗ nối, đơn vị thế giới, cho các phần không đặt sdf_part::blend riêng: 0 là nối cứng, lớn thì phần này chảy sang phần kia xa hơn.
colorMàu.

◆ model_load() [1/2]

model_handle njin::model_load ( context & ctx,
const char * path )

Nạp model 3D từ file glTF (.glb, .gltf) hoặc OBJ.

Đường dẫn tính như texture_load(). Màu và texture của vật liệu trong file được giữ, và model được chiếu sáng theo light3d_set().

Các tham số
ctxContext của engine.
pathĐường dẫn file.
Giá trị trả về
Handle của model, hoặc handle không hợp lệ nếu file thiếu hay lỗi.

◆ model_load() [2/2]

model_handle njin::model_load ( context & ctx,
const model_load_desc & desc )

Nạp model như model_load(), với bộ lọc node và gộp mesh của desc.

Vật liệu glTF có KHR_materials_transmission (kính trong) được vẽ trong suốt: độ mờ theo transmissionFactor, không đổ bóng, vẽ sau mọi phần đục.

// Khung cửa sổ không có mảng tường của nó, gộp theo vật liệu.
const char *skip[] = {"substrate", "floor_band"};
const njin::model_handle frame =
njin::model_load(ctx, {.path = "assets/window.glb", .skip_nodes = skip, .skip_count = 2, .merge = true});
model_handle model_load(context &ctx, const char *path)
Nạp model 3D từ file glTF (.glb, .gltf) hoặc OBJ.
Định danh của một model 3D, tạo bởi model_load().
Definition _types.h:153
Các tham số
ctxContext của engine.
descFile, bộ lọc node và có gộp mesh hay không.
Giá trị trả về
Handle của model, hoặc handle không hợp lệ nếu file thiếu, lỗi, hay bộ lọc không giữ mesh nào.

◆ model_unload()

void njin::model_unload ( context & ctx,
model_handle handle )

Giải phóng model cùng các texture của nó.

Handle không hợp lệ bị bỏ qua.

Các tham số
ctxContext của engine.
handleModel cần giải phóng.

◆ model_create()

model_handle njin::model_create ( context & ctx,
const mesh3d_data & mesh )

Tạo model từ một lưới tam giác trong bộ nhớ, rồi dùng như model nạp từ file: draw_model(), draw_instanced3d(), model_material_set(), ray3d_model(), model_unload().

Chiếu sáng, đổ bóng và nhận bóng như mọi hình khác.

// Một tam giác đỏ nằm trên mặt đất.
const njin::vec3 p[] = {{0, 0, 0}, {0, 0, 1}, {1, 0, 0}};
const njin::model_handle tri = njin::model_create(ctx, {.positions = p, .colors = c, .vertex_count = 3});
model_handle model_create(context &ctx, const mesh3d_data &mesh)
Tạo model từ một lưới tam giác trong bộ nhớ, rồi dùng như model nạp từ file: draw_model(),...
constexpr rgba red
Đỏ.
Definition _math.h:236
Vector 3 chiều.
Definition _types.h:47
Các tham số
ctxContext của engine.
meshLưới.
Giá trị trả về
Handle của model, hoặc handle không hợp lệ nếu lưới rỗng hay sai (cảnh báo nói vì sao).

◆ model_create_skinned()

model_handle njin::model_create_skinned ( context & ctx,
const skinned_mesh3d_data & mesh )

Tạo model có xương từ một lưới trong bộ nhớ, dùng bộ xương và animation của model khác (một thư viện clip nạp một lần cho mọi nhân vật).

Vẽ bằng draw_model_anim() như model nạp từ file, mỗi lần vẽ một tư thế và (với njin::model_recolor) một bảng màu riêng, nên nhiều nhân vật dùng chung một lưới mà vẫn mỗi người một động tác, một bộ quần áo.

// Thư viện clip một lần; mỗi tổ hợp mảnh ghép một model.
const njin::model_handle clips = njin::model_load(ctx, "assets/shared_animations.glb");
ctx, {.positions = pos.data(), .vertex_count = n, .joints = joints.data(), .weights = weights.data(),
.indices = idx.data(), .index_count = (njin::u32)idx.size(), .skeleton = clips});
njin::draw_model_anim(ctx, body, at, {.anim = njin::model_anim_find(ctx, body, "Walk_Loop"), .time = t});
void draw_model_anim(const context &ctx, model_handle handle, const transform3d &transform, const model_pose &pose, rgba tint=colors::white)
Vẽ model có xương ở tư thế pose.
model_handle model_create_skinned(context &ctx, const skinned_mesh3d_data &mesh)
Tạo model có xương từ một lưới trong bộ nhớ, dùng bộ xương và animation của model khác (một thư viện ...
i32 model_anim_find(const context &ctx, model_handle handle, const char *name)
Tìm animation theo tên đặt trong Blender (tên action khi xuất glTF).
std::uint32_t u32
Số nguyên không dấu 32 bit.
Definition _types.h:22
Các tham số
ctxContext của engine.
meshLưới, các phần và model cho bộ xương.
Giá trị trả về
Handle của model, hoặc handle không hợp lệ nếu lưới sai hay skeleton không phải model có xương (cảnh báo nói vì sao). Giải phóng bằng model_unload().

◆ model_lod_build()

i32 njin::model_lod_build ( context & ctx,
model_handle handle,
const model_lod_desc & desc = {} )

Tạo các mức chi tiết cho model: bản giản lược, ít tam giác hơn, được vẽ thay model khi nó nhỏ trên màn hình.

Sau đó draw_model(), draw_model_anim() và njin::model3d tự chọn mức theo khoảng cách tới camera; model có xương giữ xương và animation ở mọi mức, model có morph giữ morph ở mọi mức. draw_instanced3d() và ray3d_model() luôn dùng model gốc.

Làm một lần sau khi nạp (tốn vài mili giây với vài chục nghìn tam giác); gọi lại thì thay các mức cũ. model_unload() giải phóng cả các mức.

const njin::model_handle tree = njin::model_load(ctx, "tree.glb");
njin::model_lod_build(ctx, tree, {.levels = 2});
i32 model_lod_build(context &ctx, model_handle handle, const model_lod_desc &desc={})
Tạo các mức chi tiết cho model: bản giản lược, ít tam giác hơn, được vẽ thay model khi nó nhỏ trên mà...
Các tham số
ctxContext của engine.
handleModel từ model_load() hay model_create().
descSố mức và mức giản lược.
Giá trị trả về
Số mức đã tạo, 0 nếu model quá đơn giản để giản lược hay handle không hợp lệ.

◆ model_material_count()

i32 njin::model_material_count ( const context & ctx,
model_handle handle )

Số vật liệu của model.

Các tham số
ctxContext của engine.
handleModel.
Giá trị trả về
Số vật liệu, 0 nếu handle không hợp lệ.

◆ model_material_find()

i32 njin::model_material_find ( const context & ctx,
model_handle handle,
const char * name )

Tìm vật liệu theo tên đặt trong file glTF.

So theo tiền tố: "Human_Shirt" khớp vật liệu Human_Shirt_53_19_16.

Các tham số
ctxContext của engine.
handleModel.
nameTên hoặc phần đầu của tên.
Giá trị trả về
Chỉ số của vật liệu đầu tiên khớp, hoặc -1 nếu không có (hay file không phải glTF).

◆ model_material_get()

model_material njin::model_material_get ( const context & ctx,
model_handle handle,
i32 index )

Vật liệu thứ index của model.

Các tham số
ctxContext của engine.
handleModel.
index0..model_material_count() - 1.
Giá trị trả về
Vật liệu, hoặc mặc định nếu handle hay index không hợp lệ.

◆ model_material_set()

void njin::model_material_set ( context & ctx,
model_handle handle,
i32 index,
const model_material & material )

Đặt vật liệu thứ index của model, cho mọi lần vẽ sau đó.

m.albedo = njin::texture_load(ctx, "assets/crate_wood.png");
m.normal = njin::texture_load(ctx, "assets/crate_wood_n.png");
m.surface.specular = 0.1f;
njin::model_material_set(ctx, crate, 0, m);
model_material model_material_get(const context &ctx, model_handle handle, i32 index)
Vật liệu thứ index của model.
void model_material_set(context &ctx, model_handle handle, i32 index, const model_material &material)
Đặt vật liệu thứ index của model, cho mọi lần vẽ sau đó.
texture_handle texture_load(context &ctx, const char *path)
Nạp một texture từ file ảnh.
f32 specular
Độ mạnh của điểm sáng bóng. 0 là mặt mờ (gỗ, vải).
Definition njin_3d.h:144
Vật liệu của một phần model: mỗi file glTF/OBJ có một hay nhiều vật liệu, mỗi mesh dùng một.
Definition njin_3d.h:516
texture_handle normal
Normal map (tangent space, xanh lá hướng lên như glTF).
Definition njin_3d.h:519
material3d surface
Độ bóng, phát sáng, unlit, đổ bóng, world_uv.
Definition njin_3d.h:528
texture_handle albedo
Ảnh màu.
Definition njin_3d.h:518
Các tham số
ctxContext của engine.
handleModel.
index0..model_material_count() - 1, hoặc -1 cho mọi vật liệu.
materialVật liệu mới.

◆ draw_model()

void njin::draw_model ( const context & ctx,
model_handle handle,
const transform3d & transform,
rgba tint = colors::white )

Vẽ model tại transform, với vật liệu của nó (model_material_set()).

material3d_set() không áp dụng cho model; fx3d_set() thì có. Shader của game bật bằng shader_begin() thay shader của mọi phần không có shader riêng.

Model nằm ngoài tầm nhìn camera (hộp bao của nó ngoài frustum) không được vẽ nhưng vẫn đổ bóng vào cảnh; render_info_get() đếm số model bị bỏ. Một lưới lớn (địa hình, đường sá) nên chia thành nhiều model theo vùng để phần khuất được bỏ. Có mức chi tiết (model_lod_build()) thì model ở xa vẽ bằng mức đơn giản hơn.

Các tham số
ctxContext của engine.
handleModel từ model_load(). Handle không hợp lệ bị bỏ qua.
transformVị trí, hướng và tỉ lệ.
tintMàu nhân vào màu của model. Trắng là giữ nguyên.

◆ model_anim_count()

i32 njin::model_anim_count ( const context & ctx,
model_handle handle )

Số animation xương trong file của model (glTF có skin).

model_load() nạp chúng cùng model. Model không có skin nhưng có morph target thì animation của nó là các clip có đường cong trọng số (model_morph_count()).

Các tham số
ctxContext của engine.
handleModel.
Giá trị trả về
Số animation, 0 nếu model không có hay handle không hợp lệ.

◆ model_anim_find()

i32 njin::model_anim_find ( const context & ctx,
model_handle handle,
const char * name )

Tìm animation theo tên đặt trong Blender (tên action khi xuất glTF).

Các tham số
ctxContext của engine.
handleModel.
nameTên animation.
Giá trị trả về
Chỉ số 0..model_anim_count() - 1, hoặc -1 nếu không có.

◆ model_anim_name()

const char * njin::model_anim_name ( const context & ctx,
model_handle handle,
i32 index )

Tên của animation thứ index.

Các tham số
ctxContext của engine.
handleModel.
index0..model_anim_count() - 1.
Giá trị trả về
Tên, hoặc chuỗi rỗng nếu handle hay index không hợp lệ.

◆ model_anim_duration()

f32 njin::model_anim_duration ( const context & ctx,
model_handle handle,
i32 index )

Độ dài của animation thứ index, giây.

Các tham số
ctxContext của engine.
handleModel.
index0..model_anim_count() - 1.
Giá trị trả về
Độ dài, 0 nếu handle hay index không hợp lệ.

◆ draw_model_anim() [1/3]

void njin::draw_model_anim ( const context & ctx,
model_handle handle,
const transform3d & transform,
const model_pose & pose,
rgba tint = colors::white )

Vẽ model có xương ở tư thế pose.

Như draw_model(), và bóng đổ theo đúng tư thế. Mỗi lần vẽ có tư thế riêng, nên cùng một model vẽ nhiều lần (đám quái) mỗi con một động tác được.

Xương được tính trên GPU, tối đa 128 xương, 4 xương mỗi đỉnh (giới hạn của glTF). Phần model vẽ bằng shader của game (model_material::shader hay shader_begin()), draw_instanced3d() và ray3d_model() dùng tư thế gốc.

// Chạy khi di chuyển, đứng yên khi dừng, chuyển mượt trong 0.2 giây.
blend = move_toward(blend, moving ? 1.0f : 0.0f, dt / 0.2f);
njin::draw_model_anim(ctx, hero, {.position = pos, .rotation = {0, yaw, 0}},
{.anim = idle, .time = t, .blend_anim = run, .blend_time = t, .blend = blend});
void run(context &ctx)
Chạy vòng lặp chính cho đến khi cửa sổ đóng.
constexpr f32 move_toward(f32 from, f32 to, f32 max_step)
Di chuyển from về phía to một đoạn tối đa max_step, không vượt quá.
Definition _math.h:203
Các tham số
ctxContext của engine.
handleModel từ model_load(). Handle không hợp lệ bị bỏ qua.
transformVị trí, hướng và tỉ lệ.
poseTư thế. Model không có xương thì vẽ như draw_model().
tintMàu nhân vào màu của model.

◆ draw_model_anim() [2/3]

void njin::draw_model_anim ( const context & ctx,
model_handle handle,
const transform3d & transform,
const model_pose & pose,
rgba tint,
const model_recolor & recolor )

Như draw_model_anim() ở trên, và vật liệu recolor.material mang màu recolor.color trong lần vẽ này.

Để nhiều bản vẽ của cùng một model mỗi bản một màu áo (đồng phục của từng phe) mà không phải nạp model nhiều lần hay đổi model_material_set() giữa các lần vẽ: các lần vẽ chỉ chạy ở end_3d(), nên model_material_set() ở giữa chúng không có tác dụng riêng cho từng lần.

const njin::i32 shirt = njin::model_material_find(ctx, man, "Shirt");
njin::draw_model_anim(ctx, man, at, pose, njin::colors::white, {.material = shirt, .color = team_red});
i32 model_material_find(const context &ctx, model_handle handle, const char *name)
Tìm vật liệu theo tên đặt trong file glTF.
std::int32_t i32
Số nguyên có dấu 32 bit.
Definition _types.h:14
constexpr rgba white
Trắng.
Definition _math.h:234
Các tham số
ctxContext của engine.
handleModel từ model_load().
transformVị trí, hướng và tỉ lệ.
poseTư thế.
tintMàu nhân vào màu của cả model (sau khi đổi màu vật liệu).
recolorVật liệu đổi màu và màu mới.

◆ draw_model_anim() [3/3]

void njin::draw_model_anim ( const context & ctx,
model_handle handle,
const transform3d & transform,
const model_pose & pose,
rgba tint,
const model_recolor * recolors,
u32 count )

Như draw_model_anim() ở trên, với nhiều vật liệu đổi màu một lúc: bảng màu riêng của một nhân vật (da, tóc, áo, quần) trên một model dùng chung.

const njin::model_recolor palette[] = {{.material = 0, .color = skin}, {.material = 1, .color = shirt}};
njin::draw_model_anim(ctx, body, at, pose, njin::colors::white, palette, 2);
Màu thay cho màu gốc của một vật liệu, chỉ trong một lần vẽ.
Definition njin_3d.h:666
Các tham số
ctxContext của engine.
handleModel.
transformVị trí, hướng và tỉ lệ.
poseTư thế.
tintMàu nhân vào màu của cả model (sau khi đổi màu vật liệu).
recolorsCác vật liệu đổi màu; một vật liệu có mặt hai lần lấy màu đầu tiên.
countSố phần tử của recolors.

◆ model_bone_count()

i32 njin::model_bone_count ( const context & ctx,
model_handle handle )

Số xương của model (0 nếu không có xương hay handle không hợp lệ).

Các tham số
ctxContext của engine.
handleModel.
Giá trị trả về
Số xương.

◆ model_bone_name()

const char * njin::model_bone_name ( const context & ctx,
model_handle handle,
i32 bone )

Tên một xương, như trong file glTF.

Các tham số
ctxContext của engine.
handleModel.
bone0..model_bone_count() - 1.
Giá trị trả về
Tên, hoặc chuỗi rỗng nếu bone hay handle không hợp lệ.

◆ model_bone_find()

i32 njin::model_bone_find ( const context & ctx,
model_handle handle,
const char * name )

Tìm xương theo tên (so đúng cả chuỗi).

Các tham số
ctxContext của engine.
handleModel.
nameTên xương.
Giá trị trả về
Chỉ số 0..model_bone_count() - 1, hoặc -1 nếu không có.

◆ model_bone_parent()

i32 njin::model_bone_parent ( const context & ctx,
model_handle handle,
i32 bone )

Xương cha của bone trong bộ xương, để đi lên chuỗi xương (IK: đùi, cẳng chân, bàn chân) hay biết xương nào nằm dưới xương nào.

Các tham số
ctxContext của engine.
handleModel.
bone0..model_bone_count() - 1.
Giá trị trả về
Chỉ số xương cha, hoặc -1 với xương gốc, handle hay bone không hợp lệ.

◆ model_bone_bounds()

bool njin::model_bone_bounds ( const context & ctx,
model_handle handle,
i32 bone,
bool children,
vec3 * min,
vec3 * max )

Hộp bao phần da mà xương bone kéo mạnh nhất (cả các xương con nếu children), ở tư thế gốc trong file: theo các trục của model, tính từ gốc của xương.

Theo trục của model nên hộp ôm sát (đế bàn chân nằm phẳng trên sàn), không phình ra như hộp dựng theo một xương nằm chéo. Để đặt collider khớp với hình thật (bàn chân, bàn tay, đầu): khi vẽ, xoay hộp theo đúng góc xương đã xoay so với tư thế gốc (model_bone_pose() với tư thế gốc).

// Bàn chân (không kể ngón), quanh gốc xương foot_l.
njin::vec3 lo, hi;
if (njin::model_bone_bounds(ctx, man, foot_l, false, &lo, &hi)) { ... }
bool model_bone_bounds(const context &ctx, model_handle handle, i32 bone, bool children, vec3 *min, vec3 *max)
Hộp bao phần da mà xương bone kéo mạnh nhất (cả các xương con nếu children), ở tư thế gốc trong file:...
Các tham số
ctxContext của engine.
handleModel có da (lưới có xương).
bone0..model_bone_count() - 1.
childrenTính cả da của mọi xương nằm dưới bone.
minNhận góc nhỏ nhất của hộp.
maxNhận góc lớn nhất.
Giá trị trả về
false (min, max giữ nguyên) nếu không có đỉnh da nào, model không có da hay handle, bone không hợp lệ.

◆ model_bone_points()

i32 njin::model_bone_points ( const context & ctx,
model_handle handle,
i32 bone,
bool children,
vec3 * out,
i32 count )

Các đỉnh của phần da đó (như model_bone_bounds()), cùng hệ trục: theo các trục của model ở tư thế gốc, tính từ gốc của xương.

Để dựng một khối lồi ôm đúng hình (physics3d_hull_create()).

Các tham số
ctxContext của engine.
handleModel có da.
bone0..model_bone_count() - 1.
childrenTính cả da của mọi xương nằm dưới bone.
outMảng nhận các đỉnh, hoặc nullptr để chỉ đếm.
countSố phần tử của out.
Giá trị trả về
Số đỉnh có (có thể lớn hơn count: chỉ count đỉnh đầu được ghi).

◆ model_morph_count()

i32 njin::model_morph_count ( const context & ctx,
model_handle handle )

Số morph target (blend shape) của model: các target của glTF (biểu cảm mặt, cơ phồng, cửa mở), theo tên.

Target cùng tên ở nhiều mesh (cái nháy mắt ở mặt và ở mi) là một morph. model_load() nạp chúng cùng model, cùng các đường cong trọng số (kênh weights) của animation trong file.

Trọng số khi vẽ (draw_model(), draw_model_anim(), njin::model3d) là: mặc định của file (mesh.weights), rồi animation của model_pose đặt lại các morph nó có đường cong, rồi cộng model_pose::morph_weights. Morph được trộn trên CPU vào bộ đệm đỉnh của mesh, trước khi xương (nếu có) uốn nó, nên chạy với mọi shader, cả shader của game và bóng đổ. Các mức chi tiết của model_lod_build() giữ morph. draw_instanced3d() và ray3d_model() có bản nhận njin::model_pose để dùng hình đã morph (bản không có nó dùng hình gốc). Model nạp với model_load_desc::merge giữ morph của các mesh được gộp.

Các tham số
ctxContext của engine.
handleModel.
Giá trị trả về
Số morph, 0 nếu model không có hay handle không hợp lệ.

◆ model_morph_name()

const char * njin::model_morph_name ( const context & ctx,
model_handle handle,
i32 morph )

Tên của morph thứ morph: tên trong extras.targetNames của file, hoặc "<tên mesh>.<số>" khi file không đặt tên.

Các tham số
ctxContext của engine.
handleModel.
morph0..model_morph_count() - 1.
Giá trị trả về
Tên, hoặc chuỗi rỗng nếu handle hay morph không hợp lệ.

◆ model_morph_find()

i32 njin::model_morph_find ( const context & ctx,
model_handle handle,
const char * name )

Tìm morph theo tên (so đúng cả chuỗi).

Các tham số
ctxContext của engine.
handleModel.
nameTên morph.
Giá trị trả về
Chỉ số 0..model_morph_count() - 1, hoặc -1 nếu không có.

◆ model_morph_weights()

i32 njin::model_morph_weights ( const context & ctx,
model_handle handle,
const model_pose & pose,
f32 * out,
i32 count )

Trọng số của mọi morph ở tư thế pose, đúng như lần vẽ sẽ dùng (mặc định, animation, rồi pose.morph_weights).

Để đọc độ mở miệng của một đoạn nói, hay kiểm tra animation.

Các tham số
ctxContext của engine.
handleModel.
poseTư thế.
outMảng nhận trọng số, hoặc nullptr để chỉ đếm.
countSố phần tử của out.
Giá trị trả về
model_morph_count() (chỉ count trọng số đầu được ghi).

◆ model_bone_pose()

bone_pose3d njin::model_bone_pose ( const context & ctx,
model_handle handle,
const model_pose & pose,
i32 bone )

Xương bone ở tư thế pose (cùng cách tính với draw_model_anim(), kể cả khi trộn hai animation), để gắn đồ vào tay, đặt vùng trúng đòn theo xương, hay biết bàn chân đang ở đâu.

Nhân với transform của lần vẽ để ra thế giới.

// Điếu thuốc trong tay phải, ở thế giới.
const njin::bone_pose3d hand = njin::model_bone_pose(ctx, man, pose, hand_r);
const njin::vec3 at = pos + hand.position * scale; // model không xoay
bone_pose3d model_bone_pose(const context &ctx, model_handle handle, const model_pose &pose, i32 bone)
Xương bone ở tư thế pose (cùng cách tính với draw_model_anim(), kể cả khi trộn hai animation),...
Một xương ở một tư thế: vị trí và ba trục của nó trong không gian của model (trước transform của lần ...
Definition njin_3d.h:771
vec3 position
Gốc của xương.
Definition njin_3d.h:772
Các tham số
ctxContext của engine.
handleModel có xương.
poseTư thế; anim -1 (và không trộn) là tư thế gốc.
bone0..model_bone_count() - 1.
Giá trị trả về
Tư thế của xương; giá trị mặc định (gốc tọa độ, các trục chuẩn) nếu handle hay bone không hợp lệ.

◆ camera3d_ray()

ray3d njin::camera3d_ray ( const context & ctx,
const camera3d & camera,
vec2 screen )

Tia từ camera đi qua một điểm trên màn hình, để chọn vật dưới chuột: camera3d_ray(ctx, cam, mouse_pos(ctx)).

Dùng cùng tỉ lệ khung hình với begin_3d() (screen_size()), nên đúng cả khi có virtual size.

Các tham số
ctxContext của engine.
cameraCamera đã (hoặc sẽ) dùng cho begin_3d().
screenĐiểm trên màn hình, pixel (như mouse_pos()).
Giá trị trả về
Tia có gốc ở vị trí camera.

◆ camera3d_to_screen()

vec2 njin::camera3d_to_screen ( const context & ctx,
const camera3d & camera,
vec3 point,
bool * visible = nullptr )

Vị trí trên màn hình của một điểm 3D, để đặt nhãn hay thanh máu trên đầu nhân vật.

Các tham số
ctxContext của engine.
cameraCamera của lần vẽ.
pointĐiểm trong thế giới.
visibleNếu khác nullptr, nhận false khi điểm ở sau camera (vị trí trả về khi đó không có nghĩa).
Giá trị trả về
Vị trí, pixel màn hình (cùng hệ với mouse_pos()).

◆ ray3d_box()

ray3d_hit njin::ray3d_box ( const ray3d & ray,
vec3 center,
vec3 size )

Tia với hộp có các cạnh song song với trục.

Gốc tia nằm trong hộp thì chạm ở mặt tia đi ra.

Các tham số
rayTia.
centerTâm hộp.
sizeKích thước theo x, y, z.
Giá trị trả về
Điểm chạm gần nhất, nếu có.

◆ ray3d_sphere()

ray3d_hit njin::ray3d_sphere ( const ray3d & ray,
vec3 center,
f32 radius )

Tia với hình cầu.

Các tham số
rayTia.
centerTâm.
radiusBán kính.
Giá trị trả về
Điểm chạm gần nhất, nếu có.

◆ ray3d_plane()

ray3d_hit njin::ray3d_plane ( const ray3d & ray,
vec3 point,
vec3 normal )

Tia với mặt phẳng vô hạn qua point, pháp tuyến normal.

Chạm cả hai mặt.

Các tham số
rayTia.
pointMột điểm của mặt phẳng.
normalPháp tuyến (không cần độ dài 1).
Giá trị trả về
Điểm chạm, nếu tia không song song và mặt phẳng ở phía trước.

◆ ray3d_shape()

ray3d_hit njin::ray3d_shape ( const ray3d & ray,
const shape3d & shape )

Tia với một hình SDF, đúng như draw_shape3d() vẽ nó (kể cả khi xoay, bo góc).

Các tham số
rayTia.
shapeHình.
Giá trị trả về
Điểm chạm gần nhất, nếu có.

◆ ray3d_model() [1/2]

ray3d_hit njin::ray3d_model ( const context & ctx,
const ray3d & ray,
model_handle model,
const transform3d & transform )

Tia với từng tam giác của một model đặt tại transform, như draw_model() vẽ nó.

Tốn theo số tam giác: dùng cho vài model, không cho cả nghìn.

Các tham số
ctxContext của engine.
rayTia.
modelModel từ model_load().
transformVị trí, hướng và tỉ lệ.
Giá trị trả về
Điểm chạm gần nhất, hoặc không chạm nếu handle không hợp lệ.

◆ ray3d_model() [2/2]

ray3d_hit njin::ray3d_model ( const context & ctx,
const ray3d & ray,
model_handle model,
const transform3d & transform,
const model_pose & pose )

Như bản trên, nhưng mesh có morph target được thử ở hình của pose: trọng số mặc định, animation và pose.morph_weights, đúng như draw_model_anim() vẽ nó (model_morph_weights()).

Xương của pose không được dùng: tia thử tư thế gốc. Model không có morph thì như bản trên.

Các tham số
ctxContext của engine.
rayTia.
modelModel từ model_load().
transformVị trí, hướng và tỉ lệ.
poseTư thế cho trọng số morph.
Giá trị trả về
Điểm chạm gần nhất, hoặc không chạm nếu handle không hợp lệ.

◆ draw_instanced3d() [1/3]

void njin::draw_instanced3d ( const context & ctx,
mesh3d_kind mesh,
instance_buffer_handle buffer,
u32 first,
u32 count,
shader_handle shader = {} )

Vẽ count bản của một hình có sẵn bằng một lệnh vẽ, mỗi bản đặt theo dữ liệu của nó trong một bộ đệm instance (instance_buffer_create(), instance_buffer_upload(), như draw_instanced() của 2D).

Cho rừng cây, đám đông, mảnh vỡ, hàng nghìn viên gạch.

Không có shader, shader có sẵn của engine đọc mỗi instance như sau, nên vẫn có ánh sáng, bóng đổ, njin::material3d (kể cả texture) và njin::fx3d lúc gọi:

  • instance0: vị trí xyz, tỉ lệ đều w (0 là 1);
  • instance1 (từ 8 số mỗi instance): màu rgba, nhân với màu của hình;
  • instance2 (từ 12 số): góc xoay xyz, độ, cùng thứ tự với njin::transform3d;
  • instance3 (16 số): tỉ lệ theo x, y, z (0 là 1), nhân với instance0.w.

Có shader thì shader đó tự đọc instance0..3 theo ý nó; engine đặt mvp (camera, không có ma trận model) và các uniform ánh sáng như với draw_cube3d(). Như mọi hình 3D, chỉ có tác dụng giữa begin_3d() và end_3d(), và vẽ ở end_3d(): bộ đệm phải giữ nguyên dữ liệu đến lúc đó.

Các tham số
ctxContext của engine.
meshHình.
bufferBộ đệm đã ghi bằng instance_buffer_upload().
firstInstance đầu tiên.
countSố instance, bị cắt bớt nếu vượt quá số đã ghi.
shaderShader của game, hoặc không hợp lệ để dùng shader có sẵn.

◆ draw_instanced3d() [2/3]

void njin::draw_instanced3d ( const context & ctx,
model_handle model,
instance_buffer_handle buffer,
u32 first,
u32 count,
shader_handle shader = {} )

Vẽ count bản của một model bằng một lệnh vẽ cho mỗi phần của model, cùng quy ước dữ liệu instance với bản trên.

Mỗi phần giữ ảnh và màu của vật liệu nó (model_material_set()). Normal map chỉ dùng khi game tự đặt model_material::normal (normal map trong file bị bỏ qua ở đây); ảnh phát sáng không dùng. Phần có model_material::shader vẽ bằng shader đó thay cho shader, như draw_model().

Các tham số
ctxContext của engine.
modelModel từ model_load().
bufferBộ đệm đã ghi bằng instance_buffer_upload().
firstInstance đầu tiên.
countSố instance, bị cắt bớt nếu vượt quá số đã ghi.
shaderShader của game, hoặc không hợp lệ để dùng shader có sẵn.

◆ draw_instanced3d() [3/3]

void njin::draw_instanced3d ( const context & ctx,
model_handle model,
instance_buffer_handle buffer,
u32 first,
u32 count,
const model_pose & pose,
shader_handle shader = {} )

Như bản trên, với morph target theo pose (trọng số mặc định, animation và pose.morph_weights, như draw_model_anim()): mọi instance của lệnh này có cùng một hình đã morph.

Để các instance mang nhiều hình khác nhau (đám đông mỗi người một nét mặt), chia chúng thành vài nhóm, mỗi nhóm một lệnh với pose riêng. Xương của pose không được dùng. Model không có morph thì như bản trên.

// 500 người cùng cười: một lệnh vẽ.
const njin::f32 smile[] = {1.0f};
njin::draw_instanced3d(ctx, face, crowd, 0, 500, njin::model_pose{.morph_weights = smile, .morph_count = 1});
void draw_instanced3d(const context &ctx, mesh3d_kind mesh, instance_buffer_handle buffer, u32 first, u32 count, shader_handle shader={})
Vẽ count bản của một hình có sẵn bằng một lệnh vẽ, mỗi bản đặt theo dữ liệu của nó trong một bộ đệm i...
float f32
Số thực 32 bit.
Definition _types.h:28
Tư thế của một model có xương khi vẽ: animation nào, ở giây thứ mấy, và (tùy chọn) trộn với animation...
Definition njin_3d.h:620
Các tham số
ctxContext của engine.
modelModel từ model_load().
bufferBộ đệm đã ghi bằng instance_buffer_upload().
firstInstance đầu tiên.
countSố instance, bị cắt bớt nếu vượt quá số đã ghi.
poseTư thế cho trọng số morph.
shaderShader của game, hoặc không hợp lệ để dùng shader có sẵn.

◆ fx3d_set()

void njin::fx3d_set ( context & ctx,
const fx3d & fx )

Đặt hiệu ứng cho các hình 3D vẽ sau lệnh này, đến lần gọi tiếp theo hoặc end_3d().

fx3d_set(ctx, {}) là tắt. Chỉ có tác dụng giữa begin_3d() và end_3d().

// Mục tiêu trúng đạn: nháy trắng 0.1 giây rồi tan trong 0.4 giây.
njin::fx3d_set(ctx, {.flash = {1, 1, 1, 1 - t / 0.1f}, .dissolve = t / 0.4f});
njin::fx3d_set(ctx, {});
void fx3d_set(context &ctx, const fx3d &fx)
Đặt hiệu ứng cho các hình 3D vẽ sau lệnh này, đến lần gọi tiếp theo hoặc end_3d().
void draw_sphere3d(const context &ctx, vec3 center, f32 radius, rgba color)
Vẽ hình cầu đặc.
Các tham số
ctxContext của engine.
fxHiệu ứng.

◆ particles3d_spawn()

void njin::particles3d_spawn ( context & ctx,
const particle_emitter & emitter,
vec3 pos,
i32 count,
const particles3d_desc & desc = {} )

Phát một loạt count hạt tại pos, dùng lại một emitter 2D: các mẫu njin::fx (explosion(), sparks(), dust()...) hay emitter tự cấu hình.

Hạt luôn quay mặt về camera, được mô phỏng mỗi frame theo delta() (nên dừng trong hitstop) và vẽ ở end_3d(), sau các hình khác của lần vẽ đó: tường vẫn che được hạt, còn hạt không che nhau. Dùng hình tròn, hình vuông hay texture, màu, kích thước, trọng lực, lực cản, xoay và cách trộn màu của emitter. Chỉ phát theo loạt: muốn phát liên tục (khói ống khói) thì gọi mỗi frame với vài hạt.

Các tham số
ctxContext của engine.
emitterCấu hình hạt.
posVị trí phát.
countSố hạt.
descHướng phát và tỉ lệ đơn vị.

◆ particles3d_clear()

void njin::particles3d_clear ( context & ctx)

Xóa mọi hạt 3D đang bay, ví dụ khi đổi màn.

Các tham số
ctxContext của engine.

◆ particles3d_count()

i32 njin::particles3d_count ( const context & ctx)

Số hạt 3D đang sống.

Các tham số
ctxContext của engine.
Giá trị trả về
Số hạt.