OpenGL texture tiling does not work properly - opengl

I try to tile texture with size 16x16 inside rectangle 100x100. I set GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T to GL_REPEAT but it gives no effect (see image below). How to tile image properly? Should I use different method for drawing instead of glDrawArrays?
Original texture 16x16
Actual result:
Code:
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, texture.getId());
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);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// GL_REPEAT
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
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);
UPD.
// Texture coordinates
private float[] uv = new float[]{0, 0, 0, 1, 1, 1, 1, 0};
public final FloatBuffer texCoordPointer = BufferUtils.createFloatBuffer(2 * 3 * 2 * 2);
texCoordPointer.clear();
texCoordPointer.put(uv[0]).put(uv[1]);
texCoordPointer.put(uv[2]).put(uv[3]);
texCoordPointer.put(uv[4]).put(uv[5]);
texCoordPointer.put(uv[0]).put(uv[1]);
texCoordPointer.put(uv[4]).put(uv[5]);
texCoordPointer.put(uv[6]).put(uv[7]);
texCoordPointer.flip();

If you want the texture repeated for example 6 times, your texture coordinates should be in the range [0.0, 6.0]

Related

OpenGL Texture moves with camera

I am applying texture to objects and its fine but when I move camera because its 3D scene then texture also moves..
Texture having lines on it is clearly visible moving..
How can I fix the texture (paste) on the objects so that it will not move with me.
Here is the Texture Code.
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //scale linearly when image bigger than texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //scale linearly when image smalled than texture
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0,GL_RGB, GL_UNSIGNED_BYTE, image1->data);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glShadeModel(GL_FLAT);
I am applying it like this on objects (its glutSolidcube)
glPushMatrix();
glColor3f(0.50f, 0.35f, 0.25f);
glTranslated(-8, 2, -8);
glScaled(2.8,5, 4);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_GEN_S); //enable texture coordinate generation
glEnable(GL_TEXTURE_GEN_T);
drawhouse(0.08);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S); //enable texture coordinate generation
glDisable(GL_TEXTURE_GEN_T);
glPopMatrix();

Texture Mapping bug in opengl (with multiple textures)

i'm having trouble in using more then one texture in Opengl. I've written a test program that draws two squares, one bigger then other. When i texturize just one of then, everything works fine, but when i texture both, thats the result:
Thats the code i use to initialize the textures:
unsigned int grass_height, grass_width, wall_height, wall_width;
unsigned char *grass = loadBMP("./minegrama.bmp", &grass_height, &grass_width);
unsigned char *wall = loadBMP("./mineleaves.bmp", &wall_height, &wall_width);
glShadeModel(GL_SMOOTH);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glGenTextures(2, tex);
glBindTexture(GL_TEXTURE_2D, tex[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, grass_width, grass_height, 0, GL_BGR, GL_UNSIGNED_BYTE, grass);
gluBuild2DMipmaps(tex[0], GL_RGB, grass_width, grass_height, GL_RGB, GL_UNSIGNED_BYTE, grass);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, tex[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, wall_width, wall_height, 0, GL_BGR, GL_UNSIGNED_BYTE, wall);
gluBuild2DMipmaps(tex[1], GL_RGB, grass_width, grass_height, GL_RGB, GL_UNSIGNED_BYTE, wall);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Thats the code of the drawing:
//Seta o MatrixMode pra usar texturas
glMatrixMode(GL_TEXTURE);
//INICIO DO CHAO
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex[0]);
//Desenhar o chao;
glColor3f(0, 0.39, 0);
glBegin(GL_QUADS);
glVertex3f(-30, -30, -0.001);
glTexCoord3f(-30, -30, -0.001);
glVertex3f(30, -30, -0.001);
glTexCoord3f(30, -30, -0.001);
glVertex3f(30, 30, -0.001);
glTexCoord3f(30, 30, -0.001);
glVertex3f(-30, 30, -0.001);
glTexCoord3f(-30, 30, -0.001);
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
//FIM DO CHAO
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex[1]);
glTranslatef(0, 0, 10);
glBegin(GL_QUADS);
glVertex3f(-1, -1, 0); glTexCoord3f(-1, -1, 0); //Especifica cada vértice
glVertex3f(1, -1, 0); glTexCoord3f(1, -1, 0);
glVertex3f(1, 1, 0); glTexCoord3f(1, 1, 0);
glVertex3f(-1, 1, 0); glTexCoord3f(-1, 1, 0);
glDisable(GL_TEXTURE_2D);
glEnd();
glPopMatrix();
The first parameter of gluBuild2DMipmaps is wrong. The documentation for the target paramter states:
Specifies the target texture. Must be GLU_TEXTURE_2D.
In addition, your texture coordinates don't look good. With the current values, the texture on the large rectangle will be repeated 60 times. In addition, the z-value of the texture coordinates should be 0, not 0.01. Even better: Use glTexCoord2f for 2-dimensional textures.

I'm rendering to texture,but renderbuffer is black

I'm trying to render to texture.Using opengl-es 2.0.I wanna make Black and white postprocessing.But all I see, is black texture.On scene I have lightsources, and two spheres.But when I'm trying to render my texture that attached to framebuffer, I see black square.
this->frameBuffersCount = 3;
this->frameBuffers = new int[frameBuffersCount];
glGenFramebuffers(frameBuffersCount, (GLuint*)this->frameBuffers);
this->texturesCount = this->frameBuffersCount * 2;
this->bufferTextures = new int[this->texturesCount];
glGenTextures(this->texturesCount, (GLuint*)this->bufferTextures);
for(int i = 0; i < this->texturesCount / 2; ++i)
{
glBindTexture(GL_TEXTURE_2D, this->bufferTextures[2*i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D,0);
glBindTexture(GL_TEXTURE_2D, this->bufferTextures[2*i + 1]);
glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT, screenWidth, screenHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D,0);
}
for(int i = 0; i < this->frameBuffersCount; ++i)
{
glBindFramebuffer(GL_FRAMEBUFFER, this->frameBuffers[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
this->bufferTextures[2*i],
0);
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D,
this->bufferTextures[2*i + 1],
0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
this->ordinaryQuad = new ModelVertex[4];
this->ordinaryQuad[0].UV = Vector2(0.0,0.0);
this->ordinaryQuad[0].position = Vector3(-1, -1, 0.0);
this->ordinaryQuad[1].UV = Vector2(0.0,1.0);
this->ordinaryQuad[1].position = Vector3(-1.0, 1.0, 0.0);
this->ordinaryQuad[2].UV = Vector2(1.0,1.0);
this->ordinaryQuad[2].position = Vector3(1.0, 1.0, 0.0);
this->ordinaryQuad[3].UV = Vector2(1.0,0.0);
this->ordinaryQuad[3].position = Vector3(1.0, -1.0, 0.0);
This is rendering code.
void EffectManager::applyBnW()
{
glBindFramebuffer(GL_FRAMEBUFFER, this->frameBuffers[0]);
auto res = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(res == GL_FRAMEBUFFER_COMPLETE)
{
SceneManager::GetInstance().DrawScene();
glDisable(GL_DEPTH_TEST);
unsigned short indices[6] = {0,2,1,2,0,3};
Shaders shaders;
shaders.Init("../Resources/Shaders/BlackAndWhiteVS.vs", "../Resources/Shaders/BlackAndWhiteFS.fs", 0);
glUseProgram(shaders.program);
unsigned int hVBuff,hInBuff;
glGenBuffers(1, &hVBuff);
glGenBuffers(1, &hInBuff);
glBindBuffer(GL_ARRAY_BUFFER, hVBuff);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(SEngine::ModelVertex), this->ordinaryQuad, GL_STATIC_DRAW);
//glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, hInBuff);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned short), indices, GL_STATIC_DRAW);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this->bufferTextures[0]);
glGenerateMipmap(GL_TEXTURE_2D);
if(shaders.positionAttribute != -1)
{
glEnableVertexAttribArray(shaders.positionAttribute);
glVertexAttribPointer(shaders.positionAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(SEngine::ModelVertex), 0);
}
if(shaders.UVAttribute != -1)
{
glEnableVertexAttribArray(shaders.UVAttribute);
glVertexAttribPointer(shaders.UVAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(SEngine::ModelVertex), (void*)(sizeof(Vector3)));
}
if(shaders.samplerUniform != -1)
{
glUniform1i(shaders.samplerUniform, 0);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)0);
//glDrawArrays(GL_TRIANGLES,0,4);
}
What is wrong?
Not a clear answer can be given since there is not enough information/code provided in your question.
Did you clear the depth buffer ?
When you generated the color in the fragment shader for the rendered objects, did you correctly calculate the White color?
One way I do in these situations to help me debug the issue is to remove potential error areas.
Clear the framebuffer to Red color and Alpha channel = 1.0
Clear depth buffer
Hard code gl_FragColor to vec4(1,1,1,1)
By doing this you can see if the output is all red? Then the issue is with the object rendering, such as transformation, clipping, depth rejection or other reason.
If you can see the objects with White color? Then you know it's the issue with your fragment shader
I would also recommend you to remove the line
glGenerateMipmap(GL_TEXTURE_2D);
As from what I can see in your code, it does not add any extra. If not this is the root-cause to your error.
Generating mipmaps on the texture that still being used and attached to a framebuffer object is not very effecient, especially if the driver internally would have to reallocate the memory for being able to store the new mipmap levels.
Solved.It was problems with index buffer and I forget to disable depth_test.

Is there a way to put in a buffer FBO texture output format GL_ALPHA?

I am using ftgl font library.
ftgl function to create image has this code:
glBindTexture(GL_TEXTURE_2D, textID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, textureHeight,0, GL_ALPHA, GL_UNSIGNED_BYTE, textureMemory);
Format GL_ALPHA.
When I render to FBO images(GL_RGBA) they look ok.
But when I render fonts to fbo texture, there is some problems with colour and alpha.
This image should open in editor that don't touch pixels(browser uses anti-aliasing).
Code:
/// 1 step create FBO
// Create the color buffer
glGenTextures(1, &id_tex);
glBindTexture(GL_TEXTURE_2D, id_tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wid, hei, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // GL_RGBA GL_ALPHA
// Create the frame buffer
glGenFramebuffersEXT(1, &id_buf);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id_buf);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, id_tex, 0);
GLenum err = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
assert(err == GL_FRAMEBUFFER_COMPLETE_EXT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
/// 2 step render to fbo
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id_buf);
glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0,0, 1920 , 1080);
ftgl::render();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDisable(GL_TEXTURE_2D);
glFlush ();
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glViewport (0, 0, 1920, 1080);
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
/// 3 step render texture
glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
glBindTexture(GL_TEXTURE_2D, id_tex);
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex3f(point4.X , point4.Y , point4.Z);
glTexCoord2d(0,1); glVertex3f(point1.X , point1.Y , point1.Z);
glTexCoord2d(1,1); glVertex3f(point2.X , point2.Y , point2.Z);
glTexCoord2d(1,0); glVertex3f(point3.X , point3.Y , point3.Z);
glEnd();
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);

Opengl GL_QUADS produces error 0x506

I have some code in OpenGL to render a YUV image onto an OpenGL viewport. The program works without a problem when running on nvidia cards, but it generates an error when running over the Intel HD 3000, which sadly is the target machine. The point where the error is generated is marked in the code.
The shader programs are
// Vertex Shader
#version 120
void main() {
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
// fragment shader
#version 120
uniform sampler2D texY;
uniform sampler2D texU;
uniform sampler2D texV;
void main() {
vec4 color;
float y = texture2D(texY, gl_TexCoord[0].st).r;
float u = texture2D(texU, gl_TexCoord[0].st).r;
float v = texture2D(texV, gl_TexCoord[0].st).r;
color.r = (1.164 * (y - 0.0625)) + (1.596 * (v - 0.5));
color.g = (1.164 * (y - 0.0625)) - (0.391 * (u - 0.5)) - (0.813 * (v - 0.5));
color.b = (1.164 * (y - 0.0625)) + (2.018 * (u - 0.5));
color.a = 1.0;
gl_FragColor = color;
};
Then I run the program like this:
GLuint textures[3];
glGenTextures(3, textures);
glBindTexture(GL_TEXTURE_2D, textures[YTEX]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, textures[UTEX]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, textures[VTEX]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
GLsizei size = width * height;
GLvoid *y = yuv_buffer;
GLvoid *u = (GLubyte *)y + size;
GLvoid *v = (GLubyte *)u + (size >> 2);
glUseProgram(program_id);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE,
GL_UNSIGNED_BYTE, y);
glUniform1i(glGetUniformLocation(program_id, "texY"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width >> 1, height >> 1, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, u);
glUniform1i(glGetUniformLocation(program_id, "texU"), 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, textures[2]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width >> 1, height >> 1, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, u);
glUniform1i(glGetUniformLocation(program_id, "texV"), 2);
glBegin(GL_QUADS);
glTexCoord2f(texLeft, texTop);
glVertex2i(left, top);
glTexCoord2f(texLeft, texBottom);
glVertex2i(left, bottom);
glTexCoord2f(texRight, texBottom);
glVertex2i(right, bottom);
glTexCoord2f(texRight, texTop);
glVertex2i(right, top);
glEnd();
// glError() returns 0x506 here
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glUseProgram(0);
update since the error happens with frame buffers, I discover they are used like this:
when the program is instantiated, a frame buffer is created like this:
glViewport(0, 0, (GLint)width, (GLint)height);
glGenFramebuffers(1, &fbo_id);
glGenTextures(1, &fbo_texture);
glGenRenderbuffers(1, &rbo_id);
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo_id);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, fbo_texture, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, rbo_id);
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
glPushAttrib(GL_TEXTURE_BIT);
glBindTexture(GL_TEXTURE_2D, m_frameTexture->texture());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glPopAttrib();
The YUV image comes spliced in tiles, which are assembled by rendering in this fbo. Whenever a frame starts, this is performed:
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
glDrawBuffer(GL_BACK);
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (double)width, 0.0, (double)height, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_id);
Then the code above is executed, and after all the tiles had been assembled together
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
glPushAttrib(GL_VIEWPORT_BIT | GL_TEXTURE_BIT | GL_ENABLE_BIT);
glViewport(0, 0, width, height);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, (double)width, 0.0, (double)height, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glBegin(GL_QUADS);
glTexCoord2i(0, 0);
glVertex2f(renderLeft, renderTop);
glTexCoord2i(0, 1);
glVertex2f(renderLeft, renderTop + renderHeight);
glTexCoord2i(1, 1);
glVertex2f(renderLeft + renderWidth, renderTop + renderHeight);
glTexCoord2i(1, 0);
glVertex2f(renderLeft + renderWidth, renderTop);
glEnd();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
What's the value of status after:
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
If the value is anything other than GL_FRAMEBUFFER_COMPLETE, OpenGL will probably choke when it tries to read from the FBO.
The glCheckFramebufferStatus docs describes other (error) values it can return, and what causes them.
Of particular interest might be:
If the currently bound framebuffer is not framebuffer complete, then
it is an error to attempt to use the framebuffer for writing or
reading. This means that rendering commands (glDrawArrays and
glDrawElements) as well as commands that read the framebuffer
(glReadPixels, glCopyTexImage2D, and glCopyTexSubImage2D) will
generate the error GL_INVALID_FRAMEBUFFER_OPERATION if called while
the framebuffer is not framebuffer complete.
(emphasis mine)
edit based on your comments:
To paraphrase the docs wrt GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
Not all framebuffer attachment points are framebuffer attachment complete.
This means that one of the following is happening:
At least one attachment point with a renderbuffer or texture attached has its attached object no longer in existence or has an attached image with a width or height of zero,
The color attachment point has a non-color-renderable image attached. Color-renderable formats include GL_RGBA4, GL_RGB5_A1, and GL_RGB565.
The depth attachment point has a non-depth-renderable image attached. GL_DEPTH_COMPONENT16 is the only depth-renderable format.
The stencil attachment point has a non-stencil-renderable image attached. GL_STENCIL_INDEX8 is the only stencil-renderable format.
We can rule out the last 2 bullets, because it doesn't appear that you're using depth or stencil attachements. That leaves two calls to examine:
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo_texture, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo_id);
From the opengl.org wiki on FBOs:
You get GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT when any of the attachments are 'incomplete'. Criteria for completeness are:
The source object for the image still exists and has the same type it was attached with.
The image has a non-zero width and height.
The layer for 3D or array textures attachments is less than the depth of the texture.
The image's format must match the attachment point's requirements, as defined above. Color-renderable formats for color attachments, etc.
The wiki says of GL_COLOR_ATTACHMENTi​:
These attachment points can only have images bound to them with
color-renderable formats. All compressed image formats are not
color-renderable, and thus cannot be attached to an FBO.
Double check that the fbo_texture and rbo_id are still valid, and that their height/width aren't 0. Finally, it could be fbo_texture's format. You've got it set to GL_RGBA8, but the docs say valid options include GL_RGBA4, GL_RGB5_A1, and GL_RGB565. I'm not sure whether or not that excludes all other formats (like your GL_RGBA8). The wiki seems to suggest that any non-compressed format should work. Try switching it to GL_RGBA4, and see if that works out.
glGetError error codes "stick" and are not automatically cleared. If something at the beginning your program generates OpenGL error AND you check for error code 1000 opengl calls later, error will be still here.
So if you want to understand what's REALLY going on, check for errors after every OpenGL call, or call glGetError in a loop, until all error codes are returned (as OpenGL documentation suggests).
I solved the problem. It was an extensions problem which made the render buffer object disappear. I basically changed this
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo_id);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, fbo_texture, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, rbo_id);
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
for this
glBindRenderbuffer(GL_RENDERBUFFER, rbo_id);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_id);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TURE_2D, fbo_texture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, rbo_id);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
and then it worked. I still wonder exactly what the problem was, but so far I am happy with the result. Special thanks to #luke who's answer helped to locate the exact point of the problem.
Exactly, what command raises error? Try to replace GL_QUADS with GL_TRIANGLE_FAN.