diff --git a/assets/textures.go b/assets/textures.go index ac2d1ff..ff426f1 100755 --- a/assets/textures.go +++ b/assets/textures.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "image" - "image/color" "image/jpeg" "image/png" "io" @@ -14,6 +13,7 @@ import ( "unsafe" "github.com/go-gl/gl/v4.1-core/gl" + "github.com/mandykoh/prism" ) type ColorFormat int @@ -67,17 +67,20 @@ func LoadTexturePNG(file string, loadOptions *TextureLoadOptions) (Texture, erro return Texture{}, err } - img, err := png.Decode(bytes.NewReader(fileBytes)) + bytesReader := bytes.NewReader(fileBytes) + img, err := png.Decode(bytesReader) if err != nil { return Texture{}, err } + nrgbaImg := prism.ConvertImageToNRGBA(img, 2) tex := Texture{ - Path: file, + Path: file, + Pixels: nrgbaImg.Pix, + Height: int32(nrgbaImg.Bounds().Dy()), + Width: int32(nrgbaImg.Bounds().Dx()), } - tex.Pixels, tex.Width, tex.Height = pixelsFromNrgbaPng(img) - //Prepare opengl stuff gl.GenTextures(1, &tex.TexID) gl.BindTexture(gl.TEXTURE_2D, tex.TexID) @@ -89,7 +92,7 @@ func LoadTexturePNG(file string, loadOptions *TextureLoadOptions) (Texture, erro gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) // load and generate the texture - gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, tex.Width, tex.Height, 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&tex.Pixels[0])) + gl.TexImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, tex.Width, tex.Height, 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&tex.Pixels[0])) if loadOptions.GenMipMaps { gl.GenerateMipmap(tex.TexID) @@ -112,8 +115,13 @@ func LoadTextureInMemPngImg(img image.Image, loadOptions *TextureLoadOptions) (T loadOptions = &TextureLoadOptions{} } - tex := Texture{} - tex.Pixels, tex.Width, tex.Height = pixelsFromNrgbaPng(img) + nrgbaImg := prism.ConvertImageToNRGBA(img, 2) + tex := Texture{ + Path: "", + Pixels: nrgbaImg.Pix, + Height: int32(nrgbaImg.Bounds().Dy()), + Width: int32(nrgbaImg.Bounds().Dx()), + } //Prepare opengl stuff gl.GenTextures(1, &tex.TexID) @@ -126,7 +134,7 @@ func LoadTextureInMemPngImg(img image.Image, loadOptions *TextureLoadOptions) (T gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) // load and generate the texture - gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, tex.Width, tex.Height, 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&tex.Pixels[0])) + gl.TexImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, tex.Width, tex.Height, 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&tex.Pixels[0])) if loadOptions.GenMipMaps { gl.GenerateMipmap(tex.TexID) @@ -166,12 +174,14 @@ func LoadTextureJpeg(file string, loadOptions *TextureLoadOptions) (Texture, err return Texture{}, err } + nrgbaImg := prism.ConvertImageToNRGBA(img, 2) tex := Texture{ - Path: file, + Path: file, + Pixels: nrgbaImg.Pix, + Height: int32(nrgbaImg.Bounds().Dy()), + Width: int32(nrgbaImg.Bounds().Dx()), } - tex.Pixels, tex.Width, tex.Height = pixelsFromNrgbaPng(img) - //Prepare opengl stuff gl.GenTextures(1, &tex.TexID) gl.BindTexture(gl.TEXTURE_2D, tex.TexID) @@ -183,7 +193,7 @@ func LoadTextureJpeg(file string, loadOptions *TextureLoadOptions) (Texture, err gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) // load and generate the texture - gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, tex.Width, tex.Height, 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&tex.Pixels[0])) + gl.TexImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, tex.Width, tex.Height, 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&tex.Pixels[0])) if loadOptions.GenMipMaps { gl.GenerateMipmap(tex.TexID) @@ -200,65 +210,14 @@ func LoadTextureJpeg(file string, loadOptions *TextureLoadOptions) (Texture, err return tex, nil } -func pixelsFromNrgbaPng(img image.Image) (pixels []byte, width, height int32) { - - //NOTE: Load bottom left to top right because this is the texture coordinate system used by OpenGL - //NOTE: We only support 8-bit channels (32-bit colors) for now - i := 0 - width, height = int32(img.Bounds().Dx()), int32(img.Bounds().Dy()) - pixels = make([]byte, img.Bounds().Dx()*img.Bounds().Dy()*4) - for y := img.Bounds().Dy() - 1; y >= 0; y-- { - for x := 0; x < img.Bounds().Dx(); x++ { - - c := color.NRGBAModel.Convert(img.At(x, y)).(color.NRGBA) - - pixels[i] = c.R - pixels[i+1] = c.G - pixels[i+2] = c.B - pixels[i+3] = c.A - - i += 4 - } - } - - return pixels, width, height -} - -func pixelsFromNrgbaJpg(img image.Image) (pixels []byte, width, height int32) { - - //NOTE: Load bottom left to top right because this is the texture coordinate system used by OpenGL - //NOTE: We only support 8-bit channels (32-bit colors) for now - i := 0 - width, height = int32(img.Bounds().Dx()), int32(img.Bounds().Dy()) - pixels = make([]byte, img.Bounds().Dx()*img.Bounds().Dy()*4) - for y := img.Bounds().Dy() - 1; y >= 0; y-- { - for x := 0; x < img.Bounds().Dx(); x++ { - - c := color.NRGBAModel.Convert(img.At(x, y)).(color.NRGBA) - - pixels[i] = c.R - pixels[i+1] = c.G - pixels[i+2] = c.B - pixels[i+3] = c.A - - i += 4 - } - } - - return pixels, width, height -} - func LoadCubemapTextures(rightTex, leftTex, topTex, botTex, frontTex, backTex string) (Cubemap, error) { var imgDecoder func(r io.Reader) (image.Image, error) - var pixelDecoder func(image.Image) ([]byte, int32, int32) ext := strings.ToLower(path.Ext(rightTex)) if ext == ".jpg" || ext == ".jpeg" { imgDecoder = jpeg.Decode - pixelDecoder = pixelsFromNrgbaJpg } else if ext == ".png" { imgDecoder = png.Decode - pixelDecoder = pixelsFromNrgbaPng } else { return Cubemap{}, fmt.Errorf("unknown image extension: %s. Expected one of: .jpg, .jpeg, .png", ext) } @@ -292,9 +251,11 @@ func LoadCubemapTextures(rightTex, leftTex, topTex, botTex, frontTex, backTex st return Cubemap{}, err } - pixels, width, height := pixelDecoder(img) + nrgbaImg := prism.ConvertImageToNRGBA(img, 2) + height := int32(nrgbaImg.Bounds().Dy()) + width := int32(nrgbaImg.Bounds().Dx()) - gl.TexImage2D(uint32(gl.TEXTURE_CUBE_MAP_POSITIVE_X)+i, 0, gl.RGBA8, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&pixels[0])) + gl.TexImage2D(uint32(gl.TEXTURE_CUBE_MAP_POSITIVE_X)+i, 0, gl.RGBA8, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&nrgbaImg.Pix[0])) } // set the texture wrapping/filtering options (on the currently bound texture object) diff --git a/go.mod b/go.mod index 8272b77..9ac337d 100755 --- a/go.mod +++ b/go.mod @@ -12,3 +12,8 @@ require ( ) require github.com/AllenDang/cimgui-go v0.0.0-20230720025235-f2ff398a66b2 + +require ( + github.com/mandykoh/go-parallel v0.1.0 // indirect + github.com/mandykoh/prism v0.35.1 // indirect +) diff --git a/go.sum b/go.sum index 077a668..81d4694 100755 --- a/go.sum +++ b/go.sum @@ -6,5 +6,34 @@ github.com/bloeys/gglm v0.43.0 h1:ZpOghR3PHfpkigTDh+FqxLsF0gN8CD6s/bWoei6LyxI= github.com/bloeys/gglm v0.43.0/go.mod h1:qwJQ0WzV191wAMwlGicbfbChbKoSedMk7gFFX6GnyOk= github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk= github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= +github.com/mandykoh/go-parallel v0.1.0 h1:7vJMNMC4dsbgZdkAb2A8tV5ENY1v7VxIO1wzQWZoT8k= +github.com/mandykoh/go-parallel v0.1.0/go.mod h1:lkYHqG1JNTaSS6lG+PgFCnyMd2VDy8pH9jN9pY899ig= +github.com/mandykoh/prism v0.35.1 h1:JbQfQarANxSWlgJEpjv+E7DvtrqBaVP1YgJfZPvo6ME= +github.com/mandykoh/prism v0.35.1/go.mod h1:3miB3EAJ0IggYl/4eBB5MmawRbyJI1gKDtbrVvk8Q9I= github.com/veandco/go-sdl2 v0.4.35 h1:NohzsfageDWGtCd9nf7Pc3sokMK/MOK+UA2QMJARWzQ= github.com/veandco/go-sdl2 v0.4.35/go.mod h1:OROqMhHD43nT4/i9crJukyVecjPNYYuCofep6SNiAjY= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/res/textures/sb-back.jpg b/res/textures/sb-back.jpg index f06af73..750fd26 100755 Binary files a/res/textures/sb-back.jpg and b/res/textures/sb-back.jpg differ diff --git a/res/textures/sb-bottom.jpg b/res/textures/sb-bottom.jpg index 893f394..dff8205 100755 Binary files a/res/textures/sb-bottom.jpg and b/res/textures/sb-bottom.jpg differ diff --git a/res/textures/sb-front.jpg b/res/textures/sb-front.jpg index 06cd457..b9db5eb 100755 Binary files a/res/textures/sb-front.jpg and b/res/textures/sb-front.jpg differ diff --git a/res/textures/sb-left.jpg b/res/textures/sb-left.jpg index d136d18..766bc8f 100755 Binary files a/res/textures/sb-left.jpg and b/res/textures/sb-left.jpg differ diff --git a/res/textures/sb-right.jpg b/res/textures/sb-right.jpg index f5e461e..375b158 100755 Binary files a/res/textures/sb-right.jpg and b/res/textures/sb-right.jpg differ diff --git a/res/textures/sb-top.jpg b/res/textures/sb-top.jpg index 4db3c2a..9b73000 100755 Binary files a/res/textures/sb-top.jpg and b/res/textures/sb-top.jpg differ