A hackable template for creating small and fast browser games.
at main 196 lines 5.6 kB view raw
1import { 2 GL_CLAMP_TO_EDGE, 3 GL_COMPARE_REF_TO_TEXTURE, 4 GL_DATA_FLOAT, 5 GL_DATA_UNSIGNED_BYTE, 6 GL_DATA_UNSIGNED_INT, 7 GL_DEPTH_COMPONENT, 8 GL_DEPTH_COMPONENT24, 9 GL_DEPTH_COMPONENT32F, 10 GL_LINEAR, 11 GL_NEAREST, 12 GL_NEAREST_MIPMAP_LINEAR, 13 GL_PIXEL_UNSIGNED_BYTE, 14 GL_REPEAT, 15 GL_RGBA, 16 GL_RGBA16F, 17 GL_RGBA32F, 18 GL_RGBA8, 19 GL_TEXTURE_2D, 20 GL_TEXTURE_COMPARE_MODE, 21 GL_TEXTURE_MAG_FILTER, 22 GL_TEXTURE_MIN_FILTER, 23 GL_TEXTURE_WRAP_S, 24 GL_TEXTURE_WRAP_T, 25} from "./webgl.js"; 26 27export function fetch_image(path: string): Promise<HTMLImageElement> { 28 return new Promise((resolve) => { 29 let image = new Image(); 30 image.src = path; 31 image.onload = () => resolve(image); 32 }); 33} 34 35export function create_texture_from(gl: WebGLRenderingContext, image: HTMLImageElement) { 36 let texture = gl.createTexture()!; 37 gl.bindTexture(GL_TEXTURE_2D, texture); 38 gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GL_RGBA, GL_PIXEL_UNSIGNED_BYTE, image); 39 40 gl.generateMipmap(GL_TEXTURE_2D); 41 42 if (false) { 43 // The following are the default settings in WebGL2. 44 // GL_TEXTURE_MIN_FILTER: Consider switching to GL_LINEAR_MIPMAP_LINEAR for the best quality. 45 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); 46 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 47 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 48 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 49 } 50 51 return texture; 52} 53 54export interface Spritesheet { 55 Texture: WebGLTexture; 56 Width: number; 57 Height: number; 58} 59 60export function create_spritesheet_from( 61 gl: WebGLRenderingContext, 62 image: HTMLImageElement, 63): Spritesheet { 64 let texture = gl.createTexture()!; 65 gl.bindTexture(GL_TEXTURE_2D, texture); 66 gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GL_RGBA, GL_PIXEL_UNSIGNED_BYTE, image); 67 68 // No mipmapping nor LINEAR scaling to preserve the exact pixel data. 69 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 70 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 71 72 if (false) { 73 // The following are the default settings in WebGL2. 74 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 75 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 76 } 77 78 return { 79 Texture: texture, 80 Width: image.width, 81 Height: image.height, 82 }; 83} 84 85export function resize_texture_rgba8( 86 gl: WebGL2RenderingContext, 87 texture: WebGLTexture, 88 width: number, 89 height: number, 90) { 91 gl.bindTexture(GL_TEXTURE_2D, texture); 92 gl.texImage2D( 93 GL_TEXTURE_2D, 94 0, 95 GL_RGBA8, 96 width, 97 height, 98 0, 99 GL_RGBA, 100 GL_DATA_UNSIGNED_BYTE, 101 null, 102 ); 103 104 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 105 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 106 107 return texture; 108} 109 110/** Requires EXT_color_buffer_float. */ 111export function resize_texture_rgba16f( 112 gl: WebGL2RenderingContext, 113 texture: WebGLTexture, 114 width: number, 115 height: number, 116) { 117 gl.bindTexture(GL_TEXTURE_2D, texture); 118 gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_DATA_FLOAT, null); 119 120 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 121 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 122 123 return texture; 124} 125 126/** Requires EXT_color_buffer_float. */ 127export function resize_texture_rgba32f( 128 gl: WebGL2RenderingContext, 129 texture: WebGLTexture, 130 width: number, 131 height: number, 132) { 133 gl.bindTexture(GL_TEXTURE_2D, texture); 134 gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_DATA_FLOAT, null); 135 136 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 137 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 138 139 return texture; 140} 141 142export function resize_texture_depth24( 143 gl: WebGL2RenderingContext, 144 texture: WebGLTexture, 145 width: number, 146 height: number, 147) { 148 gl.bindTexture(GL_TEXTURE_2D, texture); 149 gl.texImage2D( 150 GL_TEXTURE_2D, 151 0, 152 GL_DEPTH_COMPONENT24, 153 width, 154 height, 155 0, 156 GL_DEPTH_COMPONENT, 157 GL_DATA_UNSIGNED_INT, 158 null, 159 ); 160 161 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 162 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 163 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); 164 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 165 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 166 167 return texture; 168} 169 170export function resize_texture_depth32f( 171 gl: WebGL2RenderingContext, 172 texture: WebGLTexture, 173 width: number, 174 height: number, 175) { 176 gl.bindTexture(GL_TEXTURE_2D, texture); 177 gl.texImage2D( 178 GL_TEXTURE_2D, 179 0, 180 GL_DEPTH_COMPONENT32F, 181 width, 182 height, 183 0, 184 GL_DEPTH_COMPONENT, 185 GL_DATA_FLOAT, 186 null, 187 ); 188 189 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 190 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 191 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); 192 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 193 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 194 195 return texture; 196}