Skip to content

Commit e9e1c15

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

File tree

3 files changed

+131
-2
lines changed

3 files changed

+131
-2
lines changed

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: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ module WebGL.Texture
2121
, nonPowerOfTwoOptions
2222
, repeat
2323
, size
24+
, Format
25+
, loadBytesWith
26+
, rgb , rgba, luminanceAlpha, luminance, alpha
2427
)
2528

2629
{-|
@@ -51,10 +54,11 @@ module WebGL.Texture
5154
5255
# Things You Shouldn’t Do
5356
54-
@docs nonPowerOfTwoOptions
57+
@docs nonPowerOfTwoOptions, loadBytesWith, Format, rgb , rgba, luminanceAlpha, luminance, alpha
5558
5659
-}
57-
60+
import Bitwise
61+
import Bytes exposing (Bytes)
5862
import Elm.Kernel.Texture
5963
import Task exposing (Task)
6064

@@ -304,3 +308,99 @@ or other times you may want to use only a potion of a texture image.
304308
size : Texture -> ( Int, Int )
305309
size =
306310
Elm.Kernel.Texture.size
311+
312+
313+
314+
{-| Building [`Texture`](#Texture) from bytes
315+
316+
- [`Options`](#Options) - same as for [`loadWith`](#loadWith)
317+
318+
- `(width, height)` - dimensions of new created texture
319+
320+
- [`Format`](#Format) - pixel format in bytes
321+
322+
- Bytes - encoded pixels, where `Bytes.width` > `width` \* `height` \* `Bytes per pixe`or you get `SizeError`
323+
324+
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).
325+
326+
-}
327+
loadBytesWith :
328+
Options
329+
-> ( Int, Int )
330+
-> Format
331+
-> Bytes
332+
-> Result Error Texture
333+
loadBytesWith { magnify, minify, horizontalWrap, verticalWrap, flipY } ( w, h ) (Format format bytesPerPixel) b =
334+
let
335+
isMipmap =
336+
minify /= nearest && minify /= linear
337+
338+
widthPowerOfTwo =
339+
Bitwise.and (w - 1) w == 0
340+
341+
heightPowerOfTwo =
342+
Bitwise.and (h - 1) h == 0
343+
344+
isSizeValid =
345+
(widthPowerOfTwo && heightPowerOfTwo) || (not isMipmap && horizontalWrap == clampToEdge && verticalWrap == clampToEdge)
346+
in
347+
if w > 0 && h > 0 && isSizeValid && Bytes.width b >= w * h * bytesPerPixel then
348+
let
349+
expand (Resize mag) (Resize min) (Wrap hor) (Wrap vert) =
350+
Elm.Kernel.Texture.loadBytes mag min hor vert flipY w h format b
351+
in
352+
Ok (expand magnify minify horizontalWrap verticalWrap)
353+
354+
else
355+
Err (SizeError w h)
356+
357+
358+
{-| How to read bytes intpo pixel
359+
360+
| Format | Channels | Bytes per pixel |
361+
------------------------------------------------
362+
| rgba | 4 | 4 |
363+
| rgb | 3 | 3 |
364+
| luminanceAlpha | 2 | 2 |
365+
| luminance | 1 | 1 |
366+
| alpha | 1 | 1 |
367+
------------------------------------------------
368+
369+
-}
370+
type Format
371+
= Format Int Int
372+
373+
374+
{-| Single pixel is 4 bytes long and have 4 channels
375+
-}
376+
rgba : Format
377+
rgba =
378+
Format 6408 4
379+
380+
381+
{-| Single pixel is 3 bytes long and have 3 channels
382+
-}
383+
rgb : Format
384+
rgb =
385+
Format 6407 3
386+
387+
388+
{-| Single pixel is 2 bytes long and have 2 channels
389+
-}
390+
luminanceAlpha : Format
391+
luminanceAlpha =
392+
Format 6410 2
393+
394+
395+
{-| Single pixel is 1 bytes long and have 1 channels
396+
-}
397+
luminance : Format
398+
luminance =
399+
Format 6409 1
400+
401+
402+
{-| Single pixel is 1 bytes long and have 1 channels
403+
-}
404+
alpha : Format
405+
alpha =
406+
Format 6406 1

0 commit comments

Comments
 (0)