Loading textures -> slow!

BlitzMax Forums/OpenGL Module/Loading textures -> slow!

bytecode77(Posted 2006) [#1]
hi!

just a question:
i am loading textures in my openGL engine by opening the image file and putting each texel into the bank like that:

Function LoadTexture(file$, flags = 0)
img = LoadImage(file$)
w = ImageWidth(img)
h = ImageHeight(img)
nw = GetWidth(w)
nh = GetWidth(h)
t.texture = New texture
t\bank = CreateBank(12)
t\w = nw / BLE_TextureQuality
t\h = nh / BLE_TextureQuality
t\sx# = 1
t\sy# = 1
bank_size = t\w * t\h * 3
bank_img = CreateBank(bank_size)
ib = ImageBuffer(img)
LockBuffer ib
For y = 0 To t\h - 1
	off = bank_size - (y + 1) * t\w * 3
	For x = 0 To t\w - 1
		rgb = ReadPixelFast(w * x * BLE_TextureQuality / nw, h * y * BLE_TextureQuality / nh, ib)
		PokeByte bank_img, off, (rgb And $FF0000) Shr 16
		PokeByte bank_img, off + 1, (rgb And $FF00) Shr 8
		PokeByte bank_img, off + 2, rgb And $FF
		off = off + 3
	Next
Next
UnlockBuffer ib
FreeImage img
glGenTextures 3, t\bank
glBindTexture GL_TEXTURE_2D, PeekInt(t\bank, 0)
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST
glTexImage2D GL_TEXTURE_2D, 0, 3, t\w, t\h, 0, GL_RGB, GL_UNSIGNED_BYTE, bank_img
glBindTexture GL_TEXTURE_2D, PeekInt(t\bank, 4)
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
glTexImage2D GL_TEXTURE_2D, 0, 3, t\w, t\h, 0, GL_RGB, GL_UNSIGNED_BYTE, bank_img
glBindTexture GL_TEXTURE_2D, PeekInt(t\bank, 8)
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR
gluBuild2DMipmaps GL_TEXTURE_2D, 3, t\w, t\h, GL_RGB, GL_UNSIGNED_BYTE, bank_img
FreeBank bank_img
Return Handle(t)
End Function


this is extremely slow because i am using ~20 textures about 512*512 on a little demo map. isn't there any way to make it work faster?

thanks.


klepto2(Posted 2006) [#2]
Maybe this one could be usefull for you. It is the loadtexture
method off 'minib3d'.




bytecode77(Posted 2006) [#3]
nope, sorry. my problem is, that pushing each of the (256^2)*20 texels into data banks is very slow. even on debuger off.
a c++ library would be useful, but i don't know how. so i think i have to improve it in blitz.


ImaginaryHuman(Posted 2006) [#4]
You don't need to load image. Load image means loads the data into main memory, upload it to the graphics card as a texture, then you're also doing al lock image which then has to download the image from the graphics card and turn it into a pixmap, then you're doing additional processing on it.

Use LoadPixmap. Also do not use PokeByte or ReadPixelFast, use pointer and treat the data like an array e.g. Data[Offset]. If you use PokeByte for every pixel you are causing it to look up the bank object, read the bank's base pointer, you have to calculate x and y offsets turned into an address, and then access the pixel. Very slow. Just have a source pointer and dest pointer and read whole Int's at a time where possible and use binary operations to shift stuff around and get the values where you want them. To make it even faster you can load RAW graphics data directly into the bank, perhaps a line at a time if you need a modulo, which is faster yet then decompressing an image. I do that for 20 512x512 alpha channel images and it takes about a second to load.


bytecode77(Posted 2006) [#5]
oh well :0. i don't quite understand. is there a code snippet out there somewhere?
edit: oh and i am programming in bb, not bmx. is there still a way?


JoshK(Posted 2006) [#6]
I do this by loading my own texture format straight into a pixelmap, then setting the gl texture pixels with this. I still haven't figured out how to store pixel data in the compressed format, and load the compressed data straight into OpenGL...it would be a lot faster.


bytecode77(Posted 2006) [#7]
i know. the stf format... it has the same size as your textures would have in bmp.

i tested it. 2 shorts for w/h in the file and then for each pixel 3 bytes in the texture format file. this is not very faster :(

edit: 9500 ms loading jpg. 6800 ms loading own texture format


JoshK(Posted 2006) [#8]
Instead of reading a byte for each pixel, just copy the whole pixel data at once with ReadBytes().


bytecode77(Posted 2006) [#9]
neither slow.