raylib/ports/text

Licence This example has its own licence, rather than Odin's: raylib/ports/LICENSE
These are ported Raylib examples, and as such, they are subject to Raylib's license. Copyright (c) 2013-2024 Ramon Santamaria (@raysan5)
The rest of the licence
This software is provided "as-is", without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution.

Code

text_codepoints_loading.odin ¶
115 linesSource

1package text_codepoints_loading
2
3/*******************************************************************************************
4*
5*   raylib [text] example - Codepoints loading
6*
7*   This example was originally created with raylib 4.2 in C, last time updated with raylib 2.5
8*   The original example in C can be found on raylib.com at:
9*
10*   https://www.raylib.com/examples/text/loader.html?name=text_codepoints_loading
11*
12*   raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
13*   BSD-like license that allows static linking with closed source software. The license
14*   can be found in its entirety as part of the standard Odin distribution at:
15*
16*   /vendor/raylib/LICENSE
17*
18*   or online at:
19*
20*   https://www.raylib.com/license.html
21*
22*   This example is licensed under an unmodified zlib/libpng license, which is an
23*   OSI-certified, BSD-like license that allows static linking with closed source software.
24*
25*   Copyright (c) 2022-2024 Ramon Santamaria (@raysan5)
26*
27********************************************************************************************/
28
29
30import rl "vendor:raylib"
31import "core:slice"
32
33SCREEN_WIDTH  :: 800
34SCREEN_HEIGHT :: 450
35
36// NOTE: It can contain all the required text for the game,
37// this text will be scanned to get all the required codepoints
38text: cstring = "いろはにほへと ちりぬるを\nわかよたれそ つねならむ\nうゐのおくやま けふこえて\nあさきゆめみし ゑひもせす"
39
40main :: proc() {
41	rl.InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "raylib [text] example - codepoints loading")
42	defer rl.CloseWindow()
43
44	// Set our game to run at 60 frames-per-second
45	rl.SetTargetFPS(60)
46
47	codepoint_count: i32
48	codepoints   := rl.LoadCodepoints(text, &codepoint_count)
49	deduplicated := codepoints_remove_duplicates(codepoints[:codepoint_count])
50	rl.UnloadCodepoints(codepoints)
51
52	// Load font containing all the provided codepoint glyphs
53	// A texture font atlas is automatically generated
54	font := rl.LoadFontEx("resources/DotGothic16-Regular.ttf", 36, raw_data(deduplicated), i32(len(deduplicated)))
55	defer rl.UnloadFont(font)
56
57	// Free codepoints, atlas has already been generated
58	delete(deduplicated)
59
60	// Set bilinear scale filter for better font scaling
61	rl.SetTextureFilter(font.texture, .BILINEAR)
62
63	// Set line spacing for multiline text (when line breaks are included '\n')
64	// NOTE: The original value of 20 results in overlapping glyphs
65	// Here it's set to twice the point size we loaded the font with.
66	rl.SetTextLineSpacing(72)
67
68	showFontAtlas := false
69
70	// Detect window close button or ESC key
71	for !rl.WindowShouldClose() {
72		// Update
73		//----------------------------------------------------------------------------------
74		if rl.IsKeyPressed(.SPACE) {
75			showFontAtlas = !showFontAtlas
76		}
77
78		// NOTE: The original example had unsafe code to scroll through
79		// the text one codepoint at a time by adding/subtracting codepoint
80		// size from the text pointer, without checking it remained within the
81		// string. This offset `ptr` was not actually used in the rendering below,
82		// and part of the example is therefore removed.
83
84		//----------------------------------------------------------------------------------
85
86		// Draw
87		//----------------------------------------------------------------------------------
88		rl.BeginDrawing()
89		defer rl.EndDrawing()
90
91			rl.ClearBackground(rl.RAYWHITE)
92
93			rl.DrawRectangle(0, 0, rl.GetScreenWidth(), 70, rl.BLACK)
94			rl.DrawText(rl.TextFormat("Total codepoints contained in provided text: %i", codepoint_count), 10, 10, 20, rl.GREEN)
95			rl.DrawText(rl.TextFormat("Total codepoints required for font atlas (duplicates excluded): %i", i32(len(deduplicated))), 10, 40, 20, rl.GREEN)
96
97			if showFontAtlas {
98				// Draw generated font texture atlas containing provided codepoints
99				rl.DrawTexture(font.texture, 150, 100, rl.BLACK)
100				rl.DrawRectangleLines(150, 100, font.texture.width, font.texture.height, rl.BLACK)
101			} else {
102				// Draw provided text with loaded font, containing all required codepoint glyphs
103				rl.DrawTextEx(font, text, { 160, 110 }, 48, 5, rl.BLACK)
104			}
105
106			rl.DrawText("Press SPACE to toggle font atlas view!", 10, rl.GetScreenHeight() - 30, 20, rl.GRAY)
107	}
108}
109
110// Remove codepoint duplicates if requested
111codepoints_remove_duplicates :: proc (codepoints: []rune) -> (deduplicated: []rune) {
112	deduplicated = slice.clone(codepoints)
113	slice.sort(deduplicated)
114	return slice.unique(deduplicated)
115}

Shaders

resources/shaders/glsl100/alpha_discard.fs ¶
20 linesSource

#version 100

precision mediump float;

// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;

// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;

void main()
{
    vec4 texelColor = texture2D(texture0, fragTexCoord);

    if (texelColor.a == 0.0) discard;

    gl_FragColor = texelColor*fragColor*colDiffuse;
}

resources/shaders/glsl100/sdf.fs ¶
25 linesSource

#version 100

precision mediump float;

// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;

// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;

// NOTE: Add here your custom variables
const float smoothing = 1.0/16.0;

void main()
{
    // Texel color fetching from texture sampler
    // NOTE: Calculate alpha using signed distance field (SDF)
    float distance = texture2D(texture0, fragTexCoord).a;
    float alpha = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance);

    // Calculate final fragment color
    gl_FragColor = vec4(fragColor.rgb, fragColor.a*alpha);
}

resources/shaders/glsl330/alpha_discard.fs ¶
19 linesSource

#version 330

// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
in vec4 fragColor;

// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;

// Output fragment color
out vec4 finalColor;

void main()
{
    vec4 texelColor = texture(texture0, fragTexCoord);
    if (texelColor.a == 0.0) discard;
    finalColor = texelColor * fragColor * colDiffuse;
}

resources/shaders/glsl330/sdf.fs ¶
26 linesSource

#version 330

// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
in vec4 fragColor;

// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;

// Output fragment color
out vec4 finalColor;

// NOTE: Add here your custom variables

void main()
{
    // Texel color fetching from texture sampler
    // NOTE: Calculate alpha using signed distance field (SDF)
    float distanceFromOutline = texture(texture0, fragTexCoord).a - 0.5;
    float distanceChangePerFragment = length(vec2(dFdx(distanceFromOutline), dFdy(distanceFromOutline)));
    float alpha = smoothstep(-distanceChangePerFragment, distanceChangePerFragment, distanceFromOutline);

    // Calculate final fragment color
    finalColor = vec4(fragColor.rgb, fragColor.a*alpha);
}

Other Files

Assets 22

Declarations Used 29