Skip to content

Commit

Permalink
Add WebGL.Texture.loadBytesWith
Browse files Browse the repository at this point in the history
  • Loading branch information
justgook committed May 15, 2019
1 parent a0d420a commit c406af7
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 3 deletions.
4 changes: 3 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@
"F4": false,
"F5": false,
"F6": false,
"F9": false,
"A2": false,
"A5": false,
"Float32Array": false,
"Int32Array": false,
"Uint16Array": false
"Uint16Array": false,
"Uint8Array": false
}
}
1 change: 1 addition & 0 deletions elm.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
],
"elm-version": "0.19.0 <= v < 0.20.0",
"dependencies": {
"elm/bytes": "1.0.8 <= v < 2.0.0",
"elm/core": "1.0.0 <= v < 2.0.0",
"elm/html": "1.0.0 <= v < 2.0.0"
},
Expand Down
28 changes: 28 additions & 0 deletions src/Elm/Kernel/Texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,31 @@ var _Texture_load = F6(function (magnify, mininify, horizontalWrap, verticalWrap
var _Texture_size = function (texture) {
return __Utils_Tuple2(texture.__width, texture.__height);
};


//Texture Loading from Bytes

// eslint-disable-next-line no-unused-vars
var _Texture_loadBytes = F9(function (magnify, mininify, horizontalWrap, verticalWrap, flipY, width, height, pixelFormat, bytes) {
function createTexture(gl) {
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
gl.texImage2D(gl.TEXTURE_2D, 0, pixelFormat, width, height, 0, pixelFormat, gl.UNSIGNED_BYTE, new Uint8Array(bytes.buffer));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magnify);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, mininify);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, horizontalWrap);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, verticalWrap);
if (mininify !== 9728 && mininify !== 9729) {
gl.generateMipmap(gl.TEXTURE_2D);
}
gl.bindTexture(gl.TEXTURE_2D, null);
return texture;
}
return {
$: __0_TEXTURE,
__$createTexture: createTexture,
__width: width,
__height: height
};
});
116 changes: 114 additions & 2 deletions src/WebGL/Texture.elm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ module WebGL.Texture
, nonPowerOfTwoOptions
, repeat
, size
, Format
, loadBytesWith
, unsafeLoad
, rgb , rgba, luminanceAlpha, luminance, alpha
)

{-|
Expand Down Expand Up @@ -51,10 +55,11 @@ module WebGL.Texture
# Things You Shouldn’t Do
@docs nonPowerOfTwoOptions
@docs nonPowerOfTwoOptions, loadBytesWith, unsafeLoad, Format, rgb , rgba, luminanceAlpha, luminance, alpha
-}

import Bitwise
import Bytes exposing (Bytes)
import Elm.Kernel.Texture
import Task exposing (Task)

Expand Down Expand Up @@ -304,3 +309,110 @@ or other times you may want to use only a potion of a texture image.
size : Texture -> ( Int, Int )
size =
Elm.Kernel.Texture.size



{-| Building [`Texture`](#Texture) from bytes
- [`Options`](#Options) - same as for [`loadWith`](#loadWith)
- `(width, height)` - dimensions of new created texture
- [`Format`](#Format) - pixel format in bytes
- Bytes - encoded pixels, where `Bytes.width` > `width` \* `height` \* `Bytes per pixe`or you get `SizeError`
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).
-}
loadBytesWith :
Options
-> ( Int, Int )
-> Format
-> Bytes
-> Result Error Texture
loadBytesWith ({ magnify, minify, horizontalWrap, verticalWrap, flipY } as opt) ( w, h ) ((Format _ bytesPerPixel) as format) b =
let
isMipmap =
minify /= nearest && minify /= linear

widthPowerOfTwo =
Bitwise.and (w - 1) w == 0

heightPowerOfTwo =
Bitwise.and (h - 1) h == 0

isSizeValid =
(widthPowerOfTwo && heightPowerOfTwo) || (not isMipmap && horizontalWrap == clampToEdge && verticalWrap == clampToEdge)
in
if w > 0 && h > 0 && isSizeValid && Bytes.width b >= w * h * bytesPerPixel then
Ok (unsafeLoad opt ( w, h ) format b)

else
Err (SizeError w h)


{-| It is intended specifically for library writers who want to create custom texture loaders.
-}
unsafeLoad :
Options
-> ( Int, Int )
-> Format
-> Bytes
-> Texture
unsafeLoad { magnify, minify, horizontalWrap, verticalWrap, flipY } ( w, h ) (Format format _) b =
let
expand (Resize mag) (Resize min) (Wrap hor) (Wrap vert) =
Elm.Kernel.Texture.loadBytes mag min hor vert flipY w h format b
in
expand magnify minify horizontalWrap verticalWrap

{-| How to read bytes intpo pixel
| Format | Channels | Bytes per pixel |
------------------------------------------------
| rgba | 4 | 4 |
| rgb | 3 | 3 |
| luminanceAlpha | 2 | 2 |
| luminance | 1 | 1 |
| alpha | 1 | 1 |
------------------------------------------------
-}
type Format
= Format Int Int


{-| Single pixel is 4 bytes long and have 4 channels
-}
rgba : Format
rgba =
Format 6408 4


{-| Single pixel is 3 bytes long and have 3 channels
-}
rgb : Format
rgb =
Format 6407 3


{-| Single pixel is 2 bytes long and have 2 channels
-}
luminanceAlpha : Format
luminanceAlpha =
Format 6410 2


{-| Single pixel is 1 bytes long and have 1 channels
-}
luminance : Format
luminance =
Format 6409 1


{-| Single pixel is 1 bytes long and have 1 channels
-}
alpha : Format
alpha =
Format 6406 1

0 comments on commit c406af7

Please sign in to comment.