0
votes

I'm currently trying to convert my legacy OpenGL code to modern OpenGL and I just can't get it to do what I want.

The code I'm using is very basic. It renders a video frame to an FBO quad (preserving the aspect ratio).

Here's my GL code:

glBindFramebuffer(GL_FRAMEBUFFER, device.drawingFramebufferID);

glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, deviceSize.width, deviceSize.height);

static const GLfloat squareVertices[] =
{
    (GLfloat)scaledFrameRect.origin.x,
    (GLfloat)scaledFrameRect.origin.y,
    (GLfloat)(scaledFrameRect.origin.x + scaledFrameRect.size.width),
    (GLfloat)scaledFrameRect.origin.y,
    (GLfloat)(scaledFrameRect.origin.x + scaledFrameRect.size.width),
    (GLfloat)(scaledFrameRect.origin.y + scaledFrameRect.size.height),
    (GLfloat)scaledFrameRect.origin.x,
    (GLfloat)(scaledFrameRect.origin.y + scaledFrameRect.size.height)
};

static const GLfloat textureVertices[] = {
    0.0f, 0.0f,
    (GLfloat)frame.width, 0.0f,
    (GLfloat)frame.width,  (GLfloat)frame.height,
    0.0f, (GLfloat)frame.height
};

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);

mtxLoadIdentity(projection);
mtxLoadIdentity(modelView);
mtxLoadIdentity(mvp);

mtxLoadOrthographic(projection, 0.0, deviceSize.width, 0.0f,deviceSize.height, 5.0, 10000);
mtxMultiply(mvp, projection, modelView);

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, frame.texID);
glActiveTexture(GL_TEXTURE0);

// Use shader program.
glUseProgram(self.textureRenderShader);

glUniform1i(uniforms[UNIFORM_VIDEOFRAME], /*GL_TEXTURE*/0);
glUniformMatrix4fv(uniforms[UNIFORM_MVP], 1, GL_FALSE, mvp);

// Update attribute values.
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

CGLFlushDrawable(device.renderingContext);

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

Here is the fragment shader:

#version 150
in vec2 textureCoordinate;
out vec4 fragColor;

uniform sampler2D videoFrame;

void main()
{  
    fragColor = texture(videoFrame, textureCoordinate.st, 0.0);
}

and the vertex shader:

uniform mat4 modelViewProjectionMatrix;

#version 150
in vec4  position;
in vec2  inputTextureCoordinate;
out vec2 textureCoordinate;

void main()
{
    gl_Position = position * modelViewProjectionMatrix;
    textureCoordinate = inputTextureCoordinate;
}

After drawing the texture to the frame buffer and downloading the frame buffer's content with glReadPixels, I'm only getting a green buffer.

The functions starting with 'mtx' are from an Apple sample code project so I'm assuming they are correct.

I don't have any clue what's going wrong and what could possibly cause this weird output. I hope anyone can tell what I'm doing wrong. Thanks!

Edit:

I tried to download the texture which worked flawlessly before using the core profile. Now the downloaded texture is only green (background color). So maybe the drawing code isn't all wrong but the texture upload code is (this was not modified as I thought it wouldn't need to but maybe that's wrong):

glEnable(GL_TEXTURE_RECTANGLE_ARB);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, frame.texID);

glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
             frame.width, frame.height, 0,
             GL_YCBCR_422_APPLE,
             GL_UNSIGNED_SHORT_8_8_REV_APPLE,
             frame.frameData);

unsigned char* buffer = (unsigned char*) malloc(frame.width*frame.height*3);
glGetTexImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);

The downloaded buffer contains only the background color even though I'm uploading video frames.

1
Could you replace this line: "glUniformMatrix4fv(uniforms[UNIFORM_MVP], 1, GL_FALSE, mvp);" after this line "glUseProgram(self.textureRenderShader);" Please someone correct me If I'm wrong. As I remember, you need to put uniform variables after binding shader.Berke Cagkan Toptas
I updated the code but it didn't help. Result is the same as before.guitarflow
If it still doesn't work, first thing you can do is to check if your shader is compiled without a problem. For this purpose you can use glGetShaderInfoLog() and glGetProgramInfoLog() functions.Berke Cagkan Toptas
No errors compiling the shader. One info that might help: I just tried having the shader return a solid color and this causes that currently black spike to be the solid color I returned. Still, no chance of filling the whole area. I'm pretty sure the main issue is the projection/model view matrix.guitarflow
I think it has something to do with vector/matrix multiplication being non-commutative. Make sure that you multiply your modelView and projection matrices in the right order here: mtxMultiply(mvp, projection, modelView). And this: gl_Position = position * modelViewProjectionMatrix should be most likely written as gl_Position =modelViewProjectionMatrix * position.Pavel Beliy

1 Answers

0
votes

After hours of trial and error, I found out that the pixel format GL_YCBCR_422_APPLE seems to be unavailable in Core Profile.

Interestingly, texture upload works if the shader compilation fails. If the shaders compile and no the version is < 140, texture upload works.