func (this *Window) initGL() { gl.ShadeModel(gl.SMOOTH) //SMOOTH or FLAT gl.CullFace(gl.BACK) gl.FrontFace(gl.CCW) gl.Enable(gl.CULL_FACE) gl.Enable(gl.DEPTH_TEST) gl.Enable(gl.LIGHTING) gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) /*gl.Enable(gl.FOG) gl.Fogi(gl.FOG_MODE, gl.EXP) gl.Fogfv(gl.FOG_COLOR, []float32{0.5,0.5,0.5,1.0}) gl.Fogf(gl.FOG_DENSITY, 0.0035) gl.Hint(gl.FOG_HINT, gl.DONT_CARE) gl.Fogf(gl.FOG_START, 1.0) gl.Fogf(gl.FOG_END , 5000.0)//*/ gl.Enable(gl.TEXTURE_2D) gl.TexEnvf(gl.TEXTURE_ENV, gl.TEXTURE_ENV_MODE, gl.MODULATE) //before: decal, std: modulate //gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP, true) //mipmaps (dont use it!, its bad!) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) //GL_LINEAR or GL_NEAREST, no mipmap here gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) //*/ gl.ClearColor(.1, .1, .1, 1) //gl.Enable(gl.PRIMITIVE_RESTART) //gl.PrimitiveRestartIndex() this.setGLViewport() }
func loadTexture(path string) (*gl.Texture, error) { file, err := os.Open(path) if err != nil { } defer file.Close() srcimg, _, err := image.Decode(file) if err != nil { return nil, err } // convert to RGBA if not already b := srcimg.Bounds() var dstimg *image.RGBA if srcimg.ColorModel() != color.RGBAModel { dstimg = image.NewRGBA(b) draw.Draw(dstimg, b, srcimg, b.Min, draw.Src) } else { dstimg = srcimg.(*image.RGBA) } tex := gl.GenTexture() tex.Bind(gl.TEXTURE_2D) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, b.Dx(), b.Dy(), 0, gl.RGBA, gl.UNSIGNED_BYTE, dstimg.Pix) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) return &tex, nil }
func (this *Window) initGL() { runtime.LockOSThread() if gl.Init() != 0 { panic("gl init error") } gl.ShadeModel(gl.SMOOTH) gl.CullFace(gl.BACK) gl.FrontFace(gl.CCW) gl.Enable(gl.CULL_FACE) gl.Enable(gl.DEPTH_TEST) gl.Enable(gl.LIGHTING) gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.Enable(gl.TEXTURE_2D) gl.TexEnvf(gl.TEXTURE_ENV, gl.TEXTURE_ENV_MODE, gl.MODULATE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) var magFilter, minFilter = gl.LINEAR, gl.LINEAR if globals.CreateMipmaps { minFilter = gl.LINEAR_MIPMAP_LINEAR } gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter) gl.Enable(gl.NORMALIZE) gl.ClearColor(.1, .1, .1, 1) this.setGLViewport() }
func uploadTexture_NRGBA32(img *image.NRGBA) gl.Texture { b := img.Bounds() data := make([]uint8, b.Max.X*b.Max.Y*4) for y := 0; y < b.Max.Y; y++ { for x := 0; x < b.Max.X; x++ { p := img.At(x, y) offset := y*b.Max.X*4 + x*4 r, g, b, a := p.RGBA() data[offset+0] = uint8(r) data[offset+1] = uint8(g) data[offset+2] = uint8(b) data[offset+3] = uint8(a) } } id := gl.GenTexture() id.Bind(gl.TEXTURE_2D) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, b.Max.X, b.Max.Y, 0, gl.RGBA, gl.UNSIGNED_BYTE, data) if gl.GetError() != gl.NO_ERROR { id.Delete() panic(errors.New("Failed to load a texture")) return 0 } return id }
// Load bitmap from path as GL texture func LoadGLTexture(path string) { image := sdl.Load(path) if image == nil { panic(sdl.GetError()) } // Check that the image's width is a power of 2 if image.W&(image.W-1) != 0 { fmt.Println("warning:", path, "has a width that is not a power of 2") } // Also check if the height is a power of 2 if image.H&(image.H-1) != 0 { fmt.Println("warning:", path, "has an height that is not a power of 2") } // get the number of channels in the SDL surface nOfColors := image.Format.BytesPerPixel var textureFormat gl.GLenum if nOfColors == 4 { // contains alpha channel if image.Format.Rmask == 0x000000ff { textureFormat = gl.RGBA } else { textureFormat = gl.BGRA } } else if nOfColors == 3 { // no alpha channel if image.Format.Rmask == 0x000000ff { textureFormat = gl.RGB } else { textureFormat = gl.BGR } } else { fmt.Println("warning:", path, "is not truecolor, this will probably break") } texture = gl.GenTexture() // Typical texture generation using data from the bitmap gl.BindTexture(gl.TEXTURE_2D, uint(texture)) // Generate the texture gl.TexImage2D(gl.TEXTURE_2D, 0, int(image.Format.BytesPerPixel), int(image.W), int(image.H), 0, textureFormat, gl.UNSIGNED_BYTE, image.Pixels, ) // linear filtering gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) // free up memory we have used. image.Free() }
func uploadTexture(img *image.RGBA) gl.Texture { gl.Enable(gl.TEXTURE_2D) tex := gl.GenTexture() tex.Bind(gl.TEXTURE_2D) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexImage2D(gl.TEXTURE_2D, 0, 4, img.Bounds().Max.X, img.Bounds().Max.Y, 0, gl.RGBA, gl.UNSIGNED_BYTE, img.Pix) gl.Disable(gl.TEXTURE_2D) return tex }
func (t *TextureData) LoadIntoGL() { t.id.Bind(gl.TEXTURE_2D) for i, v := range t.Mips { gl.TexImage2D(gl.TEXTURE_2D, i, gl.RGBA, v.w, v.h, 0, gl.RGBA, gl.UNSIGNED_BYTE, v.Pix) if !globals.CreateMipmaps { gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) break //just one level if no mipmaps are wanted } } t.Unbind() }
func (t *Skybox) RenderScaled(center, scale *Vec3) { v := []*Vec3{ V3(-1, -1, 1), V3(1, -1, 1), V3(1, 1, 1), V3(-1, 1, 1), V3(-1, -1, -1), V3(1, -1, -1), V3(1, 1, -1), V3(-1, 1, -1)} for i := 0; i < 8; i++ { v[i].Muli(scale).Addi(center) } if globals.UseShader { program.Unuse() } //*//save attributes and change them gl.PushAttrib(gl.ENABLE_BIT | gl.TEXTURE_BIT) defer gl.PopAttrib() //reset to old attributes gl.Enable(gl.TEXTURE_2D) gl.Disable(gl.DEPTH_TEST) gl.Disable(gl.LIGHTING) gl.Disable(gl.BLEND) //*/ oneSide := func(tex *texture.Texture, a, b, c, d int, n *Vec3) { tex.BindForSkybox(color.White) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.Begin(gl.TRIANGLES) gl.Normal3dv(n.Slc()) gl.TexCoord2i(0, 0) gl.Vertex3dv(v[a].Slc()) gl.TexCoord2i(1, 0) gl.Vertex3dv(v[b].Slc()) gl.TexCoord2i(1, 1) gl.Vertex3dv(v[c].Slc()) gl.TexCoord2i(0, 0) gl.Vertex3dv(v[a].Slc()) gl.TexCoord2i(1, 1) gl.Vertex3dv(v[c].Slc()) gl.TexCoord2i(0, 1) gl.Vertex3dv(v[d].Slc()) gl.End() } oneSide(t.up, 2, 3, 7, 6, V3(0, -1, 0)) oneSide(t.dn, 5, 4, 0, 1, V3(0, 1, 0)) oneSide(t.lt, 5, 1, 2, 6, V3(1, 0, 0)) oneSide(t.rt, 0, 4, 7, 3, V3(-1, 0, 0)) oneSide(t.ft, 1, 0, 3, 2, V3(0, 0, -1)) oneSide(t.bk, 4, 5, 6, 7, V3(0, 0, 1)) }
func NewFont(filename string, size int, c color.Color) *Font { var font Font font.textures = make(map[rune]gl.Texture) font.widths = make(map[rune]int) extfont := ttf.OpenFont(filename, size) if extfont == nil { panic("Could not load font") } defer extfont.Close() font.height = extfont.LineSkip() for _, ch := range "abcdefghijklmnopqrdstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :;@'<>,.?/~#{}[]!£$%^&*()_-+=\"\\|" { _, _, _, _, advance, err := extfont.GlyphMetrics(uint16(ch)) if err != 0 { panic("Could not get glyph metrics") } // Create a bitmap with width=advance, height=font.height surface := sdl.CreateRGBSurface(sdl.SWSURFACE|sdl.SRCALPHA, advance, font.height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000) //surface.FillRect(&sdl.Rect{0,0, uint16(advance), uint16(font.height)}, 0x0) // rect := sdl.Rect{0,0, uint16(advance), uint16(ascent)} // rect := sdl.Rect{int16(minx), int16(ascent)-int16(maxy), 0, 0} fontSurface := ttf.RenderText_Blended(extfont, string(ch), sdl.ColorFromGoColor(c)) fontSurface.Blit(nil, surface, nil) rgba := image.NewRGBA(image.Rect(0, 0, advance, font.height)) for x := 0; x < advance; x++ { for y := 0; y < font.height; y++ { rgba.Set(x, y, fontSurface.At(x, font.height-y)) } } font.widths[ch] = advance font.textures[ch] = gl.GenTexture() font.textures[ch].Bind(gl.TEXTURE_2D) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, advance, font.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, &rgba.Pix[0]) font.textures[ch].Unbind(gl.TEXTURE_2D) } return &font }
func loadTextures() (err error) { textures = make([]gl.Texture, len(texturefiles)) gl.GenTextures(textures) for i := range texturefiles { textures[i].Bind(gl.TEXTURE_2D) if glfw.LoadTexture2D(texturefiles[i], 0) { return errors.New("Failed to load texture: " + texturefiles[i]) } gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) } return }
// load in bitmap as a GL texture func LoadGLTextures(path string) { // storage space for the textures image, format := LoadImage(path) // Create the textures gl.GenTextures(textures[:]) genTexture(textures[0], image, format) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) genTexture(textures[1], image, format) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) genTexture(textures[2], image, format) gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP, gl.TRUE) }
func uploadTexture_RGBA32(w, h int, data []byte) gl.Texture { id := gl.GenTexture() id.Bind(gl.TEXTURE_2D) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int(w), int(h), 0, gl.RGBA, gl.UNSIGNED_BYTE, data) if gl.GetError() != gl.NO_ERROR { id.Delete() panic("Failed to load a texture") return 0 } return id }
func (v *Video) Render() { for running { select { case dimensions := <-v.resize: v.ResizeEvent(dimensions[0], dimensions[1]) case val := <-v.tick: slice := make([]uint8, len(val)*3) for i := 0; i < len(val); i = i + 1 { slice[i*3+0] = (uint8)((val[i] >> 16) & 0xff) slice[i*3+1] = (uint8)((val[i] >> 8) & 0xff) slice[i*3+2] = (uint8)((val[i]) & 0xff) } gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) v.tex.Bind(gl.TEXTURE_2D) if ppu.OverscanEnabled { gl.TexImage2D(gl.TEXTURE_2D, 0, 3, 240, 224, 0, gl.RGB, gl.UNSIGNED_BYTE, slice) } else { gl.TexImage2D(gl.TEXTURE_2D, 0, 3, 256, 240, 0, gl.RGB, gl.UNSIGNED_BYTE, slice) } gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) gl.Begin(gl.QUADS) gl.TexCoord2f(0.0, 1.0) gl.Vertex3f(-1.0, -1.0, 0.0) gl.TexCoord2f(1.0, 1.0) gl.Vertex3f(1.0, -1.0, 0.0) gl.TexCoord2f(1.0, 0.0) gl.Vertex3f(1.0, 1.0, 0.0) gl.TexCoord2f(0.0, 0.0) gl.Vertex3f(-1.0, 1.0, 0.0) gl.End() if v.screen != nil { sdl.GL_SwapBuffers() v.fpsmanager.FramerateDelay() } } } }
func loadTextures() (err error) { gl.GenTextures(textures) // Texture 1 textures[0].Bind(gl.TEXTURE_2D) if !glfw.LoadTexture2D(texturefile, 0) { return errors.New("Failed to load texture: " + texturefile) } gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) // Texture 2 textures[1].Bind(gl.TEXTURE_2D) if !glfw.LoadTexture2D(texturefile, 0) { return errors.New("Failed to load texture: " + texturefile) } gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) // Texture 3 textures[2].Bind(gl.TEXTURE_2D) if !glfw.LoadTexture2D(texturefile, glfw.BuildMipmapsBit) { return errors.New("Failed to load texture: " + texturefile) } gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR_MIPMAP_NEAREST) return }
func draw() { for y := 0; y < Size; y++ { for x := 0; x < Size; x++ { var color uint8 if grid.Front()[y][x] { color = 0x00 } else { color = 0xFF } pixels[(y*Size+x)*3+0] = color pixels[(y*Size+x)*3+1] = color pixels[(y*Size+x)*3+2] = color } } gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) gl.TexImage2D(gl.TEXTURE_2D, 0, 3, Size, Size, 0, gl.RGB, gl.UNSIGNED_BYTE, pixels) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) gl.Begin(gl.QUADS) gl.TexCoord2f(0.0, 1.0) gl.Vertex3f(-1.0, -1.0, 0.0) gl.TexCoord2f(1.0, 1.0) gl.Vertex3f(1.0, -1.0, 0.0) gl.TexCoord2f(1.0, 0.0) gl.Vertex3f(1.0, 1.0, 0.0) gl.TexCoord2f(0.0, 0.0) gl.Vertex3f(-1.0, 1.0, 0.0) gl.End() glfw.SwapBuffers() }
func (v *Video) Render() { runtime.LockOSThread() for running { select { case val := <-v.tick: slice := make([]uint8, len(val)*3) for i := 0; i < len(val); i = i + 1 { slice[i*3+0] = (uint8)((val[i] >> 16) & 0xff) slice[i*3+1] = (uint8)((val[i] >> 8) & 0xff) slice[i*3+2] = (uint8)((val[i]) & 0xff) } gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) v.tex.Bind(gl.TEXTURE_2D) gl.TexImage2D(gl.TEXTURE_2D, 0, 3, 256, 240, 0, gl.RGB, gl.UNSIGNED_BYTE, slice) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) gl.Begin(gl.QUADS) gl.TexCoord2f(0.0, 1.0) gl.Vertex3f(-1.0, -1.0, 0.0) gl.TexCoord2f(1.0, 1.0) gl.Vertex3f(1.0, -1.0, 0.0) gl.TexCoord2f(1.0, 0.0) gl.Vertex3f(1.0, 1.0, 0.0) gl.TexCoord2f(0.0, 0.0) gl.Vertex3f(-1.0, 1.0, 0.0) gl.End() glfw.SwapBuffers() v.fpsmanager.FramerateDelay() } } }
// load in bitmap as a GL texture func LoadGLTextures(path string) { image := sdl.Load(path) if image == nil { panic(sdl.GetError()) } // Check that the image's width is a power of 2 if image.W&(image.W-1) != 0 { fmt.Println("warning:", path, "has a width that is not a power of 2") } // Also check if the height is a power of 2 if image.H&(image.H-1) != 0 { fmt.Println("warning:", path, "has an height that is not a power of 2") } // get the number of channels in the SDL surface nOfColors := image.Format.BytesPerPixel var textureFormat gl.GLenum if nOfColors == 4 { // contains alpha channel if image.Format.Rmask == 0x000000ff { textureFormat = gl.RGBA } else { textureFormat = gl.BGRA } } else if nOfColors == 3 { // no alpha channel if image.Format.Rmask == 0x000000ff { textureFormat = gl.RGB } else { textureFormat = gl.BGR } } else { fmt.Println("warning:", path, "is not truecolor, this will probably break") } // Create the textures gl.GenTextures(textures[:]) // First texture gl.BindTexture(gl.TEXTURE_2D, uint(textures[0])) gl.TexImage2D( gl.TEXTURE_2D, 0, 3, int(image.W), int(image.H), 0, textureFormat, gl.UNSIGNED_BYTE, image.Pixels, ) // linear filtering gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) // Second texture gl.BindTexture(gl.TEXTURE_2D, uint(textures[1])) gl.TexImage2D(gl.TEXTURE_2D, 0, 3, int(image.W), int(image.H), 0, textureFormat, gl.UNSIGNED_BYTE, image.Pixels, ) // Mipmapped filtering gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) // Third texture gl.BindTexture(gl.TEXTURE_2D, uint(textures[2])) gl.TexImage2D(gl.TEXTURE_2D, 0, 3, int(image.W), int(image.H), 0, textureFormat, gl.UNSIGNED_BYTE, image.Pixels, ) // Mipmapped filtering gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) glu.Build2DMipmaps( gl.TEXTURE_2D, 3, int(image.W), int(image.H), textureFormat, image.Pixels, ) }