I have an OpenGL (4.1) application I build in Xcode that ran fine before the upgrade, but now writes nothing to the OpenGL view. The application builds without errors or warnings, and the GLSL shaders compile and link without error.
I've run a few tests to see if the shaders are basically working:
If the last line of the fragment shader is:
fragColor = vec4(1.0, 0.0, 0.0, 1.0);
The OpenGL window is totally red, as it should be. I think this also confirms that the vertex data is being passed properly. I can animate the view to rotate about any axis, and again I can see that the vertex data (including depths) is being passed properly.
If the last line of the fragment shader is either:
fragColor = vec4(texCoord[0], 0.0, 0.0, 1.0);
or
fragColor = vec4(texCoord[1], 0.0, 0.0, 1.0);
I get a red gradient in either the x or y direction, indicating to me that the texture coordinates are also being passed properly.
So I'm thinking that the texture data itself is not being passed into the sampler for some reason. Here's the relevant code.
The code that creates the texture is:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures( 1, appController->appDelegate->wispTexture);
glBindTexture(GL_TEXTURE_2D, appController->appDelegate->wispTexture[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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)TEXTUREWIDTH, (GLsizei)TEXTUREHEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, appController->appDelegate->wispTexture[0]);
The data source for the glTexImage2D call is null for now because I load it later in the application. The application builds the texture image data, but for now just to test the operation of the shaders I'm loading it to solid white with:
for(int i = 0; i < NUMTEXTUREPOINTS; i++)
{
appController->textureManager->wispBitmapData[i].red = 255;
appController->textureManager->wispBitmapData[i].green = 255;
appController->textureManager->wispBitmapData[i].blue = 255;
appController->textureManager->wispBitmapData[i].alpha = 255;
}
where wispBitmapData is declared as:
AlphaPixelBytes wispBitmapData[NUMTEXTUREPOINTS];
and AlphaPixelBytes is defined as a structure:
typedef struct
{
unsigned char red;
unsigned char green;
unsigned char blue;
unsigned char alpha;
} AlphaPixelBytes;
The code to draw the image is:
glBindTexture(GL_TEXTURE_2D, appDelegate->wispTexture[0]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)TEXTUREWIDTH, (GLsizei)TEXTUREHEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, appController->textureManager->wispBitmapData);
glBindBuffer(GL_ARRAY_BUFFER, appDelegate->wispVertexBuffer[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(wispVertices), wispVertices);
glBindBuffer(GL_ARRAY_BUFFER, appDelegate->wispTexCoordBuffer[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(wispTextureCoordinates), wispTextureCoordinates);
glBindBuffer(GL_ARRAY_BUFFER, appDelegate->wispHitsBuffer[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(wispScreenHits), wispScreenHits);
glBindBuffer(GL_ARRAY_BUFFER, appDelegate->wispNormalBuffer[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(wispNormals), wispNormals);
glUseProgram(appDelegate->wispShaders);
glBindBuffer(GL_ARRAY_BUFFER, appDelegate->wispVertexBuffer[0]);
glVertexAttribPointer(appDelegate->wispPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(appDelegate->wispPositionLoc);
glBindBuffer(GL_ARRAY_BUFFER, appDelegate->wispTexCoordBuffer[0]);
glVertexAttribPointer(appDelegate->wispTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(appDelegate->wispTexCoordLoc);
glBindBuffer(GL_ARRAY_BUFFER, appDelegate->wispHitsBuffer[0]);
glVertexAttribPointer(appDelegate->wispHitsLoc, 1, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(appDelegate->wispHitsLoc);
glBindBuffer(GL_ARRAY_BUFFER, appDelegate->wispNormalBuffer[0]);
glVertexAttribPointer(appDelegate->wispNormalLoc, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(appDelegate->wispNormalLoc);
glUniform1i(appDelegate->wispFilterModeLoc, coloringdata->filteringMode);
glUniform1i(appDelegate->wispMaxHitsLoc, maxScreenHits);
glUniform1i(appDelegate->wispMaxNumSamplesLoc, coloringdata->maxNumSamples);
glUniform1f(appDelegate->wispSampleSizeFactorLoc, coloringdata->sampleSizeFactor);
glUniform1i(appDelegate->wispDisplayModeLoc, coloringdata->displayMode);
glUniform1i(appDelegate->wispLightOnLocation, coloringdata->lightingOn);
glUniformMatrix4fv(appDelegate->wispModelMatrixLocation, 1, GL_FALSE, appDelegate->modelMatrix.m);
glUniformMatrix4fv(appDelegate->wispViewMatrixLocation, 1, GL_FALSE, appDelegate->viewMatrix.m);
glUniformMatrix4fv(appDelegate->wispProjectionMatrixLocation, 1, GL_FALSE, appDelegate->projectionMatrix.m);
glUniformMatrix3fv(appDelegate->wispNormalMatrixLocation, 1, GL_FALSE, appDelegate->normalMatrix.m);
glUniform3fv(appDelegate->wispLightPositionLocation, 1, coloringdata->lightPosition);
glActiveTexture(GL_TEXTURE0);
glUniform1i(appDelegate->wispTextureLoc, 0);
glBindTexture(GL_TEXTURE_2D, appDelegate->wispTexture[0]);
// *********************************** Draw the Image to The Screen
glBindVertexArray(appDelegate->wispVertexArray[0]);
glBindVertexArray(appDelegate->wispTexCoordArray[0]);
glBindVertexArray(appDelegate->wispHitsArray[0]);
glBindVertexArray(appDelegate->wispNormalArray[0]);
glDrawArrays(GL_POINTS, 0, NUMSCREENPOINTS);
glDisableVertexAttribArray(appDelegate->wispPositionLoc);
glDisableVertexAttribArray(appDelegate->wispTexCoordLoc);
glDisableVertexAttribArray(appDelegate->wispHitsLoc);
glDisableVertexAttribArray(appDelegate->wispNormalLoc);
[[appController->wispView openGLContext] flushBuffer];
Can anyone see anything wrong with this code? I've been over it many times, and have checked al the docs I can think of.
In the fragment shader, some of the declarations:
in vec2 texCoord;
uniform sampler2D Texture;
out vec4 fragColor;
But
fragColor = texture(Texture, texCoord);
renders a black screen.
I've kept the code posting about the shaders brief because they're actually quite complicated.
I've now created new test shaders that are quite trivial:
Vertex shader:
#version 410
in vec4 Position;
in vec2 TexCoord;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
out vec2 texCoord;
void main()
{
texCoord = TexCoord;
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * Position;
}
Fragment shader:
#version 410
in vec2 texCoord;
uniform sampler2D Texture;
out vec4 fragColor;
void main()
{
fragColor = texture(Texture, texCoord);
}
I still get the same results with the various tests described above.
I've also traced through the code testing for GL errors at each step, and there are none.
I appreciate the good people who contribute their time and experience to stackoverflow, I'm sure the reputation points offered in the bounty really mean nothing to anyone who can help me straighten this out. Just understand that I know that and appreciate your help.
I'm answering my own question because there were no other responses, and I eventually solved all my problems. I'm just putting some closure on this.
After tracing through the code, it looked to me like the OpenGL code was fine, but there was a problem with timing when some of the calls were being made.
I moved all my application initialization code from:
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
to:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
This solved everything (including a few other nagging problems that I now understand), and the application is running normally again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With