Skip to content

Commit c406af7

Browse files
committed
Add WebGL.Texture.loadBytesWith
1 parent a0d420a commit c406af7

File tree

4 files changed

+146
-3
lines changed

4 files changed

+146
-3
lines changed

.eslintrc.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,12 @@
4040
"F4": false,
4141
"F5": false,
4242
"F6": false,
43+
"F9": false,
4344
"A2": false,
4445
"A5": false,
4546
"Float32Array": false,
4647
"Int32Array": false,
47-
"Uint16Array": false
48+
"Uint16Array": false,
49+
"Uint8Array": false
4850
}
4951
}

elm.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
],
1515
"elm-version": "0.19.0 <= v < 0.20.0",
1616
"dependencies": {
17+
"elm/bytes": "1.0.8 <= v < 2.0.0",
1718
"elm/core": "1.0.0 <= v < 2.0.0",
1819
"elm/html": "1.0.0 <= v < 2.0.0"
1920
},

src/Elm/Kernel/Texture.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,31 @@ var _Texture_load = F6(function (magnify, mininify, horizontalWrap, verticalWrap
6565
var _Texture_size = function (texture) {
6666
return __Utils_Tuple2(texture.__width, texture.__height);
6767
};
68+
69+
70+
//Texture Loading from Bytes
71+
72+
// eslint-disable-next-line no-unused-vars
73+
var _Texture_loadBytes = F9(function (magnify, mininify, horizontalWrap, verticalWrap, flipY, width, height, pixelFormat, bytes) {
74+
function createTexture(gl) {
75+
var texture = gl.createTexture();
76+
gl.bindTexture(gl.TEXTURE_2D, texture);
77+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
78+
gl.texImage2D(gl.TEXTURE_2D, 0, pixelFormat, width, height, 0, pixelFormat, gl.UNSIGNED_BYTE, new Uint8Array(bytes.buffer));
79+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magnify);
80+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, mininify);
81+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, horizontalWrap);
82+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, verticalWrap);
83+
if (mininify !== 9728 && mininify !== 9729) {
84+
gl.generateMipmap(gl.TEXTURE_2D);
85+
}
86+
gl.bindTexture(gl.TEXTURE_2D, null);
87+
return texture;
88+
}
89+
return {
90+
$: __0_TEXTURE,
91+
__$createTexture: createTexture,
92+
__width: width,
93+
__height: height
94+
};
95+
});

src/WebGL/Texture.elm

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ module WebGL.Texture
2121
, nonPowerOfTwoOptions
2222
, repeat
2323
, size
24+
, Format
25+
, loadBytesWith
26+
, unsafeLoad
27+
, rgb , rgba, luminanceAlpha, luminance, alpha
2428
)
2529

2630
{-|
@@ -51,10 +55,11 @@ module WebGL.Texture
5155
5256
# Things You Shouldn’t Do
5357
54-
@docs nonPowerOfTwoOptions
58+
@docs nonPowerOfTwoOptions, loadBytesWith, unsafeLoad, Format, rgb , rgba, luminanceAlpha, luminance, alpha
5559
5660
-}
57-
61+
import Bitwise
62+
import Bytes exposing (Bytes)
5863
import Elm.Kernel.Texture
5964
import Task exposing (Task)
6065

@@ -304,3 +309,110 @@ or other times you may want to use only a potion of a texture image.
304309
size : Texture -> ( Int, Int )
305310
size =
306311
Elm.Kernel.Texture.size
312+
313+
314+
315+
{-| Building [`Texture`](#Texture) from bytes
316+
317+
- [`Options`](#Options) - same as for [`loadWith`](#loadWith)
318+
319+
- `(width, height)` - dimensions of new created texture
320+
321+
- [`Format`](#Format) - pixel format in bytes
322+
323+
- Bytes - encoded pixels, where `Bytes.width` > `width` \* `height` \* `Bytes per pixe`or you get `SizeError`
324+
325+
Do not generate texture in `view`, [read more about this here](https://package.elm-lang.org/packages/elm-explorations/webgl/latest#making-the-most-of-the-gpu).
326+
327+
-}
328+
loadBytesWith :
329+
Options
330+
-> ( Int, Int )
331+
-> Format
332+
-> Bytes
333+
-> Result Error Texture
334+
loadBytesWith ({ magnify, minify, horizontalWrap, verticalWrap, flipY } as opt) ( w, h ) ((Format _ bytesPerPixel) as format) b =
335+
let
336+
isMipmap =
337+
minify /= nearest && minify /= linear
338+
339+
widthPowerOfTwo =
340+
Bitwise.and (w - 1) w == 0
341+
342+
heightPowerOfTwo =
343+
Bitwise.and (h - 1) h == 0
344+
345+
isSizeValid =
346+
(widthPowerOfTwo && heightPowerOfTwo) || (not isMipmap && horizontalWrap == clampToEdge && verticalWrap == clampToEdge)
347+
in
348+
if w > 0 && h > 0 && isSizeValid && Bytes.width b >= w * h * bytesPerPixel then
349+
Ok (unsafeLoad opt ( w, h ) format b)
350+
351+
else
352+
Err (SizeError w h)
353+
354+
355+
{-| It is intended specifically for library writers who want to create custom texture loaders.
356+
-}
357+
unsafeLoad :
358+
Options
359+
-> ( Int, Int )
360+
-> Format
361+
-> Bytes
362+
-> Texture
363+
unsafeLoad { magnify, minify, horizontalWrap, verticalWrap, flipY } ( w, h ) (Format format _) b =
364+
let
365+
expand (Resize mag) (Resize min) (Wrap hor) (Wrap vert) =
366+
Elm.Kernel.Texture.loadBytes mag min hor vert flipY w h format b
367+
in
368+
expand magnify minify horizontalWrap verticalWrap
369+
370+
{-| How to read bytes intpo pixel
371+
372+
| Format | Channels | Bytes per pixel |
373+
------------------------------------------------
374+
| rgba | 4 | 4 |
375+
| rgb | 3 | 3 |
376+
| luminanceAlpha | 2 | 2 |
377+
| luminance | 1 | 1 |
378+
| alpha | 1 | 1 |
379+
------------------------------------------------
380+
381+
-}
382+
type Format
383+
= Format Int Int
384+
385+
386+
{-| Single pixel is 4 bytes long and have 4 channels
387+
-}
388+
rgba : Format
389+
rgba =
390+
Format 6408 4
391+
392+
393+
{-| Single pixel is 3 bytes long and have 3 channels
394+
-}
395+
rgb : Format
396+
rgb =
397+
Format 6407 3
398+
399+
400+
{-| Single pixel is 2 bytes long and have 2 channels
401+
-}
402+
luminanceAlpha : Format
403+
luminanceAlpha =
404+
Format 6410 2
405+
406+
407+
{-| Single pixel is 1 bytes long and have 1 channels
408+
-}
409+
luminance : Format
410+
luminance =
411+
Format 6409 1
412+
413+
414+
{-| Single pixel is 1 bytes long and have 1 channels
415+
-}
416+
alpha : Format
417+
alpha =
418+
Format 6406 1

0 commit comments

Comments
 (0)