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 }
// ActiveTexture implements the opengl.OpenGl interface. func (native *OpenGl) ActiveTexture(texture uint32) { gl.ActiveTexture(texture) }