func NewImage(path string) (retImg image, err error) { imgFile, err := os.Open(path) if err != nil { return image{}, err } img, _, err := Image.Decode(imgFile) if err != nil { return image{}, err } rgba := Image.NewRGBA(img.Bounds()) if rgba.Stride != rgba.Rect.Size().X*4 { return image{}, fmt.Errorf("unsupported stride") } draw.Draw(rgba, rgba.Bounds(), img, Image.Point{0, 0}, draw.Src) var texture uint32 gl.GenTextures(1, &texture) // gl.ActiveTexture(gl.TEXTURE1) gl.BindTexture(gl.TEXTURE_2D, texture) 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, int32(rgba.Rect.Size().X), int32(rgba.Rect.Size().Y), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba.Pix)) if gl.GetError() != gl.NO_ERROR { return image{}, fmt.Errorf("Failed to load texture: " + path) } return image{data: &img, textureId: texture, width: rgba.Rect.Size().X, height: rgba.Rect.Size().Y}, nil }
func newOctree(file string) (uint32, []uint32, error) { var ( header pack.OctreeHeader texture uint32 data []uint32 ) fp, err := os.Open(file) if err != nil { return 0, nil, err } defer fp.Close() if err := pack.DecodeHeader(fp, &header); err != nil { return 0, nil, err } if header.Format != pack.MipR8G8B8A8UnpackUI32 { return 0, nil, errors.New("invalid octree format") } nodeSize := uint64(1 + 8) var maxSize int32 gl.GetIntegerv(gl.MAX_TEXTURE_SIZE, &maxSize) numInts := header.NumNodes * nodeSize if maxSize*maxSize < int32(numInts) { panic("octree does not fit on GPU") } var ( height int32 width = maxSize ) for height < width { maxSize = width height = int32(numInts/uint64(width)) + 1 width /= 2 } fmt.Printf("Octree is loaded in an %vx%v, R32UI, 2D texture.\n", maxSize, height) textureSize := maxSize * height data = make([]uint32, textureSize) for i := uint64(0); i < header.NumNodes; i++ { start := i * nodeSize if err := binary.Read(fp, binary.BigEndian, data[start:start+nodeSize]); err != nil { return 0, nil, err } // Recalculate alpha value. data[start] &= 0xffffff00 for j := uint64(1); j < 9; j++ { if data[start+j] > 0 { data[start] |= uint32(0x100) >> j } } } gl.GenTextures(1, &texture) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, texture) 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.R32UI, maxSize, height, 0, gl.RED_INTEGER, gl.UNSIGNED_INT, gl.Ptr(data)) if glErr := gl.GetError(); glErr != gl.NO_ERROR { err = fmt.Errorf("GL error, loading octree: %x", glErr) } return texture, data, err }
// TexImage2D implements the opengl.OpenGl interface. func (native *OpenGl) TexImage2D(target uint32, level int32, internalFormat uint32, width int32, height int32, border int32, format uint32, xtype uint32, pixels interface{}) { gl.TexImage2D(target, level, int32(internalFormat), width, height, border, format, xtype, gl.Ptr(pixels)) }