Beispiel #1
0
func MakeTextures(num gl.Sizei, glPtr []gl.Uint, dimensions uint8, texFormat gl.Enum, width, height, depth gl.Sizei) {
	var is3d, is2d = (dimensions == 3), (dimensions == 2)
	var texTarget gl.Enum = gltypes.Ife(is3d, gl.TEXTURE_3D, gltypes.Ife(is2d, gl.TEXTURE_2D, gl.TEXTURE_1D))
	gl.GenTextures(num, &glPtr[0])
	PanicIfErrors("MakeTextures.GenTextures(num=%v)", num)
	if width == 0 {
		panic("MakeTextures() needs at least width")
	}
	if height == 0 {
		height = width
	}
	if depth == 0 {
		depth = height
	}
	for i := 0; i < len(glPtr); i++ {
		gl.BindTexture(texTarget, glPtr[i])
		gl.TexParameteri(texTarget, gl.TEXTURE_MAG_FILTER, TexFilter)
		gl.TexParameteri(texTarget, gl.TEXTURE_MIN_FILTER, TexFilter)
		gl.TexParameteri(texTarget, gl.TEXTURE_WRAP_R, TexWrap)
		gl.TexParameteri(texTarget, gl.TEXTURE_WRAP_S, TexWrap)
		gl.TexParameteri(texTarget, gl.TEXTURE_WRAP_T, TexWrap)
		if is3d {
			gl.TexStorage3D(texTarget, 1, texFormat, width, height, depth)
		} else if is2d {
			gl.TexStorage2D(texTarget, 1, texFormat, width, height)
		} else {
			gl.TexStorage1D(texTarget, 1, texFormat, width)
		}
		gl.BindTexture(texTarget, 0)
		PanicIfErrors("MakeTextures.Loop(i=%v dim=%v w=%v h=%v d=%v)", i, dimensions, width, height, depth)
	}
}
Beispiel #2
0
func MakeTextureFromImageFile(filePath string) gl.Uint {
	var file, err = os.Open(filePath)
	var img image.Image
	var tex gl.Uint
	if err != nil {
		panic(err)
	}
	defer file.Close()
	img, _, err = image.Decode(file)
	if err != nil {
		panic(err)
	}
	w, h := img.Bounds().Dx(), img.Bounds().Dy()
	sw, sh := gl.Sizei(w), gl.Sizei(h)
	rgba := image.NewRGBA(image.Rect(0, 0, w, h))
	for x := 0; x < w; x++ {
		for y := 0; y < h; y++ {
			rgba.Set(x, y, img.At(x, h-1-y))
		}
	}
	gl.GenTextures(1, &tex)
	gl.BindTexture(gl.TEXTURE_2D, tex)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)
	gl.TexStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, sw, sh)
	gl.TexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, sw, sh, gl.RGBA, gl.UNSIGNED_BYTE, gl.Pointer(&rgba.Pix[0]))
	gl.BindTexture(gl.TEXTURE_2D, 0)
	PanicIfErrors("MakeTextureFromImageFile(%v)", filePath)
	return tex
}
Beispiel #3
0
func MakeRttFramebuffer(texFormat gl.Enum, width, height, mipLevels gl.Sizei, anisoFiltering gl.Int) (gl.Uint, gl.Uint) {
	var glPtrTex, glPtrFrameBuf gl.Uint
	var glMagFilter, glMinFilter gl.Int = gl.LINEAR, gl.LINEAR
	if anisoFiltering < 1 {
		glMagFilter, glMinFilter = gl.NEAREST, gl.NEAREST
	}
	if mipLevels > 1 {
		if anisoFiltering < 1 {
			glMinFilter = gl.NEAREST_MIPMAP_NEAREST
		} else {
			glMinFilter = gl.LINEAR_MIPMAP_LINEAR
		}
	}
	gl.GenTextures(1, &glPtrTex)
	gl.BindTexture(gl.TEXTURE_2D, glPtrTex)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glMagFilter)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glMinFilter)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_BORDER)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_BORDER)
	if anisoFiltering > 1 {
		gl.TexParameteri(gl.TEXTURE_2D, 0x84FE, anisoFiltering)
	} // max 16
	gl.TexStorage2D(gl.TEXTURE_2D, mipLevels, texFormat, width, height)
	gl.GenFramebuffers(1, &glPtrFrameBuf)
	gl.BindFramebuffer(gl.FRAMEBUFFER, glPtrFrameBuf)
	gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, glPtrTex, 0)
	gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
	gl.BindTexture(gl.TEXTURE_2D, 0)
	PanicIfErrors("MakeRttFramebuffer")
	return glPtrFrameBuf, glPtrTex
}
Beispiel #4
0
func main() {
	initialWidth, initialHeight := 1280, 720
	runtime.LockOSThread()
	if sdlInit := sdl.Init(sdl.INIT_VIDEO); sdlInit != 0 {
		panic("SDL init error")
	}
	reinitScreen(initialWidth, initialHeight)
	defer cleanExit(true, false)
	if err := gl.Init(); err != nil {
		panic(err)
	}
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	gl.Enable(gl.DEPTH)
	defer cleanExit(false, true)
	glSetupShaderProg(&shaderTextureCreator, false)
	glSetupShaderProg(&shaderTextureDisplay, true)
	glFillBuffer(rttVerts, &rttVertBuf)
	glFillBuffer(dispVerts, &dispVertBuf)
	gl.GenTextures(1, &rttFrameTex)
	gl.BindTexture(gl.TEXTURE_2D, rttFrameTex)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)
	if doRtt {
		gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, nil)
		gl.GenFramebuffers(1, &rttFrameBuf)
		gl.BindFramebuffer(gl.FRAMEBUFFER, rttFrameBuf)
		gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, rttFrameTex, 0)
		gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
	} else {
		glFillTextureFromImageFile("texture.jpg")
	}
	gl.BindTexture(gl.TEXTURE_2D, 0)
	gl.ClearColor(0.3, 0.6, 0.9, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)
	gl.ActiveTexture(gl.TEXTURE0)
	for {
		if evt := sdl.PollEvent(); evt != nil {
			switch event := evt.(type) {
			case *sdl.ResizeEvent:
				reinitScreen(int(event.W), int(event.H))
			case *sdl.QuitEvent:
				return
			}
		} else {
			if doRtt {
				renderToTexture()
			}
			renderToScreen()
			sdl.GL_SwapBuffers()
		}
	}

	sdl.Quit()
}
Beispiel #5
0
func MakeTextureForTarget(glPtr *gl.Uint, dimensions uint8, width, height, depth gl.Sizei, texTarget gl.Enum, texFormat gl.Enum, panicIfErrors, reuseGlPtr bool) {
	var is3d, is2d = (dimensions == 3), (dimensions == 2)
	if texTarget == 0 {
		texTarget = gltypes.Ife(is3d, gl.TEXTURE_3D, gltypes.Ife(is2d, gl.TEXTURE_2D, gl.TEXTURE_1D))
	}
	if texFormat == 0 {
		texFormat = gl.RGBA8
	}
	if width == 0 {
		panic("MakeTextureForTarget() needs at least width")
	}
	if height == 0 {
		height = width
	}
	if depth == 0 {
		depth = height
	}
	if (!reuseGlPtr) || (*glPtr == 0) {
		gl.GenTextures(1, glPtr)
	}
	gl.BindTexture(texTarget, *glPtr)
	gl.TexParameteri(texTarget, gl.TEXTURE_MAG_FILTER, TexFilter)
	gl.TexParameteri(texTarget, gl.TEXTURE_MIN_FILTER, TexFilter)
	gl.TexParameteri(texTarget, gl.TEXTURE_WRAP_S, TexWrap)
	if is2d || is3d {
		gl.TexParameteri(texTarget, gl.TEXTURE_WRAP_T, TexWrap)
	}
	if is3d {
		gl.TexParameteri(texTarget, gl.TEXTURE_WRAP_R, TexWrap)
	}
	if is3d {
		gl.TexStorage3D(texTarget, 1, texFormat, width, height, depth)
	} else if is2d {
		gl.TexStorage2D(texTarget, 1, texFormat, width, height)
	} else {
		gl.TexStorage1D(texTarget, 1, texFormat, width)
	}
	gl.BindTexture(texTarget, 0)
	if panicIfErrors {
		PanicIfErrors("MakeTextureForTarget(dim=%v w=%v h=%v d=%v)", dimensions, width, height, depth)
	}
}
Beispiel #6
0
func loadVolume() {
	var file, err = os.Open("/home/roxor/apps/ImageVis3D/Data/BostonTeapot.raw")
	var bytes []byte
	if err != nil {
		panic(err)
	}
	defer file.Close()
	if bytes, err = ioutil.ReadAll(file); err != nil {
		panic(err)
	}
	gl.GenTextures(1, &volTex)
	gl.BindTexture(gl.TEXTURE_3D, volTex)
	gl.TexParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, glTexFilter)
	gl.TexParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, glTexFilter)
	gl.TexParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, glTexClamp)
	gl.TexParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, glTexClamp)
	gl.TexParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, glTexClamp)
	gl.TexImage3D(gl.TEXTURE_3D, 0, gl.ALPHA, 256, 256, 178, 0, gl.ALPHA, gl.UNSIGNED_BYTE, gl.Pointer(&bytes[0]))
	gl.BindTexture(gl.TEXTURE_3D, 0)
}
Beispiel #7
0
func MakeTextureFromImageFloatsFile(filePath string, w, h int) gl.Uint {
	var file, err = os.Open(filePath)
	var tex gl.Uint
	var pix = make([]gl.Float, w*h*3)
	var fVal float32
	var raw []uint8
	var buf *bytes.Buffer
	var i int
	if err != nil {
		panic(err)
	}
	defer file.Close()
	raw, err = ioutil.ReadAll(file)
	if err != nil {
		panic(err)
	}
	buf = bytes.NewBuffer(raw)
	for i = 0; (err == nil) && (i < len(pix)); i++ {
		if err = binary.Read(buf, binary.LittleEndian, &fVal); err == io.EOF {
			err = nil
			break
		} else if err == nil {
			pix[i] = gl.Float(fVal)
		}
	}
	if err != nil {
		panic(err)
	}
	sw, sh := gl.Sizei(w), gl.Sizei(h)
	gl.GenTextures(1, &tex)
	gl.BindTexture(gl.TEXTURE_2D, tex)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)
	gl.TexStorage2D(gl.TEXTURE_2D, 1, gl.RGB16F, sw, sh)
	gl.TexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, sw, sh, gl.RGB, gl.FLOAT, gl.Pointer(&pix[0]))
	gl.BindTexture(gl.TEXTURE_2D, 0)
	PanicIfErrors("MakeTextureFromImageFloatsFile(%v)", filePath)
	return tex
}
Beispiel #8
0
func renderToScreen() {
	gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
	gl.Viewport(0, 0, winWidth, winHeight)
	gl.UseProgram(shaderTextureDisplay.glProg)
	gl.BindTexture(gl.TEXTURE_2D, rttFrameTex)
	gl.Uniform1i(shaderTextureDisplay.unifTex, 0)
	gl.BindBuffer(gl.ARRAY_BUFFER, dispVertBuf)
	gl.EnableVertexAttribArray(shaderTextureDisplay.attrPos)
	gl.VertexAttribPointer(shaderTextureDisplay.attrPos, 3, gl.FLOAT, gl.FALSE, 0, gl.Pointer(nil))
	gl.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
	gl.DisableVertexAttribArray(shaderTextureDisplay.attrPos)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)
}
Beispiel #9
0
func renderToTexture() {
	gl.BindFramebuffer(gl.FRAMEBUFFER, rttFrameBuf)
	gl.Viewport(0, 0, texWidth, texHeight)
	gl.ClearColor(0.1, 0.2, 0.3, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
	gl.UseProgram(shaderTextureCreator.glProg)
	gl.BindTexture(gl.TEXTURE_3D, volTex)
	gl.Uniform1i(shaderTextureCreator.unifTex, 0)
	gl.BindBuffer(gl.ARRAY_BUFFER, rttVertBuf)
	gl.EnableVertexAttribArray(shaderTextureCreator.attrPos)
	gl.VertexAttribPointer(shaderTextureCreator.attrPos, 2, gl.FLOAT, gl.FALSE, 0, gl.Pointer(nil))
	gl.DrawArrays(gl.TRIANGLE_FAN, 0, 4)
	gl.DisableVertexAttribArray(shaderTextureCreator.attrPos)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)
}
Beispiel #10
0
func main() {
	var now = time.Now()
	initialWidth, initialHeight := 1280, 720
	runtime.LockOSThread()
	if sdlInit := sdl.Init(sdl.INIT_VIDEO); sdlInit != 0 {
		panic("SDL init error")
	}
	reinitScreen(initialWidth, initialHeight)
	defer cleanExit(true, false)
	if err := gl.Init(); err != nil {
		panic(err)
	}
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	gl.Enable(gl.DEPTH)
	sdl.WM_SetCaption("Loading volume...", "")
	loadVolume()
	defer cleanExit(false, true)
	sdl.WM_SetCaption("Compiling shaders...", "")
	glSetupShaderProg(&shaderTextureCreator)
	glSetupShaderProg(&shaderTextureDisplay)
	glFillBuffer(rttVerts, &rttVertBuf)
	glFillBuffer(dispVerts, &dispVertBuf)
	gl.GenTextures(1, &rttFrameTex)
	gl.BindTexture(gl.TEXTURE_2D, rttFrameTex)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glTexFilter)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glTexFilter)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, glTexClamp)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, glTexClamp)
	if doRtt && !noRtt {
		gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, nil)
		gl.GenFramebuffers(1, &rttFrameBuf)
		gl.BindFramebuffer(gl.FRAMEBUFFER, rttFrameBuf)
		gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, rttFrameTex, 0)
		gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
	} else {
		if noRtt {
			rttFrameBuf = 0
		} else {
			glFillTextureFromImageFile("texture.jpg")
		}
	}
	gl.BindTexture(gl.TEXTURE_2D, 0)
	gl.ClearColor(0.3, 0.2, 0.1, 1)
	gl.Clear(gl.COLOR_BUFFER_BIT)
	var looping = true
	var fps = 0
	var durSec time.Duration
	startTime, lastLoopTime, lastSecond = now, now, now
	sdl.WM_SetCaption("Up & running!", "")
	for looping {
		now = time.Now()
		if durSec = now.Sub(lastSecond); durSec.Seconds() >= 1 {
			sdl.WM_SetCaption(fmt.Sprintf("%v×%v @ %vfps", sdlScreen.W, sdlScreen.H, fps), "")
			fps = 0
			lastSecond = now
		} else {
			fps++
		}
		if evt := sdl.PollEvent(); evt != nil {
			switch event := evt.(type) {
			case *sdl.ResizeEvent:
				reinitScreen(int(event.W), int(event.H))
			case *sdl.QuitEvent:
				looping = false
			}
		}
		if doRtt || noRtt {
			renderToTexture()
		}
		if !noRtt {
			renderToScreen()
		}
		sdl.GL_SwapBuffers()
		lastLoopTime = now
	}
	sdl.Quit()
}
Beispiel #11
0
func MakeArrayBuffer(glPtr *gl.Uint, size uint64, sl interface{}, isLen, makeTex bool) gl.Uint {
	var ptr = gl.Pointer(nil)
	var glTex gl.Uint = 0
	var glTexFormat gl.Enum = gl.R8UI
	var sizeFactor, sizeTotal uint64 = 1, 0
	var tm = false
	var handle = func(sf uint64, glPtr gl.Pointer, le int, tf gl.Enum) {
		tm = true
		if le > 1 {
			ptr = glPtr
		}
		if size == 0 {
			size = uint64(le)
			isLen = true
		}
		if isLen {
			sizeFactor = sf
		}
		if tf != 0 {
			glTexFormat = tf
		}
	}
	if (sl == nil) && FillWithZeroes {
		sl = make([]uint8, size)
	}
	gl.GenBuffers(1, glPtr)
	gl.BindBuffer(gl.ARRAY_BUFFER, *glPtr)
	if sl != nil {
		if tv, tb := sl.([]uint8); tb {
			handle(1, gl.Pointer(&tv[0]), len(tv), gl.R8UI)
		}
		if tv, tb := sl.([]uint16); tb {
			handle(2, gl.Pointer(&tv[0]), len(tv), gl.R16UI)
		}
		if tv, tb := sl.([]uint32); tb {
			handle(4, gl.Pointer(&tv[0]), len(tv), gl.R32UI)
		}
		if tv, tb := sl.([]uint64); tb {
			handle(8, gl.Pointer(&tv[0]), len(tv), gl.RG32UI)
		}
		if tv, tb := sl.([]int8); tb {
			handle(1, gl.Pointer(&tv[0]), len(tv), gl.R8I)
		}
		if tv, tb := sl.([]int16); tb {
			handle(2, gl.Pointer(&tv[0]), len(tv), gl.R16I)
		}
		if tv, tb := sl.([]int32); tb {
			handle(4, gl.Pointer(&tv[0]), len(tv), gl.R32I)
		}
		if tv, tb := sl.([]int64); tb {
			handle(8, gl.Pointer(&tv[0]), len(tv), gl.RG32I)
		}
		if tv, tb := sl.([]float32); tb {
			handle(4, gl.Pointer(&tv[0]), len(tv), gl.R32F)
		}
		if tv, tb := sl.([]float64); tb {
			handle(8, gl.Pointer(&tv[0]), len(tv), gl.RG32F)
		}
		if tv, tb := sl.([]gl.Bitfield); tb {
			handle(4, gl.Pointer(&tv[0]), len(tv), gl.R8UI)
		}
		if tv, tb := sl.([]gl.Byte); tb {
			handle(1, gl.Pointer(&tv[0]), len(tv), gl.R8I)
		}
		if tv, tb := sl.([]gl.Ubyte); tb {
			handle(1, gl.Pointer(&tv[0]), len(tv), gl.R8UI)
		}
		if tv, tb := sl.([]gl.Ushort); tb {
			handle(2, gl.Pointer(&tv[0]), len(tv), gl.R16UI)
		}
		if tv, tb := sl.([]gl.Short); tb {
			handle(2, gl.Pointer(&tv[0]), len(tv), gl.R16I)
		}
		if tv, tb := sl.([]gl.Uint); tb {
			handle(4, gl.Pointer(&tv[0]), len(tv), gl.R32UI)
		}
		if tv, tb := sl.([]gl.Uint64); tb {
			handle(8, gl.Pointer(&tv[0]), len(tv), gl.RG32UI)
		}
		if tv, tb := sl.([]gl.Int); tb {
			handle(4, gl.Pointer(&tv[0]), len(tv), gl.R32I)
		}
		if tv, tb := sl.([]gl.Int64); tb {
			handle(8, gl.Pointer(&tv[0]), len(tv), gl.RG32I)
		}
		if tv, tb := sl.([]gl.Clampd); tb {
			handle(8, gl.Pointer(&tv[0]), len(tv), gl.RG32F)
		}
		if tv, tb := sl.([]gl.Clampf); tb {
			handle(4, gl.Pointer(&tv[0]), len(tv), gl.R32F)
		}
		if tv, tb := sl.([]gl.Float); tb {
			handle(4, gl.Pointer(&tv[0]), len(tv), gl.R32F)
		}
		if tv, tb := sl.([]gl.Half); tb {
			handle(2, gl.Pointer(&tv[0]), len(tv), gl.R16F)
		}
		if tv, tb := sl.([]gl.Double); tb {
			handle(8, gl.Pointer(&tv[0]), len(tv), gl.RG32F)
		}
		if tv, tb := sl.([]gl.Enum); tb {
			handle(4, gl.Pointer(&tv[0]), len(tv), gl.R32I)
		}
		if tv, tb := sl.([]gl.Sizei); tb {
			handle(4, gl.Pointer(&tv[0]), len(tv), gl.R32UI)
		}
		if tv, tb := sl.([]gl.Char); tb {
			handle(1, gl.Pointer(&tv[0]), len(tv), gl.R8UI)
		}
		if !tm {
			log.Panicf("MakeArrayBuffer() -- slice type unsupported:\n%+v", sl)
		}
	}
	sizeTotal = size * sizeFactor
	gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(sizeTotal), ptr, BufMode)
	if makeTex {
		if sizeTotal > MaxTextureBufferSize() {
			log.Panicf("Texture buffer size (%vMB) would exceed your GPU's maximum texture buffer size (%vMB)", sizeTotal/MB, maxTexBufSize/MB)
		}
		gl.GenTextures(1, &glTex)
		gl.BindTexture(gl.TEXTURE_BUFFER, glTex)
		gl.TexBuffer(gl.TEXTURE_BUFFER, glTexFormat, *glPtr)
		gl.BindTexture(gl.TEXTURE_2D, 0)
	}
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)
	PanicIfErrors("MakeArrayBuffer()")
	return glTex
}