Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 months ago.
Improve this question
I wonder if you can help me...
I followed learnopengl.com and learned the details about framebuffer. However when I am creating my own scene I found that when I press key "W", the camera moves towards the right and front. What's more, the containers, planes and the camera directions all seemed to have problems when rendering.
The results are listed below:
The direction of the camera originally wrong and when pressing W it seems like it is moving towards the right and front direction.
The rendering result also seems to have problems.
After my tests I think the problem might be the mistakenly use of glViewport. When I set the glViewport(0,0,800,600) after binding the new framebuffer, I got the output like this:
You can see the distortion disappeared however I only got things rendered on the left bottom corner...
Below is the correct output:(https://learnopengl.com/Advanced-OpenGL/Framebuffers)
This is my source code:
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include "LearnOpenGL/camera.h"
#include "LearnOpenGL/stb_image.h"
#include "glad/glad.h"
#include <GLFW/glfw3.h>
#include <LearnOpenGL/filesystem.h>
#include <LearnOpenGL/model.h>
#include "imgui-1.89/imgui.h"
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
void processInput(GLFWwindow *window);
void mouse_callback(GLFWwindow *window, double xpos, double ypos);
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
unsigned int loadTexture(char const * path);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
// camera attributes
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
float lastX = SCR_WIDTH / 2.0f;
float lastY = SCR_HEIGHT / 2.0f;
bool firstMouse = true;
float fov = 45.0f;
// timing
float deltaTime = 0.0f; // time between current frame and last frame
float lastFrame = 0.0f; // time of last frame
int main() {
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// glfw window creation
// --------------------
GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "My Playground", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// glad: load all OpenGL function pointers
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
glEnable(GL_DEPTH_TEST);
Shader shader("../chapters/advanced_opengl/shaders_framebuffer/framebuffer.vert", "../chapters/advanced_opengl/shaders_framebuffer/framebuffer.frag");
Shader screenShader("../chapters/advanced_opengl/shaders_framebuffer/framebuffer_screen.vert","../chapters/advanced_opengl/shaders_framebuffer/framebuffer_screen.frag");
float cubeVertices[] = {
// positions // texture Coords
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
float planeVertices[] = {
// positions // texture Coords
5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
-5.0f, -0.5f, 5.0f, 0.0f, 0.0f,
-5.0f, -0.5f, -5.0f, 0.0f, 2.0f,
5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
-5.0f, -0.5f, -5.0f, 0.0f, 2.0f,
5.0f, -0.5f, -5.0f, 2.0f, 2.0f
};
float quadVertices[] = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
// positions // texCoords
-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
// cube VAO
unsigned int cubeVAO, cubeVBO;
glGenVertexArrays(1, &cubeVAO);
glGenBuffers(1, &cubeVBO);
glBindVertexArray(cubeVAO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
// plane VAO
unsigned int planeVAO, planeVBO;
glGenVertexArrays(1, &planeVAO);
glGenBuffers(1, &planeVBO);
glBindVertexArray(planeVAO);
glBindBuffer(GL_ARRAY_BUFFER, planeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(planeVertices), &planeVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
// screen quad VAO
unsigned int quadVAO, quadVBO;
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
unsigned int cubeTexture = loadTexture(FileSystem::getPath("resources/container.jpg").c_str());
unsigned int floorTexture = loadTexture(FileSystem::getPath("resources/metal.png").c_str());
// configuration
shader.use();
shader.setInt("texture1",0);
screenShader.use();
screenShader.setInt("screenTexture",0);
unsigned int framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// create a color attachment texture
unsigned int textureColorbuffer;
glGenTextures(1, &textureColorbuffer);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);
// create a renderbuffer object for depth and stencil attachment (we won't be sampling these)
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT);
glBindRenderbuffer(GL_RENDERBUFFER, 0); // once we've allocated enough memory for the renderbuffer object we can unbind the renderbuffer.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); // attach the renderbuffer object to the depth and stencil attachment of the framebuffer
if(glCheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE)
{
std::cout<<"ERROR::FRAMEBUFFER:: Framebuffer is not complete!"<<std::endl;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0); // be sure to unbind the framebuffer to make sure we're not accidentally rendering to the wrong framebuffer.
// draw as wireframe
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// render loop
// -----------
while (!glfwWindowShouldClose(window)) {
// per-frame time logic
// --------------------
float currentFrame = static_cast<float>(glfwGetTime());
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// input
// -----
processInput(window);
// render
// ------
// bind to framebuffer and draw scene as we normally would to color texture
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glEnable(GL_DEPTH_TEST); // enable depth testing (is disabled for rendering screen-space quad)
// firstly clear the screen
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader.use();
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float) SCR_WIDTH / (float) SCR_HEIGHT, 0.1f,100.0f);
shader.setMat4("projection", projection);
shader.setMat4("view", view);
// cubes
glBindVertexArray(cubeVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
shader.setMat4("model",model);
glDrawArrays(GL_TRIANGLES, 0, 36);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
// floor
glBindVertexArray(planeVAO);
glBindTexture(GL_TEXTURE_2D, floorTexture);
shader.setMat4("model", glm::mat4(1.0f));
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
// now bind back to default framebuffer and draw a quad plane with the attached framebuffer color texture
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST); // disable depth test so screen-space quad isn't discarded due to depth test.
// clear all relevant buffers
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // set clear color to white (not really necessary actually, since we won't be able to see behind the quad anyways)
glClear(GL_COLOR_BUFFER_BIT);
screenShader.use();
glBindVertexArray(quadVAO);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer); // use the color attachment texture as the texture of the quad plane
glDrawArrays(GL_TRIANGLES, 0, 6);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
glfwTerminate();
return 0;
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
camera.ProcessKeyboard(FORWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}
void mouse_callback(GLFWwindow *window, double xpos, double ypos) {
if (firstMouse) {
lastX = xpos;
lastY = ypos;
firstMouse = false;
}
float xoffset = xpos - lastX;
float yoffset = lastY - ypos; // reversed: y ranges from bottom to top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);
}
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) {
camera.ProcessMouseScroll(static_cast<float>(yoffset));
}
unsigned int loadTexture(char const * 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 << "Texture failed to load at path: " << path << std::endl;
stbi_image_free(data);
}
return textureID;
}
This is my framebuffer.vert:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 TexCoords;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
TexCoords = aTexCoords;
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
This is my framebuffer.frag:
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D texture1;
void main()
{
FragColor = texture(texture1, TexCoords);
}
This is my framebuffer_screen.vert:
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 TexCoords;
void main()
{
TexCoords = aTexCoords;
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
}
This is my framebuffer_screen.frag:
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;
void main()
{
FragColor = texture(screenTexture, TexCoords);
}
I tried to find the problem but I couldn't figure it out... I would appreciate it if you could help me. Thank you so much.
This is caused by the difference between width / height in raw pixels (i.e. number of physical pixels) v.s. width / height in screen coordinates (i.e. logical window size). There is a note on the GLFW window guide that says:
Do not pass the window size to glViewport or other pixel-based OpenGL calls. The window size is in screen coordinates, not pixels. Use the framebuffer size, which is in pixels, for pixel-based calls.
glfwCreateWindow() requires the width and height to be in screen coordinates. Therefore, the SCR_WIDTH and SCR_HEIGHT are in screen coordinates. All other places, however, require width and height in raw pixels, which can be obtained by either
saving the width and height values passed to your framebuffer_size_callback callback function, or
calling glfwGetFramebufferSize from your main function, which is easier.
Using the framebuffer size (instead of SCR_WIDTH and SCR_HEIGHT) to calculate all the rendering stuff for the gl* calls solves your issue.
I've spent 2 weeks trying to get OpenGL to draw a cube in 3D, but no matter what I do, it never actually drew a cube. If I enable the depth test with glEnable(DEPTH_TEST), it simply does not render anything. If I comment out that function, it renders all the vertices as if the z-values were all 0. I'm completely stuck and have no idea what i've done wrong.
Here's my main file: https://pastebin.com/D8cEcJ4g
#include "Dependencies\glew\glew.h"
#include "Dependencies\freeglut\freeglut.h"
#include "Dependencies\soil\SOIL.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include "ShaderLoader.h";
#include "Camera.h"
#define BUTTON_UP 0
#define BUTTON_DOWN 1
GLuint program;
GLuint vao, vbo, ebo;
GLuint texture, texture2;
unsigned char keyState[255];
glm::vec3 vPosTrans = glm::vec3(-0.50f, -0.50f, 0.0f);//source
glm::vec3 vPosInit = vPosTrans;
glm::vec3 vPosDest = glm::vec3(0.50f, 0.50f, 0.0f);//destination
glm::vec3 vCurrentPos = vPosTrans;
bool Dest1or2 = true;
const GLfloat WIDTH = 800.0f, HEIGHT = 600.0f;
Camera* camera;
void init(){
camera = new Camera(180.0f, WIDTH, HEIGHT, 0.0f, 100.0f);
ShaderLoader shaderLoader;
program = shaderLoader.CreateProgram("CoordSystem_Texture_QUAD.vs", "CoordSystem_Texture_QUAD.fs");
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Set up vertex data (and buffer(s)) and attribute pointers
GLfloat vertices[] = {
//position //color //texture coord //Normals
-1.01f, -1.01f, -1.01f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, -0.0f, 0.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 0.0f, -0.0f, 1.0f, 0.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// Fill in the back face vertex data.
-1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.01f, -1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the top face vertex data.
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the bottom face vertex data.
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the left face vertex data.
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, -1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the right face vertex data.
1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
};
GLuint indices[] = {
// front
0, 1, 2,
0, 2, 3,
// top
4, 5, 6,
4, 6, 7,
// back
8, 9, 10,
8, 10, 11,
// bottom
12, 13, 14,
12, 14, 15,
// left
16, 17, 18,
16, 18, 19,
// right
20, 21, 22,
20, 22, 23,
};
//** VAO **
// Generate vertex arrow object
glGenVertexArrays(1, &vao);
// Bind the Vertex Array Object to openGl context
glBindVertexArray(vao);//otherwise glVertexAttribPointer
//** VBO **
// Then bind and set vertex buffer(s).
// First paramter is how many buffers we have to create
glGenBuffers(1, &vbo);
// bind VBO to binding point, here it is GL_ARRAY_BUFFER
// there are other binding points
glBindBuffer(GL_ARRAY_BUFFER, vbo);//bind to context
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertices),// GPU need to know how much memory needs to be allocated
vertices,//copy data to GPU
GL_STATIC_DRAW);// How to use the buffer - buffer is created and modified once
//** EBO **
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(indices),
indices,
GL_STATIC_DRAW);
// ** Attributes **
//** Vertex Attribute **
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
//** Color Attribute **
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
//** TexCoord attribute **
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
// It's always a good thing to unbind any buffer/array to prevent strange bugs
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//** Load and bind texture 1
//--------------------------
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
int width, height;
unsigned char* image = SOIL_load_image("wall.jpg", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0);
// ** Load and Bind Texture 2
//---------------------------
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image2);
glBindTexture(GL_TEXTURE_2D, 0);
// Set texture wrapping to GL_REPEAT (usually basic wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void render(){
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw our first triangle
glUseProgram(program);
//bind
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(program, "Texture"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glUniform1i(glGetUniformLocation(program, "Texture2"), 1);
glBindVertexArray(vao);
// Draw Elements intead of vertex array
glDrawArrays(GL_QUADS, 0, 24);
//glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glutSwapBuffers();
}
void update(){
GLfloat cameraSpeed = 0.05f;
camera->setCameraSpeed(cameraSpeed);
//currentTime uniform
GLfloat currentTime = glutGet(GLUT_ELAPSED_TIME);
currentTime = currentTime / 1000;
GLint currentTimeLocation = glGetUniformLocation(program, "currentTime");
glUniform1f(currentTimeLocation, currentTime);
//transforms
glm::mat4 transform = glm::mat4(1.0f);
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
glm::mat4 model = glm::mat4(1.0);
if (keyState[(unsigned char)'w'] == BUTTON_DOWN) {
camera->moveForward();
std::cout << "e";
}
if (keyState[(unsigned char)'s'] == BUTTON_DOWN) {
camera->moveBack();
std::cout << "A";
}
camera->Update();
//glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
glm::mat4 projection = camera->getProjectionMatrix();
glm::mat4 view = glm::lookAt(camera->getCameraPos(), camera->getCameraPos() + camera->getCameraFront(), camera->getCameraUp());
//glm::mat4 view = glm::lookAt(glm::vec3(1, 1, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1));
GLfloat radius = 3.5f;
GLfloat camX = sin(currentTime) * radius;
GLfloat camZ = cos(currentTime) * radius;
//glm::mat4 view = glm::lookAt(
// glm::vec3(camX, 0.0, camZ),
// glm::vec3(0.0, 0.0, 0.0),
// glm::vec3(0.0, 1.0, 0.0));
transform = glm::scale(transform, vScaleVec);
glm::vec3(0.65f, 0.65f, 0.65f);
//transform = glm::rotate(transform, 90.0f, glm::vec3(0.0, 0.0, 1.0));
if (vCurrentPos == vPosDest && Dest1or2 == true )
{
Dest1or2 = false;
}
else if (vCurrentPos == vPosTrans && Dest1or2 == false)
{
Dest1or2 = true;
}
if(Dest1or2)
vCurrentPos = glm::mix(vCurrentPos, vPosDest, currentTime * 0.01f);
else
vCurrentPos = glm::mix(vCurrentPos, vPosTrans, currentTime*0.01f);
//transform = glm::translate(transform, vCurrentPos);
//transform = glm::translate(transform, glm::vec3(-0.51f, -0.51f, 0.0f));
//transform = glm::rotate(transform, ((GLfloat)currentTime / 100) * 90.0f, glm::vec3(0.0f, 0.0f, 1.0f));
// RTS
GLuint transformLoc = glGetUniformLocation(program, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
GLint modelLoc = glGetUniformLocation(program, "model");
GLint viewLoc = glGetUniformLocation(program, "view");
GLint projLoc = glGetUniformLocation(program, "projection");
// Pass them to the shaders
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(camera->getViewMatrix()));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(camera->getProjectionMatrix()));
//glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
//glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y) {
keyState[key] = BUTTON_DOWN;
//printf("key pressed: %d \n", key);
}
void keyboard_up(unsigned char key, int x, int y) {
keyState[key] = BUTTON_UP;
}
int main(int argc, char **argv){
// init glut
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(300, 200);
glutInitWindowSize(800, 600);
glutCreateWindow("QUAD EBO");
//init GLEW
glewInit();
init();
//clear
glClearColor(1.0, 0.0, 0.0, 1.0);//clear red
// register callbacks
glutDisplayFunc(render);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboard_up);
glutIdleFunc(update);
glutMainLoop();
return 0;
}
RAW Paste Data
#include "Dependencies\glew\glew.h"
#include "Dependencies\freeglut\freeglut.h"
#include "Dependencies\soil\SOIL.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include "ShaderLoader.h";
#include "Camera.h"
#define BUTTON_UP 0
#define BUTTON_DOWN 1
GLuint program;
GLuint vao, vbo, ebo;
GLuint texture, texture2;
unsigned char keyState[255];
glm::vec3 vPosTrans = glm::vec3(-0.50f, -0.50f, 0.0f);//source
glm::vec3 vPosInit = vPosTrans;
glm::vec3 vPosDest = glm::vec3(0.50f, 0.50f, 0.0f);//destination
glm::vec3 vCurrentPos = vPosTrans;
bool Dest1or2 = true;
const GLfloat WIDTH = 800.0f, HEIGHT = 600.0f;
Camera* camera;
void init(){
camera = new Camera(180.0f, WIDTH, HEIGHT, 0.0f, 100.0f);
ShaderLoader shaderLoader;
program = shaderLoader.CreateProgram("CoordSystem_Texture_QUAD.vs", "CoordSystem_Texture_QUAD.fs");
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Set up vertex data (and buffer(s)) and attribute pointers
GLfloat vertices[] = {
//position //color //texture coord //Normals
-1.01f, -1.01f, -1.01f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, -0.0f, 0.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 0.0f, -0.0f, 1.0f, 0.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// Fill in the back face vertex data.
-1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.01f, -1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the top face vertex data.
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the bottom face vertex data.
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the left face vertex data.
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, -1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the right face vertex data.
1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
};
GLuint indices[] = {
// front
0, 1, 2,
0, 2, 3,
// top
4, 5, 6,
4, 6, 7,
// back
8, 9, 10,
8, 10, 11,
// bottom
12, 13, 14,
12, 14, 15,
// left
16, 17, 18,
16, 18, 19,
// right
20, 21, 22,
20, 22, 23,
};
//** VAO **
// Generate vertex arrow object
glGenVertexArrays(1, &vao);
// Bind the Vertex Array Object to openGl context
glBindVertexArray(vao);//otherwise glVertexAttribPointer
//** VBO **
// Then bind and set vertex buffer(s).
// First paramter is how many buffers we have to create
glGenBuffers(1, &vbo);
// bind VBO to binding point, here it is GL_ARRAY_BUFFER
// there are other binding points
glBindBuffer(GL_ARRAY_BUFFER, vbo);//bind to context
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertices),// GPU need to know how much memory needs to be allocated
vertices,//copy data to GPU
GL_STATIC_DRAW);// How to use the buffer - buffer is created and modified once
//** EBO **
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(indices),
indices,
GL_STATIC_DRAW);
// ** Attributes **
//** Vertex Attribute **
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
//** Color Attribute **
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
//** TexCoord attribute **
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
// It's always a good thing to unbind any buffer/array to prevent strange bugs
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//** Load and bind texture 1
//--------------------------
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
int width, height;
unsigned char* image = SOIL_load_image("wall.jpg", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0);
// ** Load and Bind Texture 2
//---------------------------
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image2);
glBindTexture(GL_TEXTURE_2D, 0);
// Set texture wrapping to GL_REPEAT (usually basic wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void render(){
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw our first triangle
glUseProgram(program);
//bind
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(program, "Texture"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glUniform1i(glGetUniformLocation(program, "Texture2"), 1);
glBindVertexArray(vao);
// Draw Elements intead of vertex array
glDrawArrays(GL_QUADS, 0, 24);
//glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glutSwapBuffers();
}
void update(){
GLfloat cameraSpeed = 0.05f;
camera->setCameraSpeed(cameraSpeed);
//currentTime uniform
GLfloat currentTime = glutGet(GLUT_ELAPSED_TIME);
currentTime = currentTime / 1000;
GLint currentTimeLocation = glGetUniformLocation(program, "currentTime");
glUniform1f(currentTimeLocation, currentTime);
//transforms
glm::mat4 transform = glm::mat4(1.0f);
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
glm::mat4 model = glm::mat4(1.0);
if (keyState[(unsigned char)'w'] == BUTTON_DOWN) {
camera->moveForward();
std::cout << "e";
}
if (keyState[(unsigned char)'s'] == BUTTON_DOWN) {
camera->moveBack();
std::cout << "A";
}
camera->Update();
//glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
glm::mat4 projection = camera->getProjectionMatrix();
glm::mat4 view = glm::lookAt(camera->getCameraPos(), camera->getCameraPos() + camera->getCameraFront(), camera->getCameraUp());
//glm::mat4 view = glm::lookAt(glm::vec3(1, 1, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1));
GLfloat radius = 3.5f;
GLfloat camX = sin(currentTime) * radius;
GLfloat camZ = cos(currentTime) * radius;
//glm::mat4 view = glm::lookAt(
// glm::vec3(camX, 0.0, camZ),
// glm::vec3(0.0, 0.0, 0.0),
// glm::vec3(0.0, 1.0, 0.0));
transform = glm::scale(transform, vScaleVec);
glm::vec3(0.65f, 0.65f, 0.65f);
//transform = glm::rotate(transform, 90.0f, glm::vec3(0.0, 0.0, 1.0));
if (vCurrentPos == vPosDest && Dest1or2 == true )
{
Dest1or2 = false;
}
else if (vCurrentPos == vPosTrans && Dest1or2 == false)
{
Dest1or2 = true;
}
if(Dest1or2)
vCurrentPos = glm::mix(vCurrentPos, vPosDest, currentTime * 0.01f);
else
vCurrentPos = glm::mix(vCurrentPos, vPosTrans, currentTime*0.01f);
//transform = glm::translate(transform, vCurrentPos);
//transform = glm::translate(transform, glm::vec3(-0.51f, -0.51f, 0.0f));
//transform = glm::rotate(transform, ((GLfloat)currentTime / 100) * 90.0f, glm::vec3(0.0f, 0.0f, 1.0f));
// RTS
GLuint transformLoc = glGetUniformLocation(program, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
GLint modelLoc = glGetUniformLocation(program, "model");
GLint viewLoc = glGetUniformLocation(program, "view");
GLint projLoc = glGetUniformLocation(program, "projection");
// Pass them to the shaders
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(camera->getViewMatrix()));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(camera->getProjectionMatrix()));
//glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
//glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y) {
keyState[key] = BUTTON_DOWN;
//printf("key pressed: %d \n", key);
}
void keyboard_up(unsigned char key, int x, int y) {
keyState[key] = BUTTON_UP;
}
int main(int argc, char **argv){
// init glut
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(300, 200);
glutInitWindowSize(800, 600);
glutCreateWindow("QUAD EBO");
//init GLEW
glewInit();
init();
//clear
glClearColor(1.0, 0.0, 0.0, 1.0);//clear red
// register callbacks
glutDisplayFunc(render);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboard_up);
glutIdleFunc(update);
glutMainLoop();
return 0;
}
Fragment Shader:
#version 430 core
in vec3 outColor;
in vec2 TexCoord;
out vec4 color;
uniform sampler2D Texture;
uniform sampler2D Texture2;
uniform float currentTime;
void main()
{
//vec3 colorTemp = outColor * abs(sin(currentTime));
//color = vec4(colorTemp, 1.0f) ;
//color = texture(ourTexture, TexCoord) * vec4(outColor, 1.0f) * abs(sin(currentTime)) ;
color = mix(texture(Texture, TexCoord), texture(Texture2, TexCoord), 0.2) * vec4(outColor, 1.0f) * abs(sin(currentTime));
}
Vertex shader:
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoord;
out vec3 outColor;
out vec2 TexCoord;
uniform mat4 transform;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(void)
{
gl_Position = projection * view * model * transform * vec4(position, 1.0);
outColor = color;
TexCoord = vec2(texCoord.x, 1.0 - texCoord.y);
}
If I comment out that function, it renders all the vertices as if the z-values were all 0
Well, that's because ... they are:
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
[...]
transform = glm::scale(transform, vScaleVec);
[...]
gl_Position = projection * view * model * transform * vec4(position, 1.0);
You scale with z=0, which means you move all vertices into the z = 0 plane. So it is already flat after your first transformation step (which also means transform is a singular matrix with the third row and column being all zeros). The additional transform steps you have commented out in the code, as well as all the other matrices applied in the shader, won't change any of that, the object is still a flat plane, no matter what other matrices you pre- or post-multiply to it, they just move that plane around.
I don't know which amount of scaling you want, but scaling by 0 is almost never a good idea, and 1 is the neutral element for scaling operations.
Also, why do you have model and transform as separate matrices in the shader? In 3d computer graphics, the model matrix typically contains all the transformations required for mapping the object from it's own local model space to the world space. Even if you need to track separate parts of the transformation internally, you typically don't need these during actual rendering on the gpu, and should multiply all of these together on the CPU, and just send the accumulated transformation as the model matrix to the shader.
I am trying to render 3d scene to a cubemap but the cubemap only renders the skybox, here is my RenderToCubemap function:
GLuint RenderToCubemap(glm::vec3 position, float resolution, float nearPlane, float farPlane)
{
unsigned int CM_FBO;
unsigned int textureID;
glGenFramebuffers(1, &CM_FBO);
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
for (unsigned int i = 0; i < 6; i++)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, resolution, resolution, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
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);
// attach depth texture as FBO's depth buffer
glBindFramebuffer(GL_FRAMEBUFFER, CM_FBO);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureID, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glm::mat4 shadowProj = glm::perspective(glm::radians(90.0f), (float)resolution / (float)resolution, nearPlane, farPlane);
std::vector<glm::mat4> shadowTransforms;
shadowTransforms.push_back(shadowProj * glm::lookAt(position, position + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(position, position + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(position, position + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(position, position + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(position, position + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(position, position + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
// Render scene to cubemap
// --------------------------------
glViewport(0, 0, (int)resolution, (int)resolution);
glBindFramebuffer(GL_FRAMEBUFFER, CM_FBO);
Camera capture_cam;
capture_cam.temp_cam = true;
capture_cam.projectionMatrix = shadowProj;
capture_cam.transform.Position = position;
for (size_t i = 0; i < 6; i++)
{
capture_cam.viewMatrix = shadowTransforms[i];
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, textureID, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RenderScene(capture_cam);
}
return textureID;
}
RenderScene function :
void RenderScene(Camera& cam)
{
glm::mat4 proj = cam.GetProjectionMatrix();
glm::mat4 view = cam.GetViewMatrix();
glm::vec3 viewPos = cam.transform.Position;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Shader* shader = &materials.main_shader;
shader ->use();
shader ->SetMat4("projection", proj);
shader ->SetMat4("view", view);
shader ->SetVec3("CamPos", viewPos);
// Render all meshs
// ----------------------------------------------------
for (size_t i = 0; i < Meshs.size(); i++)
{
if (Meshs[i].Material == nullptr)
continue;
Meshs[i].Material->setShaderProperties(shader);
shader->SetMat4("model", Meshs[i].Transform);
Meshs[i]->Draw();
}
// render skybox
// ----------------------------------------------------
glDepthFunc(GL_LEQUAL); // change depth function so depth test passes when values are equal to depth buffer's content
Shader* bg = &materials.background;
bg->use();
bg->SetMat4("view", view);
bg->SetMat4("projection", proj);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, envCubemap);
renderCube();
glDepthFunc(GL_LESS); // set depth function back to default
}
I am using RenderScene for main rendering and it works, but when i use it in renderToCubemap it shows only the skybox.
Any help or correction?
I have replaced "shadowTransforms" with :
std::vector<glm::mat4> shadowTransforms;
shadowTransforms.push_back(glm::lookAt(position, position + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(glm::lookAt(position, position + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(glm::lookAt(position, position + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)));
shadowTransforms.push_back(glm::lookAt(position, position + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)));
shadowTransforms.push_back(glm::lookAt(position, position + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(glm::lookAt(position, position + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
Also I have added a depth buffer:
unsigned int m_CubemapDepthRBO;
glGenRenderbuffers(1, &m_CubemapDepthRBO);
glBindRenderbuffer(GL_RENDERBUFFER, m_CubemapDepthRBO);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, (int)resolution, (int)resolution);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_CubemapDepthRBO);
Now working properly, thank Nicole Polas and Rabbid76 for quick responses.
So far I've learned how to create a cube with textures in OpenGL.
Now I want to change this code for texturing a Quad. I've changed the vertices + indices from a cube to a quad.
And the Quad looks like this:
The texture is completely distorted and the upper triangle is missing...
This is the code I'm using:
1.
GLfloat vertices[] = {
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
unsigned int indices[]{
0,1,2,
1,2,3,
};
2.
for (size_t o = 0; o < 6; o++) {
glPixelStorei(GL_UNPACK_ROW_LENGTH, breite_komplett);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, ausschnitt_x_counter);
glPixelStorei(GL_UNPACK_SKIP_ROWS, ausschnitt_y_counter);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(
GL_TEXTURE_CUBE_MAP_POSITIVE_X + o, 0, GL_RGBA, ausschnitt_breite, ausschnitt_höhe, 0, GL_RGBA, GL_UNSIGNED_BYTE, sprite_image.getPixelsPtr());
}
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
glEnable(GL_TEXTURE_2D);
Do you have an ideas what I need to change?
Edit:
unsigned int indices[]{
0,1,2,
0,2,3
};
This is my object builder:
glGenVertexArrays(1, &obj_vao);
glBindVertexArray(obj_vao);
glGenBuffers(1, &obj_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, obj_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies[0])* indicies_count, indicies, GL_STATIC_DRAW);
glGenBuffers(1, &obj_vbo);
glBindBuffer(GL_ARRAY_BUFFER, obj_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * count_vertices, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 5, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 5, (void*)(sizeof(vertices[0]) * 3));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Edit:
If the vertices would be like this:
GLfloat vertices[] = {
1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f,
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f
};
Everything would be fine and the Quad looks like this:
But I need the Quad in the origin like this:
GLfloat vertices[] = {
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
With this vertices the texture is distorted...
The indices of the 2 triangle primitives do not form a quad. The indices have to be:
unsigned int indices[]{ 0, 1, 2, 1, 2, 3 };
unsigned int indices[]{ 0, 1, 2, 0, 2, 3 };
3 0
+-----+ +
| / / |
| / / |
+ +-----+
2 1
When you crate the texture, the you mix GL_TEXTURE_CUBE_MAP and GL_TEXTURE_2D. That makes no sense. Either create a cubemap texture and set the parameters for the GL_TEXTURE_CUBE_MAP or create a 2 dimensional texture.
Anyway if you want to create a cubemap texture, then you have to use GL_TEXTURE_CUBE_MAP, when you set the parameters, too.
The texture coordinate for a texture cube is a 3 dimensional vector. Change the vertex coordinates for the side of the cube. e.g:
(You don't need the texture coordinates at all)
GLfloat vertices[] = {
// x y z
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f
};
The center of the cube is (0, 0, 0), so you can use the vertex coordinates for the texture, too:
Vertex shader
in vec3 position;
out vec3 cubeCoord;
void main()
{
cubeCoord = position;
// [...]
}
Fragment shader:
in vec3 cubeCoord;
uniform samplerCube cubeTex;
void main()
{
vec4 color = texture(cubeTex, cubeCoord);
// [...]
}
Alternatively you can use separate 3 dimensional texture coordinates for the cubemap texture:
GLfloat vertices[] = {
// x y z u v w
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 0.0f, -1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 1.0f,
};
I'm attempting to implement a skybox in a game. The image I am using is:
Unfortunately, it is extremely magnified, only showing a few of the pixels of the texture. It looks like this:
here's my code for creating the skybox:
SkyBox::SkyBox()
{
programID = LoadShaders("Resources/Shaders/skybox.vert", "Resources/Shaders/skybox.frag");
pID = glGetUniformLocation(programID, "P");
vID = glGetUniformLocation(programID, "V");
float points[] =
{
-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
};
glGenBuffers (1, &vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glBufferData (GL_ARRAY_BUFFER, sizeof (points), points, GL_STATIC_DRAW);
const char *pth = "/Users/uonibr/Documents/Programming/Space Shooter/Space Shooter/Space Shooter/Resources/space.jpg";
createCubeMap(pth, pth, pth, pth, pth, pth);
}
bool load_cube_map_side (GLuint texture, GLenum side_target, const char* file_name)
{
glBindTexture (GL_TEXTURE_CUBE_MAP, texture);
int x, y;
unsigned char* image_data = SOIL_load_image(file_name, &x, &y, 0, SOIL_LOAD_RGBA);
if (!image_data) {
fprintf (stderr, "ERROR: could not load %s\n", file_name);
return false;
}
// non-power-of-2 dimensions check
if ((x & (x - 1)) != 0 || (y & (y - 1)) != 0) {
fprintf (
stderr, "WARNING: image %s is not power-of-2 dimensions\n", file_name
);
}
// copy image data into 'target' side of cube map
glTexImage2D (
side_target,
0,
GL_RGBA,
x,
y,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
image_data
);
free (image_data);
return true;
}
void SkyBox::createCubeMap ( const char* front, const char* back, const char* top, const char* bottom, const char* left,const char* right)
{
// generate a cube-map texture to hold all the sides
glActiveTexture (GL_TEXTURE0);
glGenTextures (1, &cubeMap);
// load each image and copy into a side of the cube-map texture
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, front));
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, back));
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, top));
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, bottom));
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, left));
assert(load_cube_map_side (cubeMap, GL_TEXTURE_CUBE_MAP_POSITIVE_X, right));
// format cube map texture
glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
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);
}
and here's the rendering code for the skybox:
void SkyBox::render(const Camera &camera) const
{
glDepthMask (GL_FALSE);
glUseProgram (programID);
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_CUBE_MAP, cubeMap);
glUniformMatrix4fv(pID, 1, GL_FALSE, &camera.getProjectionMatrix()[0][0]);
glm::mat4 view = camera.getRotationMatrix();
glUniformMatrix4fv(vID, 1, GL_FALSE, &view[0][0]);
glEnableVertexAttribArray (0);
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(
0, // attribute. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glDrawArrays (GL_TRIANGLES, 0, 36);
glDisableVertexAttribArray(0);
glDepthMask (GL_TRUE);
glCullFace(GL_BACK);
}
the fragment shader is simple:
#version 330 core
in vec3 texcoords;
uniform samplerCube cube_texture;
out vec4 frag_color;
void main () {
frag_color = texture (cube_texture, texcoords);
}
as is the vertex shader:
#version 330 core
in vec3 vp;
uniform mat4 P, V;
out vec3 texcoords;
void main () {
texcoords = vp;
gl_Position = P * V * vec4 (vp, 1.0);
}
EDIT:
here's my code for producing the projection matrix:
glm::mat4 Camera::getProjectionMatrix() const
{
return glm::perspective(FoV, 4.0f / 3.0f, 0.1f, 100.0f);
}
and here is my FoV:
float FoV = 3.14159 * 65. / 180;
I determined the issue:
I was passing radians into the glm::perspective() function when I should have passed degrees. Therefore, as was commented on the question, the answer was a small FoV