Texture quality
Blitz3D Forums/Blitz3D Programming/Texture quality
| ||
How can I make the texture quality a variable? I'm talking about lowering the texture resolution. My code doesn't work properly, there's a problem with transparency atleast.;Loads a texture with error handling Function gLoadtexture(gfile$,gflags=0,optimize=1) gtext = LoadTexture(gfile$,gflags) If Main.Settings\LowQualityTexture > 0 And optimize=1 Then For a = 1 To Main.Settings\LowQualityTexture newwidth = TextureWidth(gtext)*0.5 newheight = TextureHeight(gtext)*0.5 If newwidth = 0 Then newwidth = 1 If newheight = 0 Then newheight = 1 newtexture = CreateTexture(newwidth,newheight,flags) newimage = CreateImage(TextureWidth(gtext),TextureHeight(gtext)) CopyRect 0,0,TextureWidth(gtext),TextureHeight(gtext),0,0,TextureBuffer(gtext),ImageBuffer(newimage) ScaleImage newimage,0.5,0.5 SetBuffer TextureBuffer(newtexture) DrawImage newimage,0,0 SetBuffer BackBuffer() FreeTexture gtext gtext = newtexture Next EndIf If Not gtext Then RuntimeError "Error loading texture " + gfile$ Return gtext End Function |
| ||
What's the problem? |
| ||
Well, transparency is removed from the textures. |
| ||
I don't think Blitz images support an alpha channel - they rely on black to be the mask colour, so when you copy to an image for rescaling you are losing the alpha channel. I found it much easier to just save copies of the textures scaled to the required sizes in the graphics package rather than try to rescale them all in Blitz, then just get your program to load the right size texture dep. upon the texture quality option the user has set. |
| ||
I wan't several texture quality options, and that would take too much time and disk space, plus I would need to have several models which would load the different texture file. |
| ||
This seems to work:Function ResizeTexture(srctex,scalex#,scaley#,flags) origx=TextureWidth(srctex):origy=TextureHeight(srctex) rgbimg=CreateImage(origx,origy) ;copy RGB CopyRect 0,0,origx,origy,0,0,TextureBuffer(srctex),ImageBuffer(rgbimg) alfimg=CreateImage(origx,origy) ;copy alpha LockBuffer TextureBuffer(srctex):LockBuffer ImageBuffer(alfimg) For x=0 To origx-1 For y=0 To origy-1 WritePixelFast x,y,(ReadPixelFast(x,y,TextureBuffer(srctex)) And $FF000000) Shr 24,ImageBuffer(alfimg) Next Next UnlockBuffer TextureBuffer(srctex):UnlockBuffer ImageBuffer(alfimg) ScaleImage rgbimg,scalex,scaley ScaleImage alfimg,scalex,scaley newx=origx*scalex:newy=origy*scaley newtex=CreateTexture(newx,newy,flags) LockBuffer TextureBuffer(newtex):LockBuffer ImageBuffer(rgbimg):LockBuffer ImageBuffer(alfimg) For x=0 To newx-1 For y=0 To newy-1 WritePixelFast x,y,(ReadPixelFast(x,y,ImageBuffer(alfimg)) Shl 24) Or (ReadPixelFast(x,y,ImageBuffer(rgbimg)) And $00FFFFFF),TextureBuffer(newtex) Next Next UnlockBuffer TextureBuffer(newtex):UnlockBuffer ImageBuffer(rgbimg):UnlockBuffer ImageBuffer(alfimg) FreeTexture srctex ;Or not, as the case may be FreeImage alfimg FreeImage rgbimg Return newtex End Function Images can't store alpha in the alpha channel - so instead you can store it in the blue channel of a second image, scale both, and combine them again. |
| ||
Just Write and Read pixel fast, and copy the alha channel? |
| ||
Thanks, Yasha, that works perfectly! I'll use the function in my game StuntMoto probably. EDIT: By the way, if I get a texture from a entity using: Surface = GetSurface(gmesh,1) SurfaceBrush = GetSurfaceBrush(Surface) SurfaceTexture = GetBrushTexture(SurfaceBrush) Then resize it and apply the texture to the entity, will the original entity texture get deleted from memory or is it a memory leak? |
| ||
Bah, I'm having trouble in applying the resize code to the mesh (it works fine for textures).;Loads a mesh with error handling Function gLoadmesh(gfile$,gparent=0) gmesh = LoadMesh(gfile$,gparent) If Not gmesh Then RuntimeError "Error loading mesh " + gfile$ If Main.Settings\LowQualityTexture > 0 Then Surface = GetSurface(gmesh,1) If Not Surface Then RuntimeError "Surface not found in " + gfile$ SurfaceBrush = GetSurfaceBrush(Surface) ;SurfaceBrush = GetEntityBrush(gmesh) If Not SurfaceBrush Then RuntimeError "Brush not found in " + gfile$ SurfaceTexture = GetBrushTexture(SurfaceBrush) If Not SurfaceTexture Then RuntimeError "Texture not found in " + gfile$ DebugLog TextureName$(SurfaceTexture) DebugLog gfile$ If SurfaceTexture Then For a = 1 To Main.Settings\LowQualityTexture DebugLog "Texture start" SurfaceTexture = ResizeTexture(SurfaceTexture,0.5,0.5) Next EndIf EntityTexture gmesh,SurfaceTexture FreeBrush SurfaceBrush EndIf Return gmesh End Function I get memory access error in the ResizeTexture function at the line "origx=TextureWidth(srctex)", so basically the texture is not found for some reason :o. |
| ||
Wow, that's weird. Are you sure your texture exists, or that the path is correct? Because my test didn't cause that error if the texture existed (but did, when the texture named in the b3d didn't exist). EDIT: The line SurfaceTexture = GetBrushTexture(SurfaceBrush) still apparently returns something even when the texture doesn't exist, so your check won't work. Here's my test - a generic empty project with the two functions in the thread above, gLoadMesh and ResizeTexture. The b3d is Psionic's zombie, which comes free with PaceMaker. The mesh is loaded, positioned, retextured with the new texture - and then the Z-ordering is completely wrecked? WTF? This doesn't happen if you comment out ResizeTexture from gLoadMesh. I have no idea what causes this... perhaps it's a memory leak as the texture is a different size from what the brush expected to free? EDIT 2: Doesn't happen if the resized texture is not an alpha texture. Hum. Not a memory leak then. |
| ||
I believe that when using Alpha, z-ordering is disabled: http://blogs.msdn.com/shawnhar/archive/2009/02/18/depth-sorting-alpha-blended-objects.aspx |
| ||
I wonder how games like Warcraft 3 do it. The lowest you set the "Texture Quality" setting, the more you can see the JPEG compression being applied to the texture. |
| ||
I believe they have all the textures already downscaled on the hard disc. Also, when z-ordering is scaped with alpha, the poly's are sorted by creation. I believe the ones created first, are displayed on top. |
| ||
You can enable z-sorting by using WBuffer true, however, it wouldn't really solve anything. |
| ||
But Ross, isn't there a way to control how much compression will be applied to the JPEG (just like softwares like Photoshop do it, where you can set up how much quality\compression you want)? Perhaps they compress to that much that the user set up, and then load that up in memory the way it is. That way for every texture in the game there is one version with perfect quality, and the lowest you set up the texture quality, the more compression will be applied to the instance of the texture that will be loaded and mapped. It's how I think they do it. |