tex_ID = SOIL_load_OGL_texture("test.jpg", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_COMPRESS_TO_DXT);
GLuintfor texture objects so it can be easily embedded into your existing wrapper for Texture objects. It is multiplatform as well so it aligns well with freeGLUT for instance.
What was wrong?
The FirstLet's go to the mentioned memory access violation errors. It occurred when I tried to load RGB image of size
725x544. The problem was very simple to fix, but I took me some time to solve.
- To be able to go inside
SOIL_load_OGL_textureit had to be recompiled with DEBUG flag. SOIL comes with the source code by default so I quickly setup solution under VS 2012 and press recompile.
- Soil.c is the main file for the library. It is quite large - around 2000 lines - and it is written in C style. Unfortunately the C style means, in this case, large functions (for instance 400 lines in once example!) and usually no or "little" SRP. Fortunately after a while the code seems to be readable.
SOIL_load_OGL_textureis a simple function that loads data from a file and then redirects all the work to
SOIL_internal_create_OGL_texture. Alternatively for DDS files
SOIL_direct_load_DDSis used. When loading the data Soil can force additional channels (from RGB to RGBA for instance)
SOIL_internal_create_OGL_textureis this long 400-line function. It does almost everything :). Its main purpose is to create OpenGL texture object and push the previously loaded data into OpenGL. To do that it needs to support various SOIL flags like INVERT_Y, NTSC_SAFE_RGB, MULTIPLY_ALPHA...
- For some flags GL extension are loaded - like for NPOT textures or texture rectangles. The work is done by
query_**_capability()functions. Basically GL extensions are loaded "manually", no separate library is used for that.
- After the pixel transformations are done GL texture object is created.
- Then data is uploaded to OpenGL. In most cases
- When compression is selected then SOIL can compress loaded pixel using DXT1 or DXT5 custom implementations and then use
glCompressedTexImageto push the data.
- Another step is to create mipmaps. This step is done using custom "rescaling" algorithms and mipmaps are generated for POT textures only.
- The last step involves setting proper texture parameters and a memory cleanup.
- If everything goes as expected then the function returns valid ID (
GLuint) to OpenGL Texture Object.
glPixelStoreproperly because data from my image was not aligned to 4 bytes. I wrongly assumed that SOIL can deduce the alignment. Silly thing, but it motivated me to debug the code and learn library internals.
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y. When, for instance, I removed mipmap generation it worked faster! My images was not that big: around
540x700, so I thought they should be read quickly.
- When MIPMAP flag is passed SOIL does not only create mipmaps but before that rescales the texture to be POT. Simply: it cannot make mipmaps out of NPOT texture directly. In my case for an image
540x700it was upscaled to
1024x1024! This could take some time!
- Algorithms for scaling, mipmapping, etc are all in software, no hardware acceleration is used.
- Add ability to use
glGenerateMipmap. This requires only single line in code to call, works for NPOT textures and should be hardware accelerated. Moreover nowadays it should be supported almost everywhere. Basically
GL_EXT_framebuffer_objectis only needed.
Use modern style of loading extensions. Use
glGetStringi. This should make SOIL to work in Core GL profile. Additionally GL_CLAMP needs to be changed into GL_CLAMP_TO_BORDER.
- Add ability to use immutable texture storage.
- Add some more examples and tests.