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 ea4f2c4
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 2 deletions.
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
72 changes: 71 additions & 1 deletion src/Elm/Kernel/Texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import Elm.Kernel.Utils exposing (Tuple2)
import Elm.Kernel.Scheduler exposing (binding, succeed, fail)
import WebGL.Texture as Texture exposing (LoadError, SizeError)
import WebGL.Texture as Texture exposing (LoadError, SizeError, RGBA, RGB, LUMINANCE_ALPHA, LUMINANCE, ALPHA)
import Result exposing (Err, Ok)
*/

Expand Down Expand Up @@ -65,3 +66,72 @@ 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


function getFormat(gl, format) {
return (format == __Texture_RGBA && gl.RGBA)
|| (format == __Texture_RGB && gl.RGB)
|| (format == __Texture_LUMINANCE_ALPHA && gl.LUMINANCE_ALPHA)
|| (format == __Texture_LUMINANCE && gl.LUMINANCE)
|| (format == __Texture_ALPHA && gl.ALPHA)
}

function getByteCount(format) {
return (format == __Texture_RGBA && 4)
|| (format == __Texture_RGB && 3)
|| (format == __Texture_LUMINANCE_ALPHA && 2)
|| (format == __Texture_LUMINANCE && 1)
|| (format == __Texture_ALPHA && 1)
}

// eslint-disable-next-line no-unused-vars
var _Texture_loadBytes = F9(function (magnify, mininify, horizontalWrap, verticalWrap, flipY, width, height, format, bytes) {
var isMipmap = mininify !== 9728 && mininify !== 9729;
function createTexture(gl) {
var pixelFormat = getFormat(gl, format);
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 (isMipmap) {
gl.generateMipmap(gl.TEXTURE_2D);
}
gl.bindTexture(gl.TEXTURE_2D, null);
return texture;
}
if (bytes.byteLength < width * height * getByteCount(format)) {
return __Result_Err(A2(
__Texture_SizeError,
width,
height
));
}
var widthPowerOfTwo = (width & (width - 1)) === 0;
var heightPowerOfTwo = (height & (height - 1)) === 0;
var isSizeValid = (widthPowerOfTwo && heightPowerOfTwo) || (
!isMipmap
&& horizontalWrap === 33071 // clamp to edge
&& verticalWrap === 33071
);
if (isSizeValid) {
return __Result_Ok({
$: __0_TEXTURE,
__$createTexture: createTexture,
__width: width,
__height: height
});
} else {
return __Result_Err(A2(
__Texture_SizeError,
width,
height
));
}
});
52 changes: 51 additions & 1 deletion src/WebGL/Texture.elm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ module WebGL.Texture
, nonPowerOfTwoOptions
, repeat
, size
, Format(..)
, loadBytesWith
)

{-|
Expand Down Expand Up @@ -51,10 +53,11 @@ module WebGL.Texture
# Things You Shouldn’t Do
@docs nonPowerOfTwoOptions
@docs nonPowerOfTwoOptions, loadBytesWith, Format
-}

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

Expand Down Expand Up @@ -304,3 +307,50 @@ 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 } ( w, h ) 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 |
| LUMINANCE_ALPHA | 2 | 2 |
| LUMINANCE | 1 | 1 |
| ALPHA | 1 | 1 |
------------------------------------------------
-}
type Format
= RGBA
| RGB
| LUMINANCE_ALPHA
| LUMINANCE
| ALPHA

0 comments on commit ea4f2c4

Please sign in to comment.