So, I'm struggling with 1D textures. What I'm trying to achieve is passing 3 float values to a fragment shader as a uniform. They represent a light's color, in an attempt to reuse the same shader for n lights, with all their info -color and position- stored in the texture. For now, I'm trying to pass only the color for a single light to test things out. So in the fragment shader I have this:
uniform sampler1D lightColor;
...
vec3 lc = vec3(texelFetch(lightColor, 0, 0)); // all zeroes
vec3 lc = vec3(texture(lightColor, 0, 0)); // same
I've tried to achieve it both with texelFetch and texture calls within the shader (either one or the other), in both cases to no avail. Please note that if I hardcode the value in the shader like this:
vec3 lc = vec3(0.0f, 0.0f, 0.8f);
then I get the expected results (which are non-zero values in lc), so I'm positive that, at least in the shader, the problem may be in either the texelFetch or texture calls.
Back in C++ land, the code (executed once when my lightManager initializes) is as follows:
GLfloat lightValues[] = { 0.8f, 0.8f, 0.8f };
GLuint lightID; // member, not a local variable.
glGenTextures(1, &lightID);
glBindTexture(GL_TEXTURE_1D, lightID);
glActiveTexture(GL_TEXTURE0 + lightID);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexStorage1D(GL_TEXTURE_1D, 1, GL_RGB32F, 1);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 3 * sizeof(GLfloat), GL_RGB, GL_FLOAT, lightValues);
glUniform1i(glGetUniformLocation(shader->program, "light"), lightID);
Nothing extremely fancy going here (although definitely wrong). After going through table 6.2 of the OpenGL doc, for glTexStorage1D I chose 1 for levels (no MipMaps) and GL_RGB32F for internalFormat (since I'm trying to pass 3 floats). width is 1, since there is a single value. That should take care of the allocation.
Now, on to filling the buffers up with glTexSubImage1D, for which I choose level 0 (again, no MipMaps), 0 for xoffset, for width thrice the size of a GLfloat, GL_RGB as the format and GLfloat as the type. Finally, the actual data.
A few things about the c++ code: I correctly set the filters to GL_NEAREST (so that's not to blame) and I would say the uniform location/connection to the sader is correct (via glUniform1i and glGetUniformLocation).
So here come my questions:
lights[n], since n needs to be known at compile time, so textures came naturally to mind as a way to trick this.internalFormat, format and type?lc keeps being populated with zeroes?Thanks!!
EDIT: I do not want to use techniques like multiple passing, or defining a hard limit on the number of lights passed to the shader (making n constant). I read too about some feature in OpenGL 4.2, I believe, which does not interest me either. I'm just trying to learn with the tools at hand (but it's 100% guaranteed in the future I will come back with questions about those topics, once I figure this out (: )
Okay, figured it out together with https://stackoverflow.com/users/1774414/raistmaj
Turns out width is both in glTexStorage and glTexSubImage the number of elements in the array, so 1, regardless of the number of components.
Also, glActiveTexture must be called before glBindTexture (duh!!)
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