Karl Zylinski před 1 měsícem
rodič
revize
fc5fefe7aa
2 změnil soubory, kde provedl 145 přidání a 23 odebrání
  1. 1 1
      examples/snake/snake.odin
  2. 144 22
      karl2d.doc.odin

+ 1 - 1
examples/snake/snake.odin

@@ -82,7 +82,7 @@ main :: proc() {
 	shutdown()
 }
 
-font: k2.Font_Handle
+font: k2.Font
 
 init :: proc() {
 	k2.init(WINDOW_SIZE, WINDOW_SIZE, "Snake")

+ 144 - 22
karl2d.doc.odin

@@ -9,7 +9,10 @@ package karl2d
 // Opens a window and initializes some internal state. The internal state will use `allocator` for
 // all dynamically allocated memory. The return value can be ignored unless you need to later call
 // `set_internal_state`.
-init :: proc(window_width: int, window_height: int, window_title: string,
+//
+// `screen_width` and `screen_height` refer to the the resolution of the drawable area of the
+// window. The window might be slightly larger due borders and headers.
+init :: proc(screen_width: int, screen_height: int, window_title: string,
             window_creation_flags := Window_Flags {},
             allocator := context.allocator, loc := #caller_location) -> ^State
 
@@ -236,7 +239,7 @@ measure_text :: proc(text: string, font_size: f32) -> Vec2
 
 // Tells you how much space some text of a certain size will use on the screen, using a custom font.
 // The return value contains the width and height of the text.
-measure_text_ex :: proc(font_handle: Font_Handle, text: string, font_size: f32) -> Vec2
+measure_text_ex :: proc(font_handle: Font, text: string, font_size: f32) -> Vec2
 
 // Draw text at a position with a size. This uses the default font. `pos` will be equal to the 
 // top-left position of the text.
@@ -244,7 +247,7 @@ draw_text :: proc(text: string, pos: Vec2, font_size: f32, color := BLACK)
 
 // Draw text at a position with a size, using a custom font. `pos` will be equal to the  top-left
 // position of the text.
-draw_text_ex :: proc(font_handle: Font_Handle, text: string, pos: Vec2, font_size: f32, color := BLACK)
+draw_text_ex :: proc(font_handle: Font, text: string, pos: Vec2, font_size: f32, color := BLACK)
 
 //--------------------//
 // TEXTURE MANAGEMENT //
@@ -316,52 +319,105 @@ set_render_texture :: proc(render_texture: Maybe(Render_Texture))
 //-------//
 // FONTS //
 //-------//
-load_font_from_file :: proc(filename: string) -> Font_Handle
 
-load_font_from_bytes :: proc(data: []u8) -> Font_Handle
+// Loads a font from disk and returns a handle that represents it.
+load_font_from_file :: proc(filename: string) -> Font
+
+// Loads a font from a block of memory and returns a handle that represents it.
+load_font_from_bytes :: proc(data: []u8) -> Font
 
-destroy_font :: proc(font: Font_Handle)
+// Destroy a font previously loaded using `load_font_from_file` or `load_font_from_bytes`.
+destroy_font :: proc(font: Font)
 
-get_default_font :: proc() -> Font_Handle
+// Returns the built-in font of Karl2D (the font is known as "roboto")
+get_default_font :: proc() -> Font
 
 //---------//
 // SHADERS //
 //---------//
+
+// Load a shader from a vertex and fragment shader file. If the vertex and fragment shaders live in
+// the same file, then pass it twice.
+//
+// `layout_formats` can in many cases be left default initialized. It is used to specify the format
+// of the vertex shader inputs. By formats this means the format that you pass on the CPU side.
 load_shader_from_file :: proc(
 	vertex_filename: string,
 	fragment_filename: string,
 	layout_formats: []Pixel_Format = {}
 ) -> Shader
 
+// Load a vertex and fragment shader from a block of memory. See `load_shader_from_file` for what
+// `layout_formats` means.
 load_shader_from_bytes :: proc(
 	vertex_shader_bytes: []byte,
 	fragment_shader_bytes: []byte,
 	layout_formats: []Pixel_Format = {},
 ) -> Shader
 
+// Destroy a shader previously loaded using `load_shader_from_file` or `load_shader_from_bytes`
 destroy_shader :: proc(shader: Shader)
 
+// Fetches the shader that Karl2D uses by default.
 get_default_shader :: proc() -> Shader
 
+// The supplied shader will be used for subsequent drawing. Return to the default shader by calling
+// `set_shader(nil)`.
 set_shader :: proc(shader: Maybe(Shader))
 
+// Set the value of a constant (also known as uniform in OpenGL). Look up shader constant locations
+// (the kind of value needed for `loc`) by running `loc := shader.constant_lookup["constant_name"]`.
 set_shader_constant :: proc(shd: Shader, loc: Shader_Constant_Location, val: any)
 
+// Sets the value of a shader input (also known as a shader attribute). There are three default
+// shader inputs known as position, texcoord and color. If you have shader with additional inputs,
+// then you can use this procedure to set their values. This is a way to feed per-object data into
+// your shader.
+//
+// `input` should be the index of the input and `val` should be a value of the correct size.
+//
+// You can modify which type that is expected for `val` by passing a custom `layout_formats` when
+// you load the shader.
 override_shader_input :: proc(shader: Shader, input: int, val: any)
 
+// Returns the number of bytes that a pixel in a texture uses.
 pixel_format_size :: proc(f: Pixel_Format) -> int
 
 //-------------------------------//
 // CAMERA AND COORDINATE SYSTEMS //
 //-------------------------------//
+
+// Make Karl2D use a camera. Return to the "default camera" by passing `nil`. All drawing operations
+// will use this camera until you again change it.
 set_camera :: proc(camera: Maybe(Camera))
 
+// Transform a point `pos` that lives on the screen to a point in the world. This can be useful for
+// bringing (for example) mouse positions (k2.get_mouse_position()) into world-space.
 screen_to_world :: proc(pos: Vec2, camera: Camera) -> Vec2
 
+// Transform a point `pos` that lices in the world to a point on the screen. This can be useful when
+// you need to take a position in the world and compare it to a screen-space point.
 world_to_screen :: proc(pos: Vec2, camera: Camera) -> Vec2
 
+// Get the matrix that `screen_to_world` and `world_to_screen` uses to do their transformations.
+//
+// A view matrix is essentially the world transform matrix of the camera, but inverted. In other
+// words, instead of bringing the camera in front of things in the world, we bring everything in the
+// world "in front of the camera".
+//
+// Instead of constructing the camera matrix and doing a matrix inverse, here we just do the
+// maths in "backwards order". I.e. a camera transform matrix would be:
+//
+//    target_translate * rot * scale * offset_translate
+//
+// but we do
+//
+//    inv_offset_translate * inv_scale * inv_rot * inv_target_translate
+//
+// This is faster, since matrix inverses are expensive.
 get_camera_view_matrix :: proc(c: Camera) -> Mat4
 
+// Get the matrix that brings something in front of the camera.
 get_camera_world_matrix :: proc(c: Camera) -> Mat4
 
 //------//
@@ -372,6 +428,8 @@ get_camera_world_matrix :: proc(c: Camera) -> Mat4
 // drawn. The default is the .Alpha mode, but you also have the option of using .Premultiply_Alpha.
 set_blend_mode :: proc(mode: Blend_Mode)
 
+// Make everything outside of the screen-space rectangle `scissor_rect` not render. Disable the
+// scissor rectangle by running `set_scissor_rect(nil)`.
 set_scissor_rect :: proc(scissor_rect: Maybe(Rect))
 
 // Restore the internal state using the pointer returned by `init`. Useful after reloading the
@@ -398,14 +456,30 @@ Rect :: struct {
 // An RGBA (Red, Green, Blue, Alpha) color. Each channel can have a value between 0 and 255.
 Color :: [4]u8
 
-WHITE :: Color { 255, 255, 255, 255 }
-BLACK :: Color { 0, 0, 0, 255 }
-GRAY  :: Color { 127, 127, 127, 255 }
-RED   :: Color { 198, 40, 90, 255 }
-GREEN :: Color { 30, 240, 30, 255 }
-YELLOW :: Color {240, 190, 0, 255 }
-BLANK :: Color { 0, 0, 0, 0 }
-BLUE  :: Color { 30, 116, 240, 255 }
+// See the folder examples/palette for a demo that shows all colors
+BLACK        :: Color { 0, 0, 0, 255 }
+WHITE        :: Color { 255, 255, 255, 255 }
+BLANK        :: Color { 0, 0, 0, 0 }
+GRAY         :: Color { 183, 183, 183, 255 }
+DARK_GRAY    :: Color { 66, 66, 66, 255}
+BLUE         :: Color { 25, 198, 236, 255 }
+DARK_BLUE    :: Color { 7, 47, 88, 255 }
+LIGHT_BLUE   :: Color { 200, 230, 255, 255 }
+GREEN        :: Color { 16, 130, 11, 255 }
+DARK_GREEN   :: Color { 6, 53, 34, 255}
+LIGHT_GREEN  :: Color { 175, 246, 184, 255 }
+ORANGE       :: Color { 255, 114, 0, 255 }
+RED          :: Color { 239, 53, 53, 255 }
+DARK_RED     :: Color { 127, 10, 10, 255 }
+LIGHT_RED    :: Color { 248, 183, 183, 255 }
+BROWN        :: Color { 115, 78, 74, 255 }
+DARK_BROWN   :: Color { 50, 36, 32, 255 }
+LIGHT_BROWN  :: Color { 146, 119, 119, 255 }
+PURPLE       :: Color { 155, 31, 232, 255 }
+LIGHT_PURPLE :: Color { 217, 172, 248, 255 }
+MAGENTA      :: Color { 209, 17, 209, 255 }
+YELLOW       :: Color { 250, 250, 129, 255 }
+LIGHT_YELLOW :: Color { 253, 250, 222, 255 }
 
 // These are from Raylib. They are here so you can easily port a Raylib program to Karl2D.
 RL_LIGHTGRAY  :: Color { 200, 200, 200, 255 }
@@ -435,13 +509,22 @@ RL_BLANK      :: BLANK
 RL_MAGENTA    :: Color { 255, 0, 255, 255 }
 RL_RAYWHITE   :: Color { 245, 245, 245, 255 }
 
+color_alpha :: proc(c: Color, a: u8) -> Color
+
 Texture :: struct {
+	// The render-backend specific texture identifier.
 	handle: Texture_Handle,
+
+	// The horizontal size of the texture, measured in pixels.
 	width: int,
+
+	// The vertical size of the texture, measure in pixels.
 	height: int,
 }
 
 Load_Texture_Option :: enum {
+	// Will multiply the alpha value of the each pixel into the its RGB values. Useful if you want
+	// to use `set_blend_mode(.Premultiplied_Alpha)`
 	Premultiply_Alpha,
 }
 
@@ -449,11 +532,21 @@ Load_Texture_Options :: bit_set[Load_Texture_Option]
 
 Blend_Mode :: enum {
 	Alpha,
-	Premultiplied_Alpha, // Requires the alpha-channel to be multiplied into texture RGB channels.
+
+	// Requires the alpha-channel to be multiplied into texture RGB channels. You can automatically
+	// do this using the `Premultiply_Alpha` option when loading a texture.
+	Premultiplied_Alpha,
 }
 
+// A render texture is a texture that you can draw into, instead of drawing to the screen. Create
+// one using `create_render_texture`.
 Render_Texture :: struct {
+	// The texture that the things will be drawn into. You can use this as a normal texture, for
+	// example, you can pass it to `draw_texture`.
 	texture: Texture,
+
+	// The render backend's internal identifier. It describes how to use the texture as something
+	// the render backend can draw into.
 	render_target: Render_Target_Handle,
 }
 
@@ -463,13 +556,28 @@ Texture_Filter :: enum {
 }
 
 Camera :: struct {
+	// Where the camera looks.
 	target: Vec2,
+
+	// By default `target` will be the position of the upper-left corner of the camera. Use this
+	// offset to change that. If you set the offset to half the size of the camera view, then the
+	// target position will end up in the middle of the scren.
 	offset: Vec2,
+
+	// Rotate the camera (unit: degrees)
 	rotation: f32,
+
+	// Zoom the camera. A bigger value means "more zoom".
+	//
+	// To make a certain amount of pixels always occupy the height of the camera, set the zoom to:
+	//
+	//     k2.get_screen_height()/wanted_pixel_height
 	zoom: f32,
 }
 
 Window_Flag :: enum {
+	// Make the window possible to resize. This will make the backbuffer automatically resize as
+	// well.
 	Resizable,
 }
 
@@ -485,6 +593,7 @@ Shader_Constant_Location :: struct {
 }
 
 Shader :: struct {
+	// The render backend's internal identifier.
 	handle: Shader_Handle,
 
 	// We store the CPU-side value of all constants in a single buffer to have less allocations.
@@ -492,18 +601,31 @@ Shader :: struct {
 	// maps a name to a constant location.
 	constants_data: []u8,
 	constants: []Shader_Constant_Location,
+
+	// Look up named constants. If you have a constant (uniform) in the shader called "bob", then
+	// you can find its location by running `shader.constant_lookup["bob"]`. You can then use that
+	// location in combination with `set_shader_constant`
 	constant_lookup: map[string]Shader_Constant_Location,
 
 	// Maps built in constant types such as "model view projection matrix" to a location.
 	constant_builtin_locations: [Shader_Builtin_Constant]Maybe(Shader_Constant_Location),
 
 	texture_bindpoints: []Texture_Handle,
+
+	// Used to lookup bindpoints of textures. You can then set the texture by overriding
+	// `shader.texture_bindpoints[shader.texture_lookup["some_tex"]] = some_texture.handle`
 	texture_lookup: map[string]int,
 	default_texture_index: Maybe(int),
 
 	inputs: []Shader_Input,
+
+	// Overrides the value of a specific vertex input.
+	//
+	// It's recommended you use `override_shader_input` to modify these overrides.
 	input_overrides: []Shader_Input_Value_Override,
 	default_input_offsets: [Shader_Default_Inputs]int,
+
+	// How many bytes a vertex uses gives the input of the shader.
 	vertex_size: int,
 }
 
@@ -554,7 +676,7 @@ Pixel_Format :: enum {
 	R_8_UInt,
 }
 
-Font :: struct {
+Font_Data :: struct {
 	atlas: Texture,
 
 	// internal
@@ -564,9 +686,9 @@ Font :: struct {
 Handle :: hm.Handle
 Texture_Handle :: distinct Handle
 Render_Target_Handle :: distinct Handle
-Font_Handle :: distinct int
+Font :: distinct int
 
-FONT_NONE :: Font_Handle {}
+FONT_NONE :: Font {}
 TEXTURE_NONE :: Texture_Handle {}
 RENDER_TARGET_NONE :: Render_Target_Handle {}
 
@@ -605,10 +727,10 @@ State :: struct {
 
 	window: Window_Handle,
 
-	default_font: Font_Handle,
-	fonts: [dynamic]Font,
+	default_font: Font,
+	fonts: [dynamic]Font_Data,
 	shape_drawing_texture: Texture_Handle,
-	batch_font: Font_Handle,
+	batch_font: Font,
 	batch_camera: Maybe(Camera),
 	batch_shader: Shader,
 	batch_scissor: Maybe(Rect),