glGetTextureHandleARB subsequent GL_TEXTURE_2D_MULTISAMPLE Error - opengl

I want to use bindless textures and multisampling. But Strange stuff happens.
My Texture that is supposed to be bindless:
glBindTexture(GL_TEXTURE_2D, texResolve);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
GLuint64 texResolveHandle = glGetTextureHandleARB(texResolve);
GL_CHECK_ERROR("after glGetTextureHandleARB");
//glMakeTextureHandleResidentARB(texResolveHandle);
//glMakeTextureHandleNonResidentARB(texResolveHandle);
GL_CHECK_ERROR("after glMakeTextureHandleResidentARB");
//All good so far!
Now I cerate my multisample Texture and things are getting strange:
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texMSAA);
GL_CHECK_ERROR("after glTexImage2DMultisample 1"); //still ok
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
GL_CHECK_ERROR("after glTexImage2DMultisample 2"); //ERROR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GL_CHECK_ERROR("after glTexImage2DMultisample 3"); //ERROR
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, width, height, false);
GL_CHECK_ERROR("after glTexImage2DMultisample texMSAA"); //Again OK ????
So, my question: What is happening?
Best Regards

Since you bind the texture the GL_TEXTURE_2D_MULTISAMPLE binding point, you also have to use this binding point in the glTexParameteri calls.
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_WRAP_T, GL_REPEAT);
GL_CHECK_ERROR("after glTexImage2DMultisample 2");
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GL_CHECK_ERROR("after glTexImage2DMultisample 3");
Note, that binding points in OpenGL are "by type", so one can bind, e.g., a GL_TEXTURE_2D and a GL_TEXTURE_3D to the same active texture unit at the same time.

Related

How to properly use glTexImage2D to render an object each frame?

This is the code for a ground object that gets rendered every frame in a game I'm making with c++ and openGl.
Ground::Ground() {
this->loadedObject = loadObject("ground.obj");
this->vertices = getVerticesFromLoadedObject(this->loadedObject);
this->textureCoords = getTextureCoordsFromLoadedObject(this->loadedObject);
this->textureData = loadTexture("ground.jpg");
glGenTextures(1, &this->textureId);
glBindTexture(GL_TEXTURE_2D, this->textureId);
}
void Ground::draw() {
glEnable(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, this->textureData.width, this->textureData.height, 0, GL_RGB, GL_UNSIGNED_BYTE, this->textureData.data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY_EXT);
tinyobj::shape_t shape = this->loadedObject.shape;
unsigned int vertexCount = shape.mesh.num_face_vertices.size() * 3;
glTexCoordPointer(2, GL_FLOAT, 0, this->textureCoords);
glVertexPointer(3, GL_FLOAT, 0, this->vertices);
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY_EXT);
glDisable(GL_TEXTURE_2D);
}
Even though this works, calling glTexImage2D every frame causes a memory leak, but I can't get the texture to show otherwise, I tried doing the call in Ground's constructor but it doesn't load the image at all. How do I load the image just once to avoid the memory leak?
Update: with glTexImage2D in the constructor
Ground::Ground() {
this->loadedObject = loadObject("ground.obj");
this->vertices = getVerticesFromLoadedObject(this->loadedObject);
this->textureCoords = getTextureCoordsFromLoadedObject(this->loadedObject);
this->textureData = loadTexture("ground.jpg");
glGenTextures(1, &this->textureId);
glBindTexture(GL_TEXTURE_2D, this->textureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, this->textureData.width, this->textureData.height, 0, GL_RGB, GL_UNSIGNED_BYTE, this->textureData.data);
}
void Ground::draw() {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, this->textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY_EXT);
tinyobj::shape_t shape = this->loadedObject.shape;
unsigned int vertexCount = shape.mesh.num_face_vertices.size() * 3;
glTexCoordPointer(2, GL_FLOAT, 0, this->textureCoords);
glVertexPointer(3, GL_FLOAT, 0, this->vertices);
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY_EXT);
glDisable(GL_TEXTURE_2D);
}

Why is glCheckFramebufferStatus always 36054 for GL_DEPTH_COMPONENT on OpenGL ES 3.1+?

I render the color (GL_COLOR_ATTACHMENT0) and depth (GL_DEPTH_ATTACHMENT) of my scene into a FBO, which works fine on PC with OpenGL 4+.
But on my Smartphone with OpenGL ES 3.1+ I always get for the depth via glCheckFramebufferStatus(GL_FRAMEBUFFER) the status = 36054.
glGenTextures(1, &m_textCol);
glBindTexture(GL_TEXTURE_2D, m_textCol);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wth, hgt, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &m_textDepth);
glBindTexture(GL_TEXTURE_2D, m_textDepth);
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_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, wth, hgt, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textCol, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); always 36053 -> ok
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textDepth, 0);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER); // always 36054 -> not ok
I tried it also with
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, wth, hgt, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
but no change.
Has maybe someone an idea what I'm doing wrong? Thanks.
Status 36054 is GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT.
If we look at Section 9.4 of the OpenGL ES3.1 specification, it lists the following valid internalFormat values for depth attachments:
DEPTH_COMPONENT16
DEPTH_COMPONENT24
DEPTH_COMPONENT32F
DEPTH24_STENCIL8
DEPTH32F_STENCIL8
Note that the last two also contain a stencil part. You can use these for the depth component and ignore the stencil attachment if you do not need it. Especially DEPTH24_STENCIL8 has a good chance of being widely supported.

How to fix OpenGL artefacts (small lines over the each rendering texture)?

I use OpenGL in my project that is basically clone of Mario game. There are how artefacts looks like: small lines over the each rendering texture.
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glVertexPointer(VERTEX_POINTER_COUNT, GL_FLOAT, 0, vertexPointer);
glColorPointer(COLOR_POINTER_COUNT, GL_FLOAT, 0, colorPointer);
glTexCoordPointer(TEXTURE_COORD_POINTER_COUNT, GL_FLOAT, 0, texCoordPointer);
glDrawArrays(GL_TRIANGLES, 0, 6);
glPopMatrix();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, NULL_ID);
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_BLEND);
How can I fix this?
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
These two lines tell OpenGL that those textures should wrap around when accessing values outside of the texture bounds, which the linear filtering does.
Change it to clamp instead.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glFrameBuffer2D blending doesn't work

I'm having trouble with rendering to texture output from this opengl example: http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Text_Rendering_01
My framebuffer is setup as follows:
glGenTextures(1, &back_text);
glBindTexture(GL_TEXTURE_2D, back_text);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, WINDOW_WIDTH, WINDOW_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glGenFramebuffersEXT(1, &font_buffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, font_buffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, back_text, 0);
In best case I can get filled rectangle with color where letter should appear (it appears like alpha is always 1.0).
I've tried original example and it works correctly.
My question is: do I need to enable something to make this work or do I need to take different approach?
Edit:
It turns out that I need to use
glutInitContextVersion(2,0); instead of
glutInitContextVersion(3,2); and world is happy place!! :)

Awesomium with OpenGL Texture Shift

I'm trying to use awesomium with opengl (glut and cpp) and I'm having trouble rendering the webpages to textures. The textures are randomly (different every time I run the program) shifted in the x and y axis. Picture:
I thought GL_CLAMP_TO_EDGE would take care of that problem but it did not. What am I doing wrong?
The Awesomiumpart:
web_core = WebCore::Initialize(WebConfig());
view = web_core->CreateWebView(WIDTH, HEIGHT);
WebURL url(WSLit(URL));
view->LoadURL(url);
BindMethods(view);
while (view->IsLoading())
web_core->Update();
Sleep(300);
web_core->Update();
surface = (BitmapSurface*)view->surface();
The part loading the texture:
glBindTexture(GL_TEXTURE_2D, 13);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0,
GL_BGRA_EXT, GL_UNSIGNED_BYTE, surface);
This is what I did. I know you solved the problem, but it might help someone in the future.
int w = surface->width();
int h = surface->height();
unsigned char *buffer = new unsigned char[w * h * 4];
surface->CopyTo(buffer, w * 4, 4, false, false);
glBindTexture(GL_TEXTURE_2D, texture);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, buffer);
delete[] buffer;