How to use textures in opengl? (invalid operation error: 1282) - c++

I am new to opengl and I am currently trying to tackle textures. I keep getting error 1282 (invalid operation) whenever I call glTextureParameteri(). As far as I can tell, every resource has written this the same way. This is the code snippet that is giving me trouble.
ImageLoader image("res/Textures/test.bmp");
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixels());
glBindTexture(GL_TEXTURE_2D, 0);
The error code appears on the lines with glTextureParameteri(). What is invalid/ wrong with the way I have done this?

The glTextureParameter functions take as first argument a texture handle, not a texture target. The parameters you use seem to be for the glTexParameter function. These two are not the same, so you can either use the other function or change the parameter.

Related

Setting up GL_TEXTURE_2D_ARRAY, framebuffer incomplete

For cascaded shadow mapping I'm trying to use a GL_TEXTURE_2D_ARRAY for the individual shadow maps. However following tutorials found online and even looking up things in a textbook I can't seem to create a working framebuffer, as it always errors with GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT.
The code:
glGenFramebuffers(1, &m_DepthMap.m_FrameBuffer);
glGenTextures(1, &m_DepthMap.m_DepthTexture);
glBindTexture(GL_TEXTURE_2D_ARRAY, m_DepthMap.m_DepthTexture);
glTexImage3D(
GL_TEXTURE_2D_ARRAY,
0,
GL_DEPTH_COMPONENT32F,
Renderer::m_ShadowMapResolution,
Renderer::m_ShadowMapResolution,
3,
0,
GL_DEPTH_COMPONENT,
GL_FLOAT,
nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glBindFramebuffer(GL_FRAMEBUFFER, m_DepthMap.m_FrameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_DepthMap.m_DepthTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
const int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!";
throw 0;
}
Sources that tell me that this should be correct:
https://people.inf.elte.hu/plisaai/pdf/OpenGL%20Insights.pdf , page 264
https://johanmedestrom.wordpress.com/2016/03/18/opengl-cascaded-shadow-maps/
What am I doing wrong here? Why is the framebuffer incomplete?
The tutorial you cited has led you astray.
A 2D texture is not the same thing as a 2D array texture. You can either attach a specific array layer (of a specific mipmap level) to a framebuffer, or attach all of the array images in a mipmap. In neither of these cases can you call glFramebufferTexture2D to do this for an array texture (which is why you should be checking for OpenGL errors in one way or another, as this function should have errored out).
In any case, if you want to attach a specific array layer to the framebuffer, then you want to use glFramebufferTextureLayer. If you want to attach it as a layered attachment (because you're doing layered rendering), then you'd use glFramebufferTexture.

Opengl texture initialization process

I have a simple openGL question, currently I'm trying to learn texturing and here is the part I`m confused about it :
void initTextures()
{
GLuint gTextureSphere;
int width, height, channels = 1;
unsigned char* textureMapData = SOIL_load_image("res/texturemap.jpg", &width, &height, 0, SOIL_LOAD_RGB);
//texture map
glGenTextures(1,&gTextureSphere);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,gTextureSphere);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureMapData);
SOIL_free_image_data(textureMapData);
glUniform1i(glGetUniformLocation(gProgramSphere, "normalTexture"), 0);
////////////////////////
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
I think the code above reads my image "texturemap.jpg" by SOIL_load_image function and store it at textureMapData variable. Now, I want to know that, what is the purpose of following 4 lines. I mean, I have already read the data. Am I putting this data into gTextureSphere variable with these following 4 lines ? I guess it is not possible since gTextureSphere is a GLuint type variable. Could anyone explain me ?
Now, I want to know that, what is the purpose of following 4 lines.
So far the texture data has only been loaded into the address space of the program. But OpenGL, the renderer API does not "magically" learn about the availability of that data. Let's break it down:
First generate a OpenGL handle we talk to with OpenGL so that it knows what texture object we're talking to it about. The generated handle will be stored in the variable gTextureSphere.
glGenTextures(1,&gTextureSphere);
OpenGL has several "plugs", called texture units into which texture objects can be "connected to". This tells OpenGL, that the following operations should happen on texture unit 0 (GL_TEXTURE0):
glActiveTexture(GL_TEXTURE0);
Next make a connection between the just selected texture unit and the texture object we, and OpenGL came into an agreement to call by the value contained in the variable gTextureSphere.
glBindTexture(GL_TEXTURE_2D,gTextureSphere);
Now that OpenGL knows, that we're talking about texture unit 0 and a certain texture to be plugged into it, we can tell it to do certain things with the texture object. For example copy the image data, read from a file and decoded into some buffer.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, textureMapData);
At this point OpenGL has a texture object with a working copy of the image data; we can now safely free the buffer we used to decode the image file into, since OpenGL has its own copy now.

Does glGenTextures and glBindTexture needs to be called before doing glTexImage2D and glTexSubImage2D

Hi I have 35 images to draw in a display. I am drawing it in 7X5 grid. The images are downloaded from internet. Each time an image is downloaded I try to draw the whole 35 images. But some of them are not downloaded yet. So I draw some default tile for them instead. The problem is every time an image is downloaded I am drawing the previously drawn images again too. I want to reduce it. So I was thinking about doing something like Texture Atlas. I am trying to do it manually. I am doing it by making a big image with glTexImage2D and adding subimages to it with glTexSubImage2D.
glGenTextures(1, tex);
glBindTexture(GL_TEXTURE_2D, (*tex));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, textureImageInfo->format, textureImageInfo->texWidth, textureImageInfo->texHeight, 0, textureImageInfo->format, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureImageInfo->imageWidth, textureImageInfo->imageHeight, textureImageInfo->format, GL_UNSIGNED_BYTE, textureImageInfo->image);
I call 35 glTexSubImage2D to add all 35 images to a big glTexImage2D. Here I wrote only one for easier explanation. Then finally I do
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, this->tileCoordList);
glTexCoordPointer(3, GL_FLOAT, 0, this->tileTextureCoordList);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
Now what I am confused with is do I need to generate and bind textures 35 times too for 35 call of glTexSubImage2D ?? Or just doing once is enough. The actual problem I don't understand whats binding the texture has got to do anything with it. Thanks.
There is no such thing as a "subimage" in a texture. There are only images in a texture. glTexImage2D allocates storage for a particular image in the texture, and optionally uploads data to that image. glTexSubImage2D only uploads data to an image. The "sub" means that you can update part of the image, not necessarily all of it.
glTexImage2D is like malloc followed by memcpy. glTexSubImage2D is just a memcpy. That's why you have to call glTexImage2D first.

Bind new texture to existing FBO

I am looking to bind a new texture to an existing FBO. But at the moment it decreases my speed significantly.
int holdTextureId = glGenTextures();
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, panoramaModelsFboId);
glBindTexture(GL_TEXTURE_2D, holdTextureId);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, SAVE_WIDTH, SAVE_HEIGHT, 0,GL_RGBA, GL_INT, (java.nio.ByteBuffer) null);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, holdTextureId, 0);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, panoramaModelsDepthRenderBufferId);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, SAVE_WIDTH, SAVE_HEIGHT);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, panoramaModelsDepthRenderBufferId);
//Rendering starts here..
// After which I unbind the FBO and use the texture
I have a feeling glTexImage2D is the perpetrator, so perhaps creating the textures before this process starts is an idea?
Also, I probably don't need to create the renderbuffer each time, but you can save me some time and tell me if it is needed :)
The performance hit lies in the call glTexImage2D which is a very expensive call. If you just want to bind a already existing texture, you don't have to create a new texture object, and also don't need to re-initialize it.
Just calling glFramebufferTexture2D is enough. No need to bind the texture in advance; in fact the texture must not be bound to be used as a framebuffer target.

OpenGL texture randomly not shown

I have got a very, very strange problem in my C++ OpenGL application.
I simply load a texture and apply it to a quadric:
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Then
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
gluQuadricDrawStyle(quad,GLU_FILL);
gluQuadricTexture(quad,GL_TRUE);
gluCylinder(quad,1,0,2,20,1);
glDisable(GL_TEXTURE_2D);
Now: it works perfectly 9 times out of ten, but sometimes the texture isn't shown (the quadric stays white).
The image is correctly loaded, so the problem should be with OpenGL. I have tried with several different images too. Always GL_NO_ERROR.
Any idea ? It is driving me crazy...
Found :) It was the GLint texture member that wasn't correctly reallocated in the copy constructor.
However, i still don't understand why it worked sometimes...
The code you are using seems valid. Have you ...
tried to use a simple quad instead of the quadric
assured that image is filled correctly
verified that tex is not altered somewhere else
assured that no other programs are using opengl at the same time
restarted your computer ;)