Jump to content
  • Advertisement

splush

Member
  • Content Count

    5
  • Joined

  • Last visited

Everything posted by splush

  1. Hi! I've been lurking on gamedev for a while and this is my first actual post. I am looking for some help with implementing deferred rendering.   The thing I am struggling with at the moment is the actual rendering of the geometry to the g-buffer textures. I have read a lot on the subject but I still feel like I'm falling short.   The scene is just a square object rotating with a point light in the back (the light is irrelevant at this point though). The scene is rendering fine with forward rendering.   from Scene.cpp render function: multiplerendertargets->begin(); // Base image texture glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D, texture->textureID()); // Draw the triangles glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, (void*)0); multiplerendertargets->end(); where the begin/end functions do the following: void FrameBufferObjects::begin() { glBindFramebuffer(GL_FRAMEBUFFER, fbo); glPushAttrib(GL_VIEWPORT_BIT); glViewport(0, 0, this->width, this->height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; glDrawBuffers(3, buffers); }; void FrameBufferObjects::end() { glBindFramebuffer(GL_FRAMEBUFFER, 0); glPopAttrib(); }; What I am trying to achieve is to output the three textures to the screen separately, the function for this seems to be in working order when not making any draw calls. However, when I make the draw call above and try to output the textures, all I get is a black screen.   Geometry pass fragment shader: /* Geometry pass fragment shader (first pass) */ #version 400 in VertexData { vec3 position; vec3 normal; vec2 tex_coords; } vertexIn; uniform sampler2D tDiffuse; layout(location = 0) out vec4 diffuseOut; layout(location = 1) out vec4 positionOut; layout(location = 2) out vec4 normalsOut; void main() { diffuseOut = vec4(texture(tDiffuse,vertexIn.tex_coords).rbg, 0); positionOut = vec4(vertexIn.position, 0); normalsOut = vec4(vertexIn.normal, 0); } What the scene looks like with forward rendering:     I feel like I'm missing something elementary but I just have no clue what it is and I'm going a bit blind staring away at the code. I just don't see how it would result in all the textures being completely black?   Any and all help is much appreciated.
  2. Just a final update: I ended up re-doing my gbuffer class from scratch since it was so messy, and it ended up solving the issues I was having. Deferred rendering is now implemented and running smoothly.   Thanks for all the help, it's much appreciated.   For anyone having trouble with deferred rendering I would like to suggest a few guides that I found helpful: http://ogldev.atspace.co.uk/www/tutorial35/tutorial35.html http://gamedevelopment.tutsplus.com/articles/forward-rendering-vs-deferred-rendering--gamedev-12342 (not a guide, more of an overview). http://gamedevs.org/uploads/deferred-shading-tutorial.pdf   Splush
  3. Quick update: I tried changing the output to some arbitrary vec4 from the fragment shader such as (1,1,0,0) and it still displays the same way as before. So the problem is (probably) not in the shaders. I'll do further debugging and make an update in the morning. 
  4. Hi agleed and thank you for posting,   Where I bind the textures to the texture slots? I'm not sure what you mean, so I'll address the both possibilities I can think of: either you're talking about attaching the textures to the color attachments, which is done in the fbo constructor ex. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, diffuseTex, 0); Or you are referring to  glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, multiplerendertargets->getDiffuseTex()); glUniform1i(diffuseID, 0); Which, if my understanding is correct, I don't really have to invoke until I am about to perform the lighting pass (please do correct me if I'm wrong).   As for the uniforms being used in the shader, the only one that is new since the forward rendering is tDiffuse, which is passed with the following code: diffuseID = shaderProgram->uniformLocation("tDiffuse"); //Function origin GLuint ShaderProgram::uniformLocation(const char* name) const { return glGetUniformLocation(shaderProgram, name); } And is called as a uniform sampler2D in the fragment shader (code is in the first post).   The rendering to the color attachments shouldn't require me to bind the textures to texture slots, it should complete with the drawbuffer command if I'm not mistaken.   I hope I answered your question, I'm not certain I did.
  5. Did you actually attach textures to the framebuffer? Where is the code proving it? Why do you call glActiveTexture(GL_TEXTURE0); and glEnable(GL_TEXTURE_2D); inside FrameBufferObjects::begin()? How are you attempting to draw things after the main render? If you are trying to draw each buffer, where is the code for that? Did you apply the correct framebuffer? Did you set the correct draw buffers? Never push/pop attributes (the viewport in this case)—manually set the viewport each time you change it. It is good for performance and for stability (it is the only way to know that your viewport is correct). L. Spiro   Hi Spiro, First of all thank you for your reply, I'll provide some more information, and answer your questions.   "Did you actually attach textures to the framebuffer?" I initialize the fbo and bind the textures in the following function: FrameBufferObjects::FrameBufferObjects(int width, int height) { GLenum state; this->width = width; this->height = height; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glGenRenderbuffers(1, &depthHandle); glBindRenderbuffer(GL_RENDERBUFFER, depthHandle); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, this->width, this->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthHandle); glGenRenderbuffers(1, &diffuseRenderTarget); glBindRenderbuffer(GL_RENDERBUFFER, diffuseRenderTarget); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, this->width, this->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, diffuseRenderTarget); glGenRenderbuffers(1, &positionRenderTarget); glBindRenderbuffer(GL_RENDERBUFFER, positionRenderTarget); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, this->width, this->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, positionRenderTarget); glGenRenderbuffers(1, &normalRenderTarget); glBindRenderbuffer(GL_RENDERBUFFER, normalRenderTarget); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, this->width, this->height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, normalRenderTarget); glGenTextures(1, &diffuseTex); glBindTexture(GL_TEXTURE_2D, diffuseTex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->width, this->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, diffuseTex, 0); // Generate and bind the OGL texture for positions glGenTextures(1, &positionTex); glBindTexture(GL_TEXTURE_2D, positionTex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, this->width, this->height, 0, GL_RGBA, GL_FLOAT, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Attach the texture to the FBO glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positionTex, 0); // Generate and bind the OGL texture for normals glGenTextures(1, &normalTex); glBindTexture(GL_TEXTURE_2D, normalTex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, this->width, this->height, 0, GL_RGBA, GL_FLOAT, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Attach the texture to the FBO glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normalTex, 0); state = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (state!=GL_FRAMEBUFFER_COMPLETE) util::log("Frame Buffer Objects failed"); //unbind glBindFramebuffer(GL_FRAMEBUFFER, 0); }; It's a bit on the heavy side and I'm sure there are a few unnecessary calls in there. I am not using the depth attachment at the moment.   "How are you attempting to draw things after the main render?" I am using a function that attempts to copy the fbo contents using glBlitFramebuffer(...), it looks like this: void FrameBufferObjects::showTexture(){ //Resore destination FBO to GL_DRAW_FRAMEBUFFER glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Bind fbo as a read buffer bindForReading(); GLint halfWidth = (GLint)(width / 2.0f); GLint halfHeight = (GLint)(height / 2.0f); //Diffuse glReadBuffer(GL_COLOR_ATTACHMENT0); glBlitFramebuffer(0, 0, width, height, 0, halfHeight, halfWidth, height, GL_COLOR_BUFFER_BIT, GL_LINEAR); //Position glReadBuffer(GL_COLOR_ATTACHMENT1); glBlitFramebuffer(0, 0, width, height, 0, 0, halfWidth, halfHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); //Normal glReadBuffer(GL_COLOR_ATTACHMENT2); glBlitFramebuffer(0, 0, width, height, halfWidth, halfHeight, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR); } and the bind for reading is just glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo), nothing else.     As for the glActiveTexture(GL_TEXTURE0); and glEnable(GL_TEXTURE_2D); calls, they were an accidental duplicate call, they are now only being called in the main render.   Also noted the fact that viewport should be handled manually, thank you.   The showTexture function is currently outputting the following result:     Where the background is cleared to a gray tone, and the contents of the three color attachments are displayed in the remaining 3 quads. Although these display nothing but the color black, and that's the problem.   I am going to try and debug the textures with gdebuffer and see where it all goes wrong.   My question now is, am I binding the buffers correctly and am I trying to display these in a sensible way? The framebuffer status check always returns complete.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!