Texture mode not working properly...

BlitzMax Forums/OpenGL Module/Texture mode not working properly...

Ryan Burnside(Posted 2009) [#1]
I need to double the drawing scale of my current project.

I used this command to set up the window:
gluOrtho2D(0.0, 800.0, 600.0, 0.0)

I have the texture smoothing function set to the following

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

I'm scaling by 2.0 and all positions are whole number floats.

The screen is blurring my images when I double scale them. I want them to remain sharp.

I'm drawing 8x8 images and the sprites are getting really fuzzy.


Bremer(Posted 2009) [#2]
One way around it could be to make your images twice as large and not do any scaling in the program. This way your images are as crisp as you want, and you do not have to fuzz with scaling issues.


ImaginaryHuman(Posted 2009) [#3]
Strange, cus if you specify GL_NEAREST you really should not get any filtering at all especially if you're drawing to exact coordinates.

One thing you might want to try is that I read somewhere OpenGL considers the center of a pixel to be the point at which a texel covers it fully, so if you draw a pixel at 0,0 you're actually sort of drawing it from -0.5,-0.5 to 0.5,0,5 ??? If that is the case - and I'm not sure about this but you can experiment, then if you draw your object at a whole integer coordinate plus 0.5,0.5 maybe that will center it over the pixel.

Another issue is that floating point numbers are not accurate representations of decimal numbers and the larger the number gets the less accurate it becomes. You cannot accurately represent all integers using a float, so even if you're saying draw to 100.0,100.0 maybe it will draw to 99.9993,99.9993 or something, which will effectively position your pixel with sub-pixel accuracy, which will kick in an averaging of the affected pixels. You would either solve this by moving to Doubles instead of Floats, or using fixed-point integers. For a regular 2d world where your coordinates are not likely to go above 65536 you can use Shl 16 to turn an integer into a fixed-point number, and Shr 16 to convert fixed point to integer. This will likely be more accurate in many cases than using a float because there are exact equal distances between each `unit` of fixed point value.


Grover(Posted 2009) [#4]
ImaginaryHuman is likely right here. This sounds more like a precision problem than anything. If you were using DirectX.. youd be stuffed, and would have to probably work with writing to the framebuffer pixel by pixel :) However.. OpenGL has a great answer - use double instead of float. OpenGL is effectively a 'experimenters/acedemics' developed graphics API - this means it has many levels of accuracy and consistency. Internally if you are using floats for translates, and rotations you will lose accuracy for every operation you do. At very fine pixel levels this means you lose the ability to accurately write to a specific pixel. Additionally, textures with their mip-mapping and filtering reduce the quality of the texture dependent on various factors. What you can do is regenerate mipmaps to suit gluBuild2DMipmaps() is often used for this or you can turn off mipmapping and filtering and use a 1:1 relationship with the texture pixel (texel) and the visual pixel itself. This is not overly recommended though, since any movement will result in 'aliasing effects'.

So.. an answer is what you might be after I guess :) Turn off mipmap and filtering or make your textures actually bigger rather than scale them. If you scale any texture you will suffer some form of artefacts anyway - either stretching, filtering or blockyness.

Heres some good help on the subject:
http://www.hanecci.com/pukiwiki/index.php?Programming/OpenGL/Texture#oc591fa2