Hello, I try to write very basic code for environment map. There is a cube in the middle of scene surrounded by 3 another cubes and this middle cube should reflect everything around it. But when I run code I see only something like this below. I tried to use one FBO instead of 6 and change texture’s settings but it doesn’t helped. Why do I see only a part of cubes’ textures around the mirror cube? How to fix it???
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Hello Window!", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to initialize GLFW" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glEnable(GL_DEPTH_TEST);
glm::mat4 projection = glm::mat4(1.0f);
glm::mat4 view = glm::mat4(1.0f);
Cube cube1(1.0f, "D:/Textures for OpenGL/container.jpg", &view, &projection);
Cube cube2(1.0f, "D:/Textures for OpenGL/wall.jpg", &view, &projection);
Cube cube3(1.0f, "D:/Textures for OpenGL/grass.jpg", &view, &projection);
float cubeVertices[] = {
// positions // normals
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f
};
VAO cubeVAO;
cubeVAO.Bind();
VBO cubeVBO(cubeVertices, sizeof(cubeVertices));
cubeVAO.LinkAttrib(cubeVBO, 0, 3, GL_FLOAT, 6 * sizeof(float), (void*)0);
cubeVAO.LinkAttrib(cubeVBO, 1, 3, GL_FLOAT, 6 * sizeof(float), (void*)(3 * sizeof(float)));
Shader cubeShader("mirrorCubeVertex.vert", "mirrorCubeFragment.frag");
float skyboxVertices[] = {
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f
};
VAO skyBoxVAO;
skyBoxVAO.Bind();
VBO skyBoxVBO(skyboxVertices, sizeof(skyboxVertices));
skyBoxVAO.LinkAttrib(skyBoxVBO, 0, 3, GL_FLOAT, 3 * sizeof(float), (void*)0);
Shader skyboxShader("skyboxVertex.vert", "skyboxFragment.frag");
stbi_set_flip_vertically_on_load(false);
std::vector<std::string> faces
{
"D:/Textures for OpenGL/right.jpg",
"D:/Textures for OpenGL/left.jpg",
"D:/Textures for OpenGL/top.jpg",
"D:/Textures for OpenGL/bottom.jpg",
"D:/Textures for OpenGL/front.jpg",
"D:/Textures for OpenGL/back.jpg",
};
GLuint cubemapTexture = loadCubemap(faces);
VAO refVAO;
refVAO.Bind();
VBO refVBO(skyboxVertices, sizeof(skyboxVertices));
skyBoxVAO.LinkAttrib(skyBoxVBO, 0, 3, GL_FLOAT, 3 * sizeof(float), (void*)0);
Shader refShader("skyboxVertex.vert", "skyboxFragment.frag");
skyboxShader.use();
skyboxShader.setInt("cubeMap", 0);
cubeShader.use();
cubeShader.setInt("skybox", 0);
GLuint framebuffers[6];
GLuint renderbuffers[6];
GLuint textureColorBuffer;
glGenTextures(1, &textureColorBuffer);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureColorBuffer);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_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);
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
}
for (int i = 0; i < 6; i++)
{
glGenFramebuffers(1, &framebuffers[i]);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[i]);
glGenRenderbuffers(1, &renderbuffers[i]);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[i]);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 256, 256);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffers[i]);
auto fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
std::cout << "Framebuffer not complete: " << fboStatus << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
while (!glfwWindowShouldClose(window))
{
float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
processInput(window);
for (int i = 0; i < 6; i++)
{
glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, textureColorBuffer, 0);
glEnable(GL_DEPTH_TEST);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
switch (i)
{
case 0:
camera.Position = glm::vec3(0.0f, 0.0f, -1.0f);
camera.Yaw = -90.0f;
camera.Pitch = 0.0f;
camera.updateCameraVectors();
break;
case 1:
camera.Position = glm::vec3(1.0f, 0.0f, 0.0f);
camera.Yaw = 0.0f;
camera.Pitch = 0.0f;
camera.updateCameraVectors();
break;
case 2:
camera.Position = glm::vec3(0.0f, 0.0f, 1.0f);
camera.Yaw = 90.0f;
camera.Pitch = 0.0f;
camera.updateCameraVectors();
break;
case 3:
camera.Position = glm::vec3(-1.0f, 0.0f, 0.0f);
camera.Yaw = 180.0f;
camera.Pitch = 0.0f;
camera.updateCameraVectors();
break;
case 4:
camera.Position = glm::vec3(0.0f, 1.0f, 0.0f);
camera.Yaw = -90.0f;
camera.Pitch = 89.0f;
camera.updateCameraVectors();
break;
case 5:
camera.Position = glm::vec3(0.0f, -1.0f, 0.0f);
camera.Yaw = -90.0f;
camera.Pitch = -89.0f;
camera.updateCameraVectors();
break;
}
projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
view = camera.GetViewMatrix();
glm::mat4 model = glm::mat4(1.0f);
cube1.setPosition(glm::vec3(0.0f, 0.0f, -3.0f));
cube1.draw();
cube2.setPosition(glm::vec3(3.0f, 0.0f, 0.0f));
cube2.draw();
cube3.setPosition(glm::vec3(-3.0f, 0.0f, 0.0f));
cube3.draw();
cubeShader.use();
cubeShader.setMat4("projection", projection);
cubeShader.setMat4("view", view);
cubeShader.setMat4("model", model);
cubeShader.setVec3("cameraPos", camera.Position);
cubeVAO.Bind();
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
cubeVAO.Unbind();
glDepthFunc(GL_LEQUAL);
skyboxShader.use();
view = glm::mat4(glm::mat3(camera.GetViewMatrix()));
skyboxShader.setMat4("view", view);
skyboxShader.setMat4("projection", projection);
skyboxShader.setMat4("model", model);
// Skybox Cube
skyBoxVAO.Bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
skyBoxVAO.Unbind();
glDepthFunc(GL_LESS);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
view = camera.GetViewMatrix();
glm::mat4 model = glm::mat4(1.0f);
cube1.setPosition(glm::vec3(0.0f, 0.0f, -3.0f));
cube1.draw();
cube2.setPosition(glm::vec3(3.0f, 0.0f, 0.0f));
cube2.draw();
cube3.setPosition(glm::vec3(-3.0f, 0.0f, 0.0f));
cube3.draw();
cubeShader.use();
cubeShader.setMat4("projection", projection);
cubeShader.setMat4("view", view);
cubeShader.setMat4("model", model);
cubeShader.setVec3("cameraPos", camera.Position);
cubeVAO.Bind();
glBindTexture(GL_TEXTURE_CUBE_MAP, textureColorBuffer);
glDrawArrays(GL_TRIANGLES, 0, 36);
cubeVAO.Unbind();
glDepthFunc(GL_LEQUAL);
skyboxShader.use();
view = glm::mat4(glm::mat3(camera.GetViewMatrix()));
skyboxShader.setMat4("view", view);
skyboxShader.setMat4("projection", projection);
skyboxShader.setMat4("model", model);
// Skybox Cube
skyBoxVAO.Bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
skyBoxVAO.Unbind();
glDepthFunc(GL_LESS);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
}