I'm trying to implement a skybox and then use the cube map for the skybox to make a reflective sphere in my scene using some code I found editing to fit my project. The skybox shows but the image is almost corrupted looking, there is a basic outline of the mountains but no colour as you can see in the image.
http://i.imgur.com/kJT4aCV.jpg
I've been trying to make sure active texture and my shaders are correct but I just can't figure it out.
Vertex and fragment shader
#version 330 core
layout (location = 0) in vec3 position;
out vec3 TexCoords;
uniform mat4 projection;
uniform mat4 view;
void main()
{
vec4 pos = projection * view * vec4(position, 1.0);
gl_Position = pos.xyww;
TexCoords = position;
}
#version 330 core
in vec3 TexCoords;
out vec4 color;
uniform samplerCube skybox;
void main()
{
color = texture(skybox, TexCoords);
}
Load cubemap
GLuint loadCubemap(std::vector<const GLchar*> faces)
{
GLuint textureID;
glGenTextures(1, &textureID);
int width, height, numComponents;
unsigned char* image;
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
for (GLuint i = 0; i < faces.size(); i++)
{
image = stbi_load(faces[i], &width, &height, &numComponents, 4);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
stbi_image_free(image);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
return textureID;
}
Drawing skybox
glDepthFunc(GL_LEQUAL);
skyShader.Bind();
skyShader.Update(transform, camera);
view = glm::mat4(glm::mat3(camera.GetViewProjection()));
glUniformMatrix4fv(glGetUniformLocation(skyShader.getProg(), "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(skyShader.getProg(), "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glBindVertexArray(skyboxVAO);
glActiveTexture(GL_TEXTURE0);
glUniform1i(glGetUniformLocation(skyShader.getProg(), "skybox"), 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, skyboxTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glDepthFunc(GL_LESS);
Let me know if any other parts would be useful to see
The texture was read in, and fed to OpenGL with inconsistent number of components per pixel
image = stbi_load(faces[i], &width, &height, &numComponents, 4); read in the image with 4 components
But when you fed it to OpenGL, glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); you fed it as a texture with 3 components per pixel, causing every 4 bytes to be interpreted as red when it should've been something else
Related
I'm trying to make a skybox that can change with a button.
My solution for this is to bind my skyboxes and load my textures in the following way:
//SkyBox
GLuint skyboxVBO, skyboxVAO;
glGenVertexArrays(1, &skyboxVAO);
glGenBuffers(1, &skyboxVBO);
glBindVertexArray(skyboxVAO);
glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *)0);
// Load textures
vector<const GLchar*> facesN;
facesN.push_back("SkyBox/night/right.tga");
facesN.push_back("SkyBox/night/left.tga");
facesN.push_back("SkyBox/night/top.tga");
facesN.push_back("SkyBox/night/bottom.tga");
facesN.push_back("SkyBox/night/back.tga");
facesN.push_back("SkyBox/night/front.tga");
GLuint cubemapTextureN = TextureLoading::LoadCubemap(facesN);
vector<const GLchar*> faces;
faces.push_back("SkyBox/day/right.tga");
faces.push_back("SkyBox/day/left.tga");
faces.push_back("SkyBox/day/top.tga");
faces.push_back("SkyBox/day/bottom.tga");
faces.push_back("SkyBox/day/back.tga");
faces.push_back("SkyBox/day/front.tga");
GLuint cubemapTexture = TextureLoading::LoadCubemap(faces);
Then, in the program loop I draw the skybox with the following:
// Draw skybox as last
glDepthFunc(GL_LEQUAL); // Change depth function so depth test passes when values are equal to depth buffer's content
SkyBoxshader.Use();
view = glm::mat4(glm::mat3(camera.GetViewMatrix())); // Remove any translation component of the view matrix
glUniformMatrix4fv(glGetUniformLocation(SkyBoxshader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(SkyBoxshader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
// skybox cube
glBindVertexArray(skyboxVAO);
glActiveTexture(GL_TEXTURE1);
if (daytime == 1.0f) {
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
}
else {
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTextureN);
}
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glDepthFunc(GL_LESS); // Set depth function back to default
In theory, whenever I press the button that changes the value of daytime, the skybox should change its textures to cubemapTextureN and, with another press of the button, change back to cubemapTexture. Instead, it just draws the texture that was loaded last, cubemapTexture in this case.
I already tested daytime and it does change, so it's not that.
Also, I tried loading cubemapTextureN after cubemapTexture and by doing so cubemapTextureN gets drawn instead, but still no change. I'm assuming somehow while loading the second textures, the first ones get updated, which shouldn't happen since they have different names, unless i'm understanding it wrong.
Easy solution would be to just make models of the entire skyboxes and work with that, but if possible I want to see if I can use this solution.
Edit:
These are the Shaders for the skybox.
Fragment shader:
#version 330 core
in vec3 TexCoords;
out vec4 color;
uniform samplerCube skybox;
void main()
{
color = texture(skybox, TexCoords);
}
Vertex shader:
#version 330 core
layout (location = 0) in vec3 position;
out vec3 TexCoords;
uniform mat4 projection;
uniform mat4 view;
void main()
{
vec4 pos = projection * view * vec4(position, 1.0);
gl_Position = pos.xyww;
TexCoords = position;
}
And their use:
Shader SkyBoxshader("Shaders/SkyBox.vs", "Shaders/SkyBox.frag");
Also, if this is usefull, this is the header with the definition of TextureLoading, which contains LoadCubemap
#pragma once
// GLEW
#include <GL/glew.h>
// Other Libs
#include "stb_image.h"
// Other includes
#include "Model.h"
#include <vector>
class TextureLoading
{
public:
static GLuint LoadTexture(GLchar *path)
{
unsigned int textureID;
glGenTextures(1, &textureID);
int width, height, nrComponents;
unsigned char *data = stbi_load(path, &width, &height, &nrComponents, 0);
if (data)
{
GLenum format;
if (nrComponents == 1)
format = GL_RED;
else if (nrComponents == 3)
format = GL_RGB;
else if (nrComponents == 4)
format = GL_RGBA;
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
stbi_image_free(data);
}
else
{
std::cout << "Failed to load texture" << path << std::endl;
stbi_image_free(data);
}
return textureID;
}
static GLuint LoadCubemap(vector<const GLchar * > faces)
{
GLuint textureID;
glGenTextures(1, &textureID);
int width, height, nrChannels;
for (unsigned int i = 0; i < faces.size(); i++)
{
unsigned char *data = stbi_load(faces[i], &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
}
else
{
std::cout << "Cubemap texture failed to load at path: " << faces[i] << std::endl;
stbi_image_free(data);
}
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
return textureID;
}
};
There's some Artifacts on my FrameBuffer Depth Texture I can't get rid off:
The Code used to init the FrameBuffer:
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glGenTextures(1, &color);
glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D, depth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color, 0);
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, depth, 0);
GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, attachments);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
std::cout << "FBO FEHLER" << std::endl;
}
Code used to draw the FrameBuffer:
shader->bind();
// Bind Textures
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, color);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, depth);
glUniform1i(shader->getUniform("tex"), 0);
glUniform1i(shader->getUniform("depth"), 1);
glUniformMatrix4fv(shader->getUniform("matrix"), 1, GL_FALSE, glm::value_ptr(ortho));
// Draw Call
glBindBuffer(GL_ARRAY_BUFFER,fbovbo);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 20, (void*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 20, (void*)12);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Unbind
shader->unbind();//*/
FragmentShader of the actual rendering:
#version 330 core
layout(location = 0) out vec4 out_color;
layout(location = 1) out vec4 out_depth;
in float temp;
void main(void){
out_color = vec4(1,0.0,0.0,1.0);
out_depth = vec4(gl_FragCoord.z);
}
FragmentShader of the FrameBuffer rendering:
#version 330 core
in vec2 fuv;
out vec4 color;
uniform sampler2D tex;
uniform sampler2D depth;
void main(){
vec4 d = texture2D(depth, fuv);
gl_FragDepth = d.a;
vec4 c = texture2D(tex,fuv);
if(c.a<0.1){
discard;
}
color = c;
//color = vec4(texture2D(depth, fuv).zzz,1.0);
//color.a = 0.8;
//color = vec4(1,0,0,0.5);
}
The red "Mesh" is behind the brown surface, but its borders still appear. thats the problem
The problem might come from the limited precision of the depth buffer. Basically, the range between near and farplane has to be represented by the depth-buffer. In your case, the depth-buffer has 8 bit, thus there are only 256 different depth values that can be represented. When two objects are closer together than this, they will be mapped to the same value in the depth buffer.
To overcome this, you can try to increase the precision of the depth buffer, for example, by using
glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D, depth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_SHORT, NULL);
Side-note: I'm not sure why the depth texture has four channels. If you don't need them, I would change this to a one channel format.
I am trying to implement a skybox in open gl. It doesn't work unless I bind It as GL_TEXTURE_2D
This is how I load my cube map:
// http://www.antongerdelan.net/opengl/cubemaps.html
void SkyBoxMaterial::CreateCubeMap(const char* front, const char* back, const char* top, const char*bottom, const char* left, const char*right, GLuint *tex_cube){
glGenTextures(ONE, tex_cube);
assert(LoadCubeMapSide(*tex_cube, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, front));
assert(LoadCubeMapSide(*tex_cube, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, back));
assert(LoadCubeMapSide(*tex_cube, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, top));
assert(LoadCubeMapSide(*tex_cube, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, bottom));
assert(LoadCubeMapSide(*tex_cube, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, left));
assert(LoadCubeMapSide(*tex_cube, GL_TEXTURE_CUBE_MAP_POSITIVE_X, right));
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
checkGLErrors("SKYBOX_MATERIAL::CreateCubeMap", "END"); }
In the snippet below I bind the texture as a cube map. This does not work! I jus get a black square. However, if I would bind it to GL_TEXTURE_2D I get a textured cube (?).
bool SkyBoxMaterial::LoadCubeMapSide(GLuint texture, GLenum side_target, const char* fileName){
glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
int width, height, n;
int force_channels = 4;
unsigned char* image_data = stbi_load(fileName, &width, &height, &n, force_channels);
glTexImage2D(side_target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
free(image_data);
return true;
}
Rendering of my material:
void SkyBoxMaterial::Draw(){
glDepthMask(GL_FALSE);
glUseProgram(programID);
glBindVertexArray(VAO);
glActiveTexture(GL_TEXTURE0);
glUniform1i(glGetUniformLocation(programID, "skybox"), 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMapTexture);
glDrawArrays(geometry->getDrawMode(), 0, geometry->getNumVertices());
glBindVertexArray(CLEAR);
glUseProgram(CLEAR);
glDepthMask(GL_TRUE);
}
My vertex shader:
#version 430 core
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
layout (location = 0) in vec3 gl_vertex;
out vec3 texcoords;
void main(){
vec4 homogeneous_vertecies = vec4(gl_vertex,1.0);
gl_Position = projection*view*model*homogeneous_vertecies;
texcoords = gl_vertex;
}
Fragement Shader:
#version 430 core
in vec3 texcoords;
uniform samplerCube skybox;
// Ouput data
out vec4 color;
void main(){
color = texture(skybox,texcoords);
}
I am failry new to OpenGl. Is this maybe a flagging Issue?
These are the only 3 flags I set at the start.
glEnable(GL_DEPTH_TEST);
// Cull triangles which normal is not towards the camera
glEnable(GL_CULL_FACE);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
Don't really know what to go on here. This seems very obscure to me.
Thanks!
Marc
I'm using integer texture and bind it to framebuffer to get render data.
I'v bind it to quad to display it on the screen and I'm sure the content of the texture is right.
But when I use glGetTexImage to get the content of the texture, I get random numbers.
here is the code to create the framebuffer:
glEnable(GL_TEXTURE_2D);
glGenFramebuffers(1, ¶m.fbo);
glGenTextures(1,¶m.triTex);
glBindTexture(GL_TEXTURE_2D, param.triTex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, param.fboSize, param.fboSize, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, param.fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, param.triTex, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
The texture and framebuffer renders without problem.
here is the code of getting the content:
glBindTexture(GL_TEXTURE_2D, param.triTex);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
triTexData = (unsigned int *)malloc(param.fboSize * param.fboSize * sizeof(unsigned int));
memset(triTexData, 0, sizeof(unsigned int) * param.fboSize * param.fboSize);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, triTexData);
glBindTexture(GL_TEXTURE_2D,0);
Fragment shader and geometry shader
#version 330
flat in int color;
out vec4 fragColor;
void main(void)
{
fragColor = vec4(color,0.0,0.0,0.0);
}
#version 330
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
flat out int color;
void main(void)
{
gl_Position = gl_in[0].gl_Position;
color = gl_PrimitiveIDIn;
EmitVertex();
gl_Position = gl_in[1].gl_Position;
color = gl_PrimitiveIDIn;
EmitVertex();
gl_Position = gl_in[2].gl_Position;
color = gl_PrimitiveIDIn;
EmitVertex();
EndPrimitive();
};
Your fragment shader should actually be written this way to output to a GL_R32UI image:
#version 330
flat in int color;
out uint fragColor;
void main (void) {
fragColor = color;
}
At present, you are not reading back "random" numbers, you are just seeing what happens when you interpret floating-point data as integers without the proper conversion. Not pleasant, is it?
I've been trying to add SSAO (based on the tutorial here: http://john-chapman-graphics.blogspot.co.nz/2013/01/ssao-tutorial.html) to a project of mine and I've gotten stuck on rendering the depth correctly.
I have created a framebuffer texture to draw the depth to each frame. The texture itself looks correct when I draw it to a quad but I can't figure out how to correctly apply it to the whole scene.
Here's what the regular scene looks like:
And here's the applied depth texture:
Currently in my fragment shader I just use my regular texture coordinates (TexCoord0) to draw the depth texture. I'm guessing I need to change this but I don't have a clue what to change it to.
Here's the relevant fragment shader code:
#version 330 core
in vec2 TexCoord0;
smooth in vec3 vNormal;
smooth in vec3 vWorldPos;
in mat4 ProjectionMatrix;
uniform sampler2D uDepthTex;
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = texture(uDepthTex, TexCoord0);
}
I'm at a bit of a loss as to how to fix this. I've read a lot of sample code online which seems to use regular texture coordinates to draw the depth.
EDIT:
Here's my framebuffer setup code:
glGenFramebuffers(1, &ssaoFramebufferID);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFramebufferID);
glGenTextures(1, &ssaoDepthTextureID);
glBindTexture(GL_TEXTURE_2D, ssaoDepthTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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_MODE, GL_NONE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, ssaoDepthTextureID, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
And the depth pass code I call each frame before regular draw:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFramebufferID);
glViewport(0, 0, 1024, 1024);
depthShader.Bind();
depthShader.SetUniformMatrixfv("depthMVP", camera.GetViewMatrix() * Matrix4::Perspective(60, aspectRatio, 0.1f, 10.0f));
DrawScene(true);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, width, height);
My depth shaders, vertex:
#version 330 core
layout(location = 0) in vec3 Position;
uniform mat4 depthMVP;
void main() {
gl_Position = depthMVP * vec4(Position, 1.0);
}
fragment:
#version 330 core
layout(location = 0) out float fragmentdepth;
void main() {
fragmentdepth = gl_FragCoord.z;
}
EDIT2:
The glClear call where it currently is gives me a completely black texture. Putting it below the first glViewport call gives the depth image I displayed above though:
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFramebufferID);
glViewport(0, 0, 1024, 1024);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
I managed to get it working thanks to some help in the comments:
My code is now as follows, fragment shader:
#version 330 core
in vec2 TexCoord0;
smooth in vec3 vNormal;
smooth in vec3 vWorldPos;
in mat4 ProjectionMatrix;
uniform sampler2D uDepthTex;
uniform float uWidth;
uniform float uHeight;
layout(location = 0) out vec4 FragColor;
void main()
{
vec2 res = gl_FragCoord.xy / vec2(uWidth, uHeight);
FragColor = texture(uDepthTex, res);
}
Framebuffer creation:
glGenFramebuffers(1, &ssaoFramebufferID);
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFramebufferID);
glGenTextures(1, &ssaoDepthTextureID);
glBindTexture(GL_TEXTURE_2D, ssaoDepthTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 768, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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_NONE);
Depth draw code:
glBindFramebuffer(GL_FRAMEBUFFER, ssaoFramebufferID);
glViewport(0, 0, 1024, 768);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
depthShader.Bind();
glDisable(GL_ALPHA_TEST);
depthShader.SetUniformMatrixfv("depthMVP", Matrix4::Perspective(60, aspectRatio, 0.1f, 10.0f) * camera.GetViewMatrix());
DrawScene();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, width, height);
glEnable(GL_ALPHA_TEST);