Mutipass Shader problem

Hey Guys, I’m attempting to Create a texture, bind it to a location, output a vec3 in the fragment shader to that location, then pass in that texture (which should now have the data) into another shader as a uniform. I am getting a black texture in my second shader, and I am not sure why. I have included a much more thorough explanation of the problem and a tl;dr code section for those of you who are lazy, but I would really really appreciate it if you read the whole post, even though its long, because I provide much more code, and you will have a much better idea of how everything ties together in my program so far.

My texture is created like this:


glGenTextures(1, &tex1);
//glActiveTexture(GL_TEXTURE);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
	GL_LINEAR_MIPMAP_LINEAR);
glBindTexture(GL_TEXTURE_2D, tex1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

I believe this should accurately create a 2D texture. Next, here is my main loop that will initialize the framebuffer object, attach my texture to the framebuffer, and bind that texture to the location(hopefully). This is a different file, so appctx.filename->methodOrVariable is how I access things from each respective file. That should be working file. Pardon the spacing on this one. It all lines up properly in the actual file, it just copies bad. If anyone really needs me to line it up better to be able to understand it then I will do so, please just let me know.



        if (appctx.input->redraw) {
            // we're handing the redraw now
            appctx.input->redraw = false;

            // clear old screen contents
            glClearColor(.5f, .7f, .9f, 1.f);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			//CREATING AND INITIALIZING FBO-----------------------------------------------------------------------------------------
			unsigned int fbo = appctx.scene->fbo;
			glGenFramebuffers(0, &fbo);
			glBindFramebuffer(GL_FRAMEBUFFER, fbo);

			//appctx.terrain->resetShaders();

			//ATTACHING TEXTURES TO FBO---------------------------------------------------------------------------------------------
			glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, appctx.terrain->tex1, 0);
			/*glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, appctx.terrain->tex2, 0);
			glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, appctx.terrain->tex3, 0);*/

			GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0, /*GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2*/ };
			glDrawBuffers(1, DrawBuffers);

			//Check to make sure its Error-Free
			GLenum e = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
			if (e != GL_FRAMEBUFFER_COMPLETE){
				printf("There is a problem with the FBO
");
			}
			//----------------------------------------------------------------------------------------------------------------------
			

            // draw something
            appctx.scene->update();
            appctx.terrain->draw();
            appctx.lightmarker->draw();

			
			/*glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
			glReadBuffer(GL_COLOR_ATTACHMENT0);

			glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
			GLenum attachments[1] = { GL_COLOR_ATTACHMENT0 };
			glDrawBuffers(1, attachments);
			glBlitFramebuffer(0, 0, 1024, 1024, 0, 0, 512, 512, GL_COLOR_BUFFER_BIT, GL_LINEAR);*/
				
			//SWITCHING FRAMEBUFFERS------------------------------------------------------------------------------------------------
			glBindFramebuffer(GL_FRAMEBUFFER, 0);

			//Making sure its error free
			e = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
			if (e != GL_FRAMEBUFFER_COMPLETE){
				printf("There is a problem with the FBO
");
			}

			appctx.terrain->changeShaders();
			appctx.scene->update();
			appctx.terrain->draw();
			appctx.lightmarker->draw();
			//-----------------------------------------------------------------------------------------------------------------------
            // show what we drew
            glfwSwapBuffers(win);
        }


the changeShaders and resetShaders methods switch the shaders to the ones appropriate for the pass, and call sets them up with the correct information. Inside the updateShaders method for the shaders used in the second pass, I’m using this line of code to try and send my texture in as a uniform:


glUniform1i(glGetUniformLocation(shaderID, "Normal"), 3);

The number 3 is used because in the draw function(I’m using the same draw function for both passes) my textures are activated like this:


    for(int i=0; i<NUM_TEXTURES; ++i) {
		//printf("%d 
", i);
        glActiveTexture(GL_TEXTURE0 + i);
        glBindTexture(GL_TEXTURE_2D, textureIDs[i]);
    }
	glActiveTexture(GL_TEXTURE3);
	glBindTexture(GL_TEXTURE_2D, tex1);

The textures activated in the for loop already have data in them, and are sent into the first pass as uniforms. They are not used in the second pass. In the first pass math is done on them to get the final output color that I want. Below is my code for the first pass shader.


// fragment shader for simple terrain application
#version 400 core

//glUniform1i setting uniform variable 1 integer call with v and texID
//glGetUniformLocation(shaderID, uniform name)

uniform sampler2D colorTexture;
uniform sampler2D normalTexture;
uniform sampler2D glossTexture;
//uniform sampler2D pass1NormalTexture;
//uniform sampler2D pass1DiffuseTexture;
//uniform sampler2D pass1SpecularTexture;

// input from vertex shader
in vec3 position, light;
in vec3 tangent, bitangent, normal;
in vec2 texcoord;

// output to frame buffer
//out vec4 fragColor;
layout(location = 0) out vec3 colors;


void main() {
    // surface normal
    vec3 nmap = texture(normalTexture, texcoord).xyz * 2 - 1;
    nmap.xy *= 2;               // steeper bumps
    vec3 N = normalize(nmap.x * normalize(tangent) +
                       nmap.y * normalize(bitangent) + 
                       nmap.z * normalize(normal));

    // light vectors
    vec3 L = normalize(light - position); // light direction
    vec3 V = normalize(/*eye at 0,0,0*/ - position);
    vec3 H = normalize(V + L);
    float N_L = max(0., dot(N,L)), N_H = max(0., dot(N,H));
    
    // diffuse
    vec3 color = texture(colorTexture, texcoord).rgb;

    // specular: normalized Blinn-Phong with Kelemen/Szirmay Kalos shadow/mask
    float gloss = pow(8192, texture(glossTexture, texcoord).x);
    float spec = (gloss+2) * pow(N_H, gloss) / (1 + max(0.,dot(V,L)));
    float fresnel = 0.04 + 0.96 * pow(1 - dot(V,H), 5);


    // final color
    color = mix(color, vec3(spec), fresnel);
    vec3 fragColor = color*N_L;
	//normals = fragColor;
	colors.x = fragColor.x;
	colors.y = fragColor.y;
	colors.z = fragColor.z;
}


For the second shader I am using taking the input in as a sampler2D name “Normal”, and I’m simply outputting the final color. However all I get is black texture, and I am not sure what is wrong here. I don’t really know for sure how to get from rendering to a location to having that data in my texture. Right now I am unsure if the problem is that I am not properly rendering to my texture, so the texture remains empty, or if the problem is that I am not activating my texture properly, so my data is either not being added to my texture or it is being overwritten. It could also be that I am not passing it to the second shader correctly, and that the data is in my texture. If you need any more information from me, I will be checking this thread regularly, and I will be perfectly willing to explain everything/anything you need to help me with this problem. Below I have included a tl;dr code section. Is this code adding the output vector from the fragment shader to appctx.terrain->tex1, which is my texture, or is it not? If not, what else do I need to do to properly have the data from the output vector in the fragment shader stored in my texture. If I can have that much, I’ll be confident that I can proceed.


glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, appctx.terrain->tex1, 0);
			
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0, /*GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2*/ };
glDrawBuffers(1, DrawBuffers);