Access violation when calling glTextureParameteri with OpenGL and DevIL
Asked Answered
C

2

5

I'm trying to load an image with DevIL and then create a texture. I have a class named Texture, and I'm doing all this stuff in the constructor. A valid context has been created. I'm getting an access violation on the first call to glTextureParameteri(), so I guess the texture didn't bind correctly. I just see no reason why it would not bind.

Here's the constructor:

Texture::Texture(const std::string& filename){
//DevIL handle for the image
unsigned int ilID;

ilGenImages(1, &ilID);

ilBindImage(ilID);

ilEnable(IL_ORIGIN_SET);
ilOriginFunc(IL_ORIGIN_LOWER_LEFT);

if (!ilLoad(IL_BMP, (ILstring)filename.c_str())){
    DebugUtility::gl_log_err("Failed to load image &s\n", filename.c_str()); //Just function that prints to log file
    return;
}
ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);

glGenTextures(1, &texture);

//"texture" is global GLuint
glBindTexture(GL_TEXTURE_2D, texture);

//LINE BELOW CAUSES ACCESS VIOLATION!
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

glTextureParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTextureParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
    ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT),
    0, GL_RGBA, GL_UNSIGNED_BYTE, ilGetData());

ilDeleteImages(1, &ilID);
//Again, prints to log file
DebugUtility::gl_log("Succefully loaded and created texture %s", filename.c_str());
} 

ilLoad returns true, since the code inside that if-block is not executed. Here is the error (I'm using Visual Studio 2013):

Unhandled exception at 0x74E1CB49 in projectSDL.exe: 0xC0000005: Access violation executing location 0x00000000.

Civic answered 27/10, 2014 at 14:23 Comment(0)
A
7

The function glTextureParameteri() is an extension, try using glTexParameteri() and binding an active texture unit glActiveTexture(GL_TEXTURE0). glTextureParameteri() also expects the texture ID, not the target.

Abreast answered 27/10, 2014 at 14:43 Comment(1)
glTextureParameter() is standard in OpenGL 4.5. I expected people to confuse it with glTexParameter() the first time I saw it. Sometimes you wonder about the API design choices in OpenGL...Monochrome
M
4

glTextureParameter() is a new entry point in OpenGL 4.5. It is part of a family called Direct State Access (often referred to by the acronym DSA). Before being promoted to core functionality in 4.5, it was defined in the EXT_direct_state_access extension.

The idea is that you can modify state of objects without binding them. This can improve efficiency by reducing the number of API calls and driver overhead.

These new entry points take an object name as the first argument, compared to the corresponding older entry points, which take a target as the first argument. In your case, you either have to use the older entry point:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

(note the Tex instead of Texture), or pass the texture name as the first argument, without having to first bind the texture:

glTextureParameteri(texture, GL_TEXTURE_WRAP_S, GL_REPEAT);

[warning, this paragraph is opinion based and potentially controversial] Unfortunately, the entry points were defined in a way that make them easily mixed up with previous entry points. While OpenGL was never designed to be particularly programmer friendly, I predict that many more people will get tripped up by these new entry points, which have very similar names as existing ones, and the same signatures. It looks like a very unfortunate API design to me.

Monochrome answered 27/10, 2014 at 15:52 Comment(2)
So, witch one is better to use? Tex if doing multiple calls and texture if doing only one call?Civic
I would probably stick with glTexParameter(), unless you have a good reason to believe that you need DSA to meet your performance goals. Mainly because the OpenGL 4.5 spec was only release a couple of months ago, so support for it will not be widely available. Greatly restricting what machines can run your code does not seem worth it, unless you critically rely on these very recent features.Monochrome

© 2022 - 2024 — McMap. All rights reserved.