Texture is all black - opengl-es

As far as I can tell, my first attempt to draw a texture on a triangle is being setup correctly, but it shows up as all black.
I am sending the image to OpenGL as such:
GLuint gridTexture;
glGenTextures(1, &gridTexture);
glBindTexture(GL_TEXTURE_2D, gridTexture);
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_RGBA, size.x,
size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
While I'm not sure how to test that "pixels" holds what I'd expect, I do know that the size.x and size.y variables are logging correctly for the PNG I'm using so I assume the pixels is working well also since they are both extracted together in my resource loader
My shaders are simple:
attribute vec4 Position;
attribute vec4 SourceColor;
attribute vec2 TextureCoordinate;
varying vec4 DestinationColor;
varying vec2 TextureCoordOut;
uniform mat4 Projection;
uniform mat4 Modelview;
void main(void)
{
DestinationColor = SourceColor;
gl_Position=Projection*Modelview*Position;
TextureCoordOut = TextureCoordinate;
}
fragment:
varying lowp vec4 DestinationColor;
varying mediump vec2 TextureCoordOut;
uniform sampler2D Sampler;
void main(void)
{
gl_FragColor = texture2D(Sampler, TextureCoordOut) * DestinationColor;
// gl_FragColor = DestinationColor; //this works and I see varied colors fine
}
I send texture coordinates from client memory like this:
glEnableVertexAttribArray(textCoordAttribute));
glVertexAttribPointer(textCoordAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(vec2),&texs[0]);
The triangle and its vertices with texture coordinates are like this; I know the coordinates aren't polished, I just want to see something on the screen:
//omitting structures that I use to hold my vertex data, but you can at least see the vertices and the coordinates I am associating with them. The triangle draws fine, and if I disable the texture2D() function in the frag shader I can see the colors of the vertices so everything appears to be working except the texture itself.
top.Color=vec4(1,0,0,1);
top.Position=vec3(0,300,0);
texs.push_back(vec2(0,1));
right.Color=vec4(0,1,0,1);
right.Position=vec3(300,0,0);
texs.push_back(vec2(1,0));
left.Color=vec4(0,0,1,1);
left.Position=vec3(-300,0,0);
texs.push_back(vec2(0,0));
verts.push_back(top);
verts.push_back(right);
verts.push_back(left);
For good measure I tried binding the texture again with glBindTexture before drawing to make it was "active" but that made no difference.
I think there is probably a very simple step I am not doing somewhere but I can't find it anywhere.

For people suffering from textures showing up black, another reason I found was if you don't set up these simple parameters when creating the texture (before glTexImage2D), the texture shows up black
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_GENERATE_MIPMAP, GL_FALSE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

The issue is resolved by making my texture dimensions a power of 2 in length and width.

you must have a bound data to the texture before setting the filter. You must call glTexImage2D first
GLuint gridTexture;
glGenTextures(1, &gridTexture);
glBindTexture(GL_TEXTURE_2D, gridTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x,
size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

Related

OpenGL ES3 framebuffer draw depth in red scale

So after hard work to make directional light shadow map work finally I can see a shadow map rendered on a quad but it is drawn only with depth GL_DEPTH_COMPONENT16 and type GL_UNSIGNED_SHORT , or GL_DEPTH_COMPONENT32F and type GL_FLOAT but it is in red scale not gray scale
the problem is I used many methods to calculate the depth to draw the shadow but no shadow appears.
glCullFace(GL_FRONT);
glGenFramebuffers(1, &depthMapFBO);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glGenTextures(1, &depthMap);
glBindTexture(GL_TEXTURE_2D, depthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
glDrawBuffers(1, GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glCullFace(GL_BACK);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOGI("framebuffer incomplete");
}
and the fragment is:
uniform mediump sampler2DShadow shadowMap;
......
float bias = 0.005;
float visibility = 1.0;
for (int i=0;i<4;i++){
int index = i;
visibility -= 0.2*(1.0-texture( shadowMap, vec3(FragPosLightSpace.xy + poissonDisk[index]/700.0, (FragPosLightSpace.z-bias)/FragPosLightSpace.w) ));
}
result =light.intensity* (visibility * (diffuse + specular));
...but it is in red scale not gray scale
A texture with an depth component format, such as GL_DEPTH_COMPONENT16 or GL_DEPTH_COMPONENT32F has only 1 color channel, the red color channel.
If you read data from a texture sampler, where a depth component texture is bound to, then the green, blue and alpha channel are set automatically.
The Image Format specification of Khronos group says:
Image formats do not have to store each component. When the shader samples such a texture, it will still resolve to a 4-value RGBA vector. The components not stored by the image format are filled in automatically. Zeros are used if R, G, or B is missing, while a missing Alpha always resolves to 1.Note: Texture swizzling can change what the missing values are.
Because of that, the red color is set, the green and blue color is set to 0 and the alpha channel is 1. The causes the opaque red surface.
If you want to read a grayscale color from a depth component texture, then you have to read the red color channel and you have to apply the red color channel to the green and blue color, too.
You have to adapt the code like this:
float depth = texture( shadowMap, ..... ).r;
vec3 depthGrayscale = vec3( depth );
or this:
vec3 depthGrayscale = texture( shadowMap, ..... ).rrr;

OpenGLES2: How to load and access a big float array

I have a large WxH float array:
float floatArray[W][H];
I want to access it in a fragment shader and I need to load/access it through a texture due to its size:
vec4 v4 = texture2D(tex, v_texCoord);
//Getting v4.x as floatArray[v_texCoord.x * W][v_texCoord.y * H]
I load the texture like this:
int texturenames[1];
glGenTextures(1, texturenames);
glActiveTexture(GL_TEXTURE0 + texturenames[0]);
glBindTexture(GL_TEXTURE_2D, texturenames[0]);
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_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_FLOAT, floatArray);
glUniform1i(glGetUniformLocation(program_, "tex"), texturenames[0]);
I don't get the right values. Note that the third (internalformat) and seventh (format) parameters of glTexImage2D are GL_LUMINANCE.
void glTexImage2D(GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLint border,
GLenum format,
GLenum type,
const GLvoid * data);
How can I load and access a big float array in OpenGLES2?
Short answer - you can't. OpenGL ES 2.0 doesn't support floating point texturing.
Given you only want a single channel perhaps you could encode it in an RGBA unorm texture and recover the value algorithmically in the shader, but it sounds horribly expensive on a mobile GPU.
OpenGL ES 3.0 does support float texturing, so that might provide more luck.

How does sampler2DArrayShadow in glsl works

I am not able understand how to use sampler2DAprrayShadows and how it works. Got some part of it that we need to use depth texture values (GL_DEPTH_COMPONENT) to get the compare result with ref depth.
But then how to use the return float value to get the texel.
Got reference from :
http://www.khronos.org/opengles/sdk/docs/manglsl/xhtml/texture.xml
I have written a small code to test it as below:
My fragment shader as:
in highp vec2 texcoord;
in highp vec4 basecolor;
out highp vec4 myFragColor;
uniform highp sampler2DArrayShadow basetexture;
void main(void)
{
highp vec3 coords = (vec3(texcoord, 0.0) + vec3(1.0, 1.0, 1.0)) / 2.0;
highp float depth = texture(basetexture, vec4(coords.x, coords.y, coords.z, -0.5));
myFragColor = vec4(depth * basecolor);
}
Created 3D texture (texdata), and binding it as :
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT16, TEX_SIZE, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, texdata);
maybe this could help you:
depth cubemap make tutorial
And to be frank, you're supposed to make a frame buffer object which binds a 2D depth texture instead of a Cubemap one. If you want to use sampler: sampler2DArrayShadow, then you just need to overload the glsl function texture, which is texture( Sampler2DArrayShadow gSampler, Vec4 P, [float bias]) .P.z is the number of the 2D tex, and P.w is the reference depth value. The default bias is 0, you can ignore it if don't need one.

Aliassing when flipping a texture in fragment shader

I've created a multi-texture fragment shader in which I want to flip one of the textures but when doing this my texture gets all jaggy. Is there a solution to this problem?
This is my fragment shader code:
void main(void)
{
lowp vec4 camera = texture2D(texture0, destinationTexCoord);
lowp vec4 viewfinder = texture2D(texture1, vec2(destinationTexCoord.x, 1.0 - destinationTexCoord.y));
lowp vec4 result = mix(camera, viewfinder, viewfinder.a);
gl_FragColor = result;
}
Texture filtering I'm using:
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_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);
Some background information: I'm blending these textures in my fragment shader (blending code stripped out) so I'm not looking for a solution where I rotate a second plane and merge them down on the framebuffer. I'm wondering if it is a good idea to flip/rotate around the texture coordinates in my fragment shader.
In the end I'll pass in a uniform saying: rotate or don't, resulting in that one texture getting rotated or not.
Using mediump instead of lowp for destinationTexCoord will improve the sampling rate for
the vec2(destinationTexCoord.x, 1.0 - destinationTexCoord.y) calculation. However, my recommendation is to use two varying vec2s instead of using a dependent texture read. i.e. cameraTexCoord and viewfinderTexCoord. You can avoid a mediump calculation in the fragment shader, and take advantage of the hardware's (hopefully) optimized vert-frag interpolation.
There's really no reason to use lowp for texture coordinates, unless they are dependent, in which case lowp may be better for the fragment shader calculations. Otherwise, lowp has not resulted in any gains, in my experience (I only know PowerVR hardware on iOS though).

Render to texture problem with alpha

When I render to texture, and then draw the same image, it seems to make everything darker. To get this image:
http://img24.imageshack.us/img24/8061/87993367.png
I'm rendering the upper-left square with color (1, 1, 1, .8) to a texture, then rendering that texture, plus the middle square (same color) to another texture, then finally that texture plus the lower-right square (same color) to the screen.
As you can see, each time I render to texture, everything gets a little darker.
My render-to-texture code looks like: (I'm using OpenGL ES on the iPhone)
// gen framebuffer
GLuint framebuffer;
glGenFramebuffersOES(1, &framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
// gen texture
GLuint texture;
glGenTextures(1, &texture);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
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_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
// hook it up
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture, 0);
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES))
return false;
// set up drawing
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glViewport(0, 0, Screen::Width, Screen::Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, Screen::Width, 0, Screen::Height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor4f(1, 1, 1, 1);
// do whatever drawing we'll do here
Draw();
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
Is there anything that I'm doing wrong here? Do you need more code to figure it out? What might be going on here?
I'm only guessing:
Drawing the first texture gives you 204 (0.8 * 255) in the RGB and alpha channels. When you draw for the second time (with GL_BLEND enabled, I presume), you're getting the light gray 204 RGB with 80% alpha which gives you a medium gray.
Solution: use glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) and premultiply your colors.

Resources