Got weird lighting result based on Phong model after learning LearnOpenGL chapter 13 - c++

First incorrect result
Hello guys, I've been studying OpenGL on learnopengl.com and I found the result weird when I finished learning the basic lighting chapter. The result is I found specular light on the corner of the cube surface where the light could not reach. The strange result is shown in pictures below:
Even if the camera is hidden behind the cube from the light, the strange specular light still remains:
My vertex shader is:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
out vec3 FragPos;
out vec3 Normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform mat3 normalMatrix;
void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = normalMatrix * aNormal;
// Normal = aNormal;
gl_Position = projection * view * vec4(FragPos, 1.0);
}
My fragment shader is (the same as the official code provided by LearnOpenGL):
#version 330 core
out vec4 FragColor;
in vec3 Normal;
in vec3 FragPos;
uniform vec3 lightPos;
uniform vec3 viewPos;
uniform vec3 lightColor;
uniform vec3 objectColor;
void main()
{
// ambient
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
// diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
// specular
float specularStrength = 0.5;
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * lightColor;
vec3 result = (ambient + diffuse + specular) * objectColor;
FragColor = vec4(result, 1.0);
}
My source file is:
#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/shader_m.h"
#include <cmath>
#define STB_IMAGE_IMPLEMENTATION
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);
// 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
// lighting
glm::vec3 lightPos(1.2f, 1.0f, 2.0f);
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, "LearnOpenGL", NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
// glad: load all OpenGL function pointers
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// cursor
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
// shader declaration
Shader ourShader("../src/shaders/shader.vs", "../src/shaders/shader.fs");
Shader lightingShader("../src/shaders/lightsource_shader.vs", "../src/shaders/lightsource_shader.fs");
// set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------
float vertices[] = {
-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
};
// first, configure the cube's VAO (and VBO)
unsigned int VBO, cubeVAO;
glGenVertexArrays(1, &cubeVAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindVertexArray(cubeVAO);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *) 0);
glEnableVertexAttribArray(0);
// normal attribute
glVertexAttribPointer(1,3,GL_FLOAT, GL_FALSE, 6*sizeof(float),(void*)0);
glEnableVertexAttribArray(1);
//second, configure the light's VAO (VBO stays the same; the vertices are the same for the light object which is also a 3D cube)
unsigned int lightCubeVAO;
glGenVertexArrays(1, &lightCubeVAO);
glBindVertexArray(lightCubeVAO);
// we only need to bind to the VBo (to link it with glVertexAtrribPointer), no need to fill it; the VBO's data already contains all we need (it's already bound, but we do it again for educational purposes)
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *) 0);
glEnableVertexAttribArray(0);
glEnable(GL_DEPTH_TEST);
// render loop
// -----------
while (!glfwWindowShouldClose(window)) {
// per-frame time logic
// --------------------
float currentFrame = static_cast<float>(glfwGetTime());
deltaTime = glfwGetTime() - lastFrame;
lastFrame = glfwGetTime();
// input
// -----
processInput(window);
// render
// ------
// firstly clear the screen
glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// activate shader
ourShader.use();
ourShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f);
ourShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
ourShader.setVec3("lightPos", lightPos);
ourShader.setVec3("viewPos", camera.Position);
// view/projection transformations
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float) SCR_WIDTH / (float) SCR_HEIGHT, 0.1f,100.0f);
glm::mat4 view = camera.GetViewMatrix();
ourShader.setMat4("projection", projection);
ourShader.setMat4("view", view);
// model transformation (aka world transformation)
glm::mat4 model = glm::mat4(1.0f);
ourShader.setMat4("model", model);
glm::mat3 normal_matrix = glm::transpose(glm::inverse(glm::mat3(model)));
// glm::mat3 normal_matrix = glm::mat3(glm::transpose(glm::inverse(model)));
ourShader.setMat3("normalMatrix", normal_matrix);
// render the cube
glBindVertexArray(cubeVAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
// also draw the lamp object
lightingShader.use();
lightingShader.setMat4("projection", projection);
lightingShader.setMat4("view", view);
model = glm::mat4(1.0f);
model = glm::translate(model, lightPos);
model = glm::scale(model, glm::vec3(0.1f));
lightingShader.setMat4("model", model);
glBindVertexArray(cubeVAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// optional: de-allocate all resources once they've outlived their purpose:
// ------------------------------------------------------------------------
glDeleteVertexArrays(1, &cubeVAO);
glDeleteVertexArrays(1, &lightCubeVAO);
glDeleteBuffers(1, &VBO);
// 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);
std::cout<<"cameraPos"<<camera.Position.x<<","<<camera.Position.y<<","<<camera.Position.z<<std::endl;
}
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) {
camera.ProcessMouseScroll(static_cast<float>(yoffset));
}
Other solutions I tried but didn't work
Furthermore, if I just use the specular result to generate the FragColor, the result would be like this:
in this case, my fragment shader is:
#version 330 core
out vec4 FragColor;
in vec3 Normal;
in vec3 FragPos;
uniform vec3 lightPos;
uniform vec3 viewPos;
uniform vec3 lightColor;
uniform vec3 objectColor;
void main()
{
// ambient
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
// diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
// specular
float specularStrength = 0.5;
vec3 viewDir = normalize(viewPos - FragPos);
float NdotL = dot(norm, lightDir);
vec3 specular = vec3(0.0);
if(NdotL > 0.0)
{
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
specular = specularStrength * spec * lightColor;
}
vec3 result = (ambient + diffuse + specular) * objectColor;
FragColor = vec4(result, 1.0);
}
The code above is inspired by the solution on OpenGL Phong lighting: specular highlight is wrong, but this solution turned out the above result.

You didn't set the offset for the normal vector attribute. The offset of the normal vector is 3*sizeof(float)
glVertexAttribPointer(1,3,GL_FLOAT, GL_FALSE, 6*sizeof(float),(void*)0);
glVertexAttribPointer(1,3,GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)(3*sizeof(float)));

Related

OpenGL - How to properly add lighting to a scene using the Blinn-Phong shading model?

Recently, I have been trying to add lighting to a simple OpenGL scene using the Blinn-Phong shading model as described in this website.
I tried to follow the tutorial as closely as possible. However, the lighting seems off, especially on the side faces of the cube as the light source begins to move across the front.
I believe it would have something to do with the positions of the Normals not being in the right place due to rotation on the model matrix or having done something wrong in the lighting shader, however, I am not sure whether either of those is really the cause.
Here is the source code, by the way:
#include <glad/glad.h>
#include <SFML/Graphics.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <cstdlib>
#include <cmath>
// Vertex shader for the light source cube
const std::string source_vert_shader = R"(
#version 330 core
layout (location = 0) in vec3 vertPos;
uniform mat4 proj, view, model;
void main() {
gl_Position = proj * view * model * vec4(vertPos, 1);
}
)";
// Fragment shader for the light source cube
const std::string source_frag_shader = R"(
#version 330 core
out vec4 FragColor;
void main() {
FragColor = vec4(1);
}
)";
// Vertex shader for the cube
const std::string cube_vert_shader = R"(
#version 330 core
layout (location = 0) in vec3 vertPos;
layout (location = 1) in vec3 vertNorm;
uniform mat4 proj, view, model;
out vec3 fragPos;
out vec3 interNorm;
void main() {
fragPos = vec3(model * vec4(vertPos, 1));
gl_Position = proj * view * vec4(fragPos, 1);
interNorm = mat3(transpose(inverse(model))) * vertNorm;
}
)";
// Fragment shader for the cube
const std::string cube_frag_shader = R"(
#version 330 core
in vec3 fragPos;
in vec3 interNorm;
out vec4 FragColor;
uniform vec3 viewPos;
uniform vec3 lightPos;
uniform vec3 objectColor;
const float pi = 3.14159265;
const float shininess = 16;
void main() {
vec3 normal = normalize(interNorm);
vec3 lightDir = normalize(lightPos - fragPos);
float dist = length(lightPos - fragPos);
float attenuation = 1 / (dist * dist);
// Ambient light effect
const float ambientStrength = 0.05;
vec3 ambient = ambientStrength * objectColor;
// Diffuse light effect
float diff = max(dot(normal, lightDir), 0);
vec3 diffuse = attenuation * diff * objectColor;
// Specular light effect
vec3 specular = vec3(0);
if (diff != 0) {
const float energy_conservation = (8 + shininess) / (8 * pi);
vec3 viewDir = normalize(viewPos - fragPos);
vec3 halfwayDir = normalize(lightDir + viewDir);
float spec = energy_conservation * pow(max(dot(normal, halfwayDir), 0), shininess);
specular = attenuation * spec * vec3(0.3);
}
const float gamma = 2.2;
// Apply the different lighting techniques of the Phong shading model and finally apply gamma correction
FragColor = vec4(pow(ambient + diffuse + specular, vec3(1 / gamma)), 1);
}
)";
int main() {
// Initialize the window
sf::RenderWindow window(
sf::VideoMode(1365, 768), "Lighting", sf::Style::Default,
sf::ContextSettings(24, 8, 4, 3, 3, sf::ContextSettings::Core, true));
// Initialize OpenGL functions
gladLoadGLLoader(reinterpret_cast<GLADloadproc>(sf::Context::getFunction));
// Specify the viewport of the scene
glViewport(0, 0, window.getSize().x, window.getSize().y);
// Enable depth testing
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// Enable blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Load the shaders into the application
sf::Shader shader, source_shader;
(void)shader.loadFromMemory(cube_vert_shader, cube_frag_shader);
(void)source_shader.loadFromMemory(source_vert_shader, source_frag_shader);
// Define the vertices of the cube and the light source cube
float vertices[] = {
// Vertices 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
};
// Attach the vertices in the vertices array to the VAO and the VBO
GLuint vao, vbo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), nullptr);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void*>(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// The same VBO can be used to render the light source cube
GLuint source_vao;
glGenVertexArrays(1, &source_vao);
glBindVertexArray(source_vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), nullptr);
glEnableVertexAttribArray(0);
// Projection matrix
auto proj = glm::perspective(glm::radians(45.0f), static_cast<GLfloat>(window.getSize().x) / window.getSize().y, 0.1f, 100.0f);
glm::vec3 view_pos(0.0f, 0.0f, -5.0f);
// View/camera matrix
glm::mat4 view(1.0f);
view = glm::translate(view, view_pos);
view = glm::rotate(view, glm::radians(45.0f), glm::vec3(1.0f, 1.0f, 1.0f));
// Model matrix
glm::mat4 model(1.0f);
//model = glm::rotate(model, glm::radians(45.0f), glm::vec3(1.0f, 1.0f, 0.0f));
// For the cube in the center
shader.setUniform("proj", sf::Glsl::Mat4(glm::value_ptr(proj)));
shader.setUniform("view", sf::Glsl::Mat4(glm::value_ptr(view)));
shader.setUniform("model", sf::Glsl::Mat4(glm::value_ptr(model)));
shader.setUniform("viewPos", sf::Glsl::Vec3(view_pos.x, view_pos.y, view_pos.z));
shader.setUniform("objectColor", sf::Glsl::Vec3(1.0f, 0.3f, 1.0f));
// For the light source cube
source_shader.setUniform("proj", sf::Glsl::Mat4(glm::value_ptr(proj)));
source_shader.setUniform("view", sf::Glsl::Mat4(glm::value_ptr(view)));
sf::Clock clock;
sf::Event evt{};
while (window.isOpen()) {
while (window.pollEvent(evt)) {
if (evt.type == sf::Event::Closed) {
// When window is closed, destroy the VAO and the VBO
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
window.close();
}
if (evt.type == sf::Event::Resized)
// Update the viewport as the window is resized
glViewport(0, 0, evt.size.width, evt.size.height);
}
// Clear the screen with a color
glClearColor(0.8f, 0.2f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Calculate an angular factor based on the elapsed time
auto const angular_factor = glm::radians(45.0f) * clock.getElapsedTime().asSeconds();
sf::Shader::bind(&shader);
// Makes the light source move in circles around the cube in the center
glm::vec3 light_pos(
6.0f * std::sin(angular_factor),
0.0f,
6.0f * std::cos(angular_factor)
);
shader.setUniform("lightPos", sf::Glsl::Vec3(light_pos.x, light_pos.y, light_pos.z));
// Draw the cube
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 36);
sf::Shader::bind(&source_shader);
model = glm::identity<glm::mat4>();
model = glm::scale(model, glm::vec3(0.3f, 0.3f, 0.3f));
model = glm::translate(model, light_pos);
source_shader.setUniform("model", sf::Glsl::Mat4(glm::value_ptr(model)));
// Draw the light source cube
glBindVertexArray(source_vao);
glDrawArrays(GL_TRIANGLES, 0, 36);
sf::Shader::bind(nullptr);
// Swap the window's buffers
window.display();
}
}

OPENGL Showing white box instead of moveable cube

Need help with this problem on opengl. It will compile but wont do anything other than create a white box instead of the cube it should be. I finally got my compiler working properly but now this is happening and am unsure what I am doing wrong. Should rotate around and be a multicolor cube.
#include <Windows.h>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
using namespace std;
#define GLSL(Version, Source) "#version " #Version "\n" #Source
#define WINDOW_TITLE "5-1 Practice Activity 6"
GLint shaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, VAO;
GLfloat cameraSpeed = 0.0005f;
GLchar currentKey;
int keymod;
GLfloat scale_by_y = 2.0f;
GLfloat scale_by_z = 2.0f;
GLfloat scale_by_x = 2.0f;
GLfloat lastMouseX = 400, lastMouseY = 300;
GLfloat mouseXoffset, mouseYoffset, yaw = 0.0f, pitch = 0.0f;
GLfloat sensitivity = 0.1f;
bool mouseDetected = true;
bool rotate = false;
bool checkMotion = false;
bool checkZoom = false;
glm::vec3 CameraPosition = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 CameraUpY = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 CameraForwardZ = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 front;
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
void UMouseMove(int x, int y);
void OnMouseClick(int button, int state, int x, int y);
void onMotion(int x, int y);
const GLchar* vertexShaderSource = "#version 400 core\n"
"layout (location = 0) in vec3 position;"
"layout (location = 1) in vec3 color;"
"out vec3 mobileColor;"
"uniform mat4 model;"
"uniform mat4 view;"
"uniform mat4 projection;"
"{\n"
"gl_Position = projection * view * model * vec4(position, 1.0f);"
"mobileColor = color;"
"}\n";
const GLchar* fragmentShaderSource = "#version 400 core\n"
"in vec3 mobileColor;"
"out vec4 gpuColor;"
"void main()\n"
"{\n"
"gpuColor = vec4(mobileColor, 1.0);"
"}\n";
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WindowWidth, WindowHeight);
glutCreateWindow(WINDOW_TITLE);
glutReshapeFunc(UResizeWindow);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
UCreateShader();
UCreateBuffers();
glUseProgram(shaderProgram);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glutDisplayFunc(URenderGraphics);
glutPassiveMotionFunc(UMouseMove);
glutMotionFunc(onMotion);
glutMouseFunc(OnMouseClick);
glutMainLoop();
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
return 0;
}
void UResizeWindow(int w, int h) {
WindowWidth = w;
WindowHeight = h;
glViewport(0, 0, WindowWidth, WindowHeight);
}
void URenderGraphics(void) {
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(VAO);
CameraForwardZ = front;
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
model = glm::rotate(model, 45.0f, glm::vec3(0.0f, 1.0f, 0.0f));
model = glm::scale(model, glm::vec3(scale_by_x, scale_by_y, scale_by_z));
glm::mat4 view;
view = glm::lookAt(CameraForwardZ, CameraPosition, CameraUpY);
glm::mat4 projection;
projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
GLint projLoc = glGetUniformLocation(shaderProgram, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glutSwapBuffers();
}
void UCreateShader() {
GLint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
glCompileShader(vertexShader);
GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
void UCreateBuffers() {
GLfloat vertices[] = {
-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.5, 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, 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, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f//pot here?
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Active the Element Buffer Object / Indices
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)nullptr);
glEnableVertexAttribArray(0); // Enables vertex attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1); // Enables vertex attribute
glBindVertexArray(0); //Deactivates the VAO which is good
}
void UMouseMove(int x, int y) {
front.x = 10.0f * cos(yaw);
front.y = 10.0f * sin(pitch);
front.z = sin(yaw) * cos(pitch) * 10.0f;
}
void onMotion(int curr_x, int curr_y) {
if (checkMotion) {
mouseXoffset = curr_x - lastMouseX;
mouseYoffset = lastMouseY - curr_y;
lastMouseX = curr_x;
lastMouseY = curr_y;
mouseXoffset *= sensitivity;
mouseYoffset *= sensitivity;
if (yaw != yaw + mouseXoffset && pitch == pitch + mouseYoffset) {
yaw += mouseXoffset;
}
else if (pitch != pitch + mouseYoffset && yaw == yaw + mouseXoffset) {
pitch += mouseYoffset;
}
front.x = 10.0f * cos(yaw);
front.y = 10.0f * sin(pitch);
front.z = sin(yaw) * cos(pitch) * 10.0f;
}
if (checkZoom) {
if (lastMouseY > curr_y) {
scale_by_y += 0.1f;
scale_by_x += 0.1f;
scale_by_z += 0.1f;
glutPostRedisplay();
}
else {
scale_by_y -= 0.1f;
scale_by_x -= 0.1f;
scale_by_z -= 0.1f;
if (scale_by_y < 0.2f) {
scale_by_y = 0.2f;
scale_by_x = 0.2f;
scale_by_z = 0.2f;
}
glutPostRedisplay();
}
lastMouseY = curr_y;
lastMouseX = curr_x;
}
}
void OnMouseClick(int button, int state, int x, int y) {
keymod = glutGetModifiers();
checkMotion = false;
if (button == GLUT_LEFT_BUTTON && keymod == GLUT_ACTIVE_ALT && state == GLUT_DOWN) {
checkMotion = true;
checkZoom = false;
}
else if (button == GLUT_RIGHT_BUTTON && keymod == GLUT_ACTIVE_ALT && state == GLUT_DOWN) {
checkMotion = false;
checkZoom = true;
}
}
Ive gone through line by line but for the life of me I cannot figure it out any help would be much appreicated!
The vertex shader does not compile, because there is missing a line:
const GLchar* vertexShaderSource = "#version 400 core\n"
"layout (location = 0) in vec3 position;"
"layout (location = 1) in vec3 color;"
"out vec3 mobileColor;"
"uniform mat4 model;"
"uniform mat4 view;"
"uniform mat4 projection;"
"void main()\n" // <--- MISSING
"{\n"
"gl_Position = projection * view * model * vec4(position, 1.0f);"
"mobileColor = color;"
"}\n";
I recommend to check if the shader compilation succeeded and if the program object linked successfully.
If the compiling of a shader succeeded can be checked by glGetShaderiv and the parameter GL_COMPILE_STATUS. e.g.:
#include <iostream>
#include <vector>
bool CompileStatus( GLuint shader )
{
GLint status = GL_TRUE;
glGetShaderiv( shader, GL_COMPILE_STATUS, &status );
if (status == GL_FALSE)
{
GLint logLen;
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetShaderInfoLog( shader, logLen, &written, log.data() );
std::cout << "compile error:" << std::endl << log.data() << std::endl;
}
return status != GL_FALSE;
}
If the linking of a program was successful can be checked by glGetProgramiv and the parameter GL_LINK_STATUS. e.g.:
bool LinkStatus( GLuint program )
{
GLint status = GL_TRUE;
glGetProgramiv( program, GL_LINK_STATUS, &status );
if (status == GL_FALSE)
{
GLint logLen;
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetProgramInfoLog( program, logLen, &written, log.data() );
std::cout << "link error:" << std::endl << log.data() << std::endl;
}
return status != GL_FALSE;
}
Call CompileStatus and LinkStatus in UCreateShader:
void UCreateShader() {
GLint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
glCompileShader(vertexShader);
CompileStatus(vertexShader);
GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
glCompileShader(fragmentShader);
CompileStatus(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
LinkStatus(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}

modern opengl textured pyramid

I think am missing something when drawing the textured pyramid. I can't get it to work properly since I am not good with 3d modern OpenGL. Somehow, I managed to draw a cube but seems am going wrong with the pyramid. I want the four sides to have 0.5(top), 0.0(left), 1,0 (right). and the bottom to be 0,1 (top left), 1,1 (top right), 0,0 (bottom left) and 1,0 (bottom right). I need these coordinates since am only getting flunky images with my coordinate. Any help would be appreciated.
here is my code with the vertices of a cube that I had created earlier and was running well.
/*Header Inclusions*/
#include <iostream>
#include <GL/Glew.h>
#include <GL/freeglut.h>
// GLM Math inclusions
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>
//include soil
#include "SOIL2/SOIL2.h"
using namespace std; // Uses the standard namespace
#define WINDOW_TITLE "Modern OpenGL" // Macro for window title
//Vertex and fragment shader
#ifndef GLSL
#define GLSL(Version, source) "#version " #Version "\n" #source
#endif
// Variables for window width and height
GLint ShaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, VAO, texture;
GLfloat degrees = glm::radians(-45.0f);
/* User-defined Function prototypes to:*/
void UResizeWindow(int,int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
void UGenerateTexture(void);
/*Vertex shader source code*/
const GLchar * vertexShaderSource = GLSL(330,
layout(location = 0) in vec3 position;
layout(location = 2) in vec2 textureCoordinate;
out vec2 mobileTextureCoordinate; //declare a vec 4 variable
//Global variables for the transform matrices
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(){
gl_Position = projection * view * model * vec4(position, 1.0f);//transform vertices
mobileTextureCoordinate = vec2(textureCoordinate.x, 1.0f - textureCoordinate.y);
}
);
/*Fragment shader program source code*/
const GLchar * fragmentShaderSource = GLSL(330,
in vec2 mobileTextureCoordinate;
out vec4 gpuTexture;//out vertex_Color;
uniform sampler2D uTexture;
void main(){
gpuTexture = texture(uTexture, mobileTextureCoordinate);
}
);
//main program
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WindowWidth, WindowHeight);
glutCreateWindow(WINDOW_TITLE);
glutReshapeFunc(UResizeWindow);
glewExperimental = GL_TRUE;
if (glewInit()!= GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
UCreateShader();
UCreateBuffers();
UGenerateTexture();
// Use the Shader program
glUseProgram(ShaderProgram);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color
glutDisplayFunc(URenderGraphics);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
glutMainLoop();
// Destroys Buffer objects once used
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
return 0;
}
/* Resizes the window*/
void UResizeWindow(int w, int h)
{
WindowWidth = w;
WindowHeight = h;
glViewport(0, 0, WindowWidth, WindowHeight);
}
/* Renders graphics */
void URenderGraphics(void)
{
glEnable(GL_DEPTH_TEST); // Enable z-depth
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clears the screen
glBindVertexArray(VAO); // Activate the Vertex Array Object before rendering and transforming them
// Transforms the object
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0, 0.0f, 0.0f)); // Place the object at the center of the 7i,p9rA
model = glm::rotate(model, degrees, glm::vec3(0.0, 1.0f, 0.0f)); // Rotate the object 45 degrees on the XYZ
model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f)); // Increase the object size by a scale of 2
// Transforms the camera
glm::mat4 view;
view = glm::translate(view, glm::vec3(0.0f,0.0f,-5.0f)); //Moves the world 0.5 units on X and -5 units in Z
// Creates a perspective projection
glm::mat4 projection;
projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
// Retrieves and passes transform matrices to the Shader program
GLint modelLoc = glGetUniformLocation(ShaderProgram, "model");
GLint viewLoc = glGetUniformLocation(ShaderProgram, "view");
GLint projLoc = glGetUniformLocation(ShaderProgram, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
glBindTexture(GL_TEXTURE_2D, texture);
// Draws the triangles
glDrawArrays(GL_TRIANGLES,0, 36);
glBindVertexArray(0); // Deactivate the Vertex Array Object
glutSwapBuffers(); // Flips the the back buffer with the front buffer every frame. Similar to GL FLush
}
/*Creates the Shader program*/
void UCreateShader()
{
// Vertex shader
GLint vertexShader = glCreateShader(GL_VERTEX_SHADER); // Creates the Vertex Shader
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); // Attaches the Vertex Shader to the source code
glCompileShader(vertexShader); // Compiles the Vertex Shader
// Fragment Shader
GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Creates the Fragment Shader
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);// Attaches the Fragment Shader to the source code
glCompileShader(fragmentShader); // Compiles the Fragment Shader
// Shader program
ShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id
glAttachShader(ShaderProgram, vertexShader); // Attach Vertex Shader to the Shader program
glAttachShader(ShaderProgram, fragmentShader);; // Attach Fragment Shader to the Shader program
glLinkProgram(ShaderProgram); //Link Vertex and Fragment shader, to Shader program
// Delete the Vertex and Fragment shaders once linked
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
/*creates the buffer and array object*/
void UCreateBuffers()
{
//position and color data
GLfloat vertices[] = {
-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
};
//Generate buffer id,
glGenVertexArrays(1, &VAO);
glGenBuffers(1,&VBO);
// Activate the Vertex Array Object before binding and setting any VB0s and Vertex Attribute Pointers.
glBindVertexArray(VAO);
// Activate the VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //Copy vertices to VBO
// Set attribute pointer 0 to hold Position data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0); // Enables vertex attribute
// Set attribute pointer 2 to hold Color data
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(2); // Enables vertex attribute
glBindVertexArray(0); // Deactivates the VAC, which is good practice
}
/*Generate and load the texture*/
void UGenerateTexture(){
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
int width,height;
unsigned char* image = SOIL_load_image("snhu.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);
}
I recommend to define a structure type for the attribute tuples:
struct TAttributeTuple
{
glm::vec3 v;
glm::vec2 uv;
};
Define the 5 corner points of the pyramid:
(Your explanation of the points is a bit unclear, so I am not sure if the points are according to your specification. Possibly you've modify them.)
glm::vec3 top( 0.5f, 0.5f, 0.5f );
glm::vec3 p01( -0.1f, 0.0f, 1.0f );
glm::vec3 p11( 1.1f, 0.0f, 1.0f );
glm::vec3 p00( 0.0f, 0.0f, 0.0f );
glm::vec3 p10( 1.0f, 0.0f, 0.0f );
Setup the array of vertex attributes:
TAttributeTuple vertices[]
{
{ p00, glm::vec2(0.0f, 0.0f) },
{ p10, glm::vec2(1.0f, 0.0f) },
{ p11, glm::vec2(1.0f, 1.0f) },
{ p00, glm::vec2(0.0f, 0.0f) },
{ p11, glm::vec2(1.0f, 1.0f) },
{ p01, glm::vec2(0.0f, 1.0f) },
{ p00, glm::vec2(0.0f, 0.0f) },
{ p10, glm::vec2(1.0f, 0.0f) },
{ top, glm::vec2(0.5f, 1.0f) },
{ p10, glm::vec2(0.0f, 0.0f) },
{ p11, glm::vec2(1.0f, 0.0f) },
{ top, glm::vec2(0.5f, 1.0f) },
{ p11, glm::vec2(0.0f, 0.0f) },
{ p01, glm::vec2(1.0f, 0.0f) },
{ top, glm::vec2(0.5f, 1.0f) },
{ p01, glm::vec2(0.0f, 0.0f) },
{ p00, glm::vec2(1.0f, 0.0f) },
{ top, glm::vec2(0.5f, 1.0f) }
};

I wonder where am going wrong with the zooming and orbiting

I want to be able to pan, zoom, and orbit the cube. I would like to know why the cube appears fully zoomed on the screen such that I have to move backwards to view the whole cube. I would also like to change the zooming controls to alt and right mouse button for both zooming and orbiting but I cant get it to work. Any assistance would be appreciated.
/*/header inclusions*/
#include <iostream> // Includes C++ i/o stream
#include <GL/glew.h> // Includes glew header
#include <GL/freeglut.h> // Includes freeglut header
// GLM Math inclusions
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>
using namespace std; // Uses the standard namespace
#define WINDOW_TITLE "Modern OpenGL" // Macro for window title
//Vertex and fragment shader
#ifndef GLSL
#define GLSL(Version, source) "#version " #Version "\n" #source
#endif
// Variables for window width and height
GLint ShaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, VAO;
GLfloat cameraSpeed = 0.0005f;
GLchar currentKey;
GLfloat lastMouseX = 400, lastMouseY = 300;
GLfloat mouseXOffset, mouseYOffset, yaw = 0.0f, pitch = 0.0f;
GLfloat sensitivity = 0.5f;
bool mouseDetected = true;
//global vectors declaration
glm::vec3 cameraPosition = glm::vec3(0.0f,0.0f,0.0f);
glm::vec3 CameraUpY = glm::vec3(0.0f,1.0f,0.0f);
glm::vec3 CameraForwardZ = glm::vec3(0.0f,0.0f,-1.0f);
glm::vec3 front;
/* User-defined Function prototypes to:*/
void UResizeWindow(int,int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
void UKeyboard(unsigned char key, int x, int y);
void UKeyReleased(unsigned char key, int x, int y);
void UMouseMove(int x, int y);
/*Vertex shader source code*/
const GLchar * vertexShaderSource = GLSL(330,
layout(location=0) in vec3 position;
layout(location=1) in vec3 color;
out vec3 mobileColor; //declare a vec 4 variable
//Global variables for the transform matrices
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(){
gl_Position = projection * view * model * vec4(position, 1.0f);//transform vertices
mobileColor = color;
}
);
/*Fragment shader program source code*/
const GLchar * fragmentShaderSource = GLSL(330,
in vec3 mobileColor;
out vec4 gpuColor;//out vertex_Color;
void main(){
gpuColor = vec4 (mobileColor, 1.0);
}
);
//main program
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WindowWidth, WindowHeight);
glutCreateWindow(WINDOW_TITLE);
glutReshapeFunc(UResizeWindow);
glewExperimental = GL_TRUE;
if (glewInit()!= GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
UCreateShader();
UCreateBuffers();
// Use the Shader program
glUseProgram(ShaderProgram);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color
glutDisplayFunc(URenderGraphics);
glutKeyboardFunc(UKeyboard);
glutKeyboardUpFunc(UKeyReleased);
glutPassiveMotionFunc(UMouseMove);
glutMainLoop();
// Destroys Buffer objects once used
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
return 0;
}
/* Resizes the window*/
void UResizeWindow(int w, int h)
{
WindowWidth = w;
WindowHeight = h;
glViewport(0, 0, WindowWidth, WindowHeight);
}
/* Renders graphics */
void URenderGraphics(void)
{
glEnable(GL_DEPTH_TEST); // Enable z-depth
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clears the screen
glBindVertexArray(VAO); // Activate the Vertex Array Object before rendering and transforming them
//camera movement logic
if(currentKey == 'w')
cameraPosition += cameraSpeed * CameraForwardZ;
if(currentKey == 's')
cameraPosition -= cameraSpeed * CameraForwardZ;
if(currentKey == 'a')
cameraPosition -= glm::normalize(glm::cross(CameraForwardZ, CameraUpY)) * cameraSpeed;
if(currentKey == 'd')
cameraPosition += glm::normalize(glm::cross(CameraForwardZ, CameraUpY)) * cameraSpeed;
CameraForwardZ = front;
// Transforms the object
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0, 0.0f, 0.0f)); // Place the object at the center of the 7i,p9rA
model = glm::rotate(model, 45.0f, glm::vec3(1.0, 1.0f, 1.0f)); // Rotate the object 45 degrees on the XYZ
model = glm::scale(model, glm::vec3(1.0f, 1.0f, -1.0f)); // Increase the object size by a scale of 2
// Transforms the camera
glm::mat4 view;
view = glm::lookAt(cameraPosition, cameraPosition + CameraForwardZ, CameraUpY); //Moves the world 0.5 units on X and -5 units in Z
// Creates a perspective projection
glm::mat4 projection;
projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
// Retrieves and passes transform matrices to the Shader program
GLint modelLoc = glGetUniformLocation(ShaderProgram, "model");
GLint viewLoc = glGetUniformLocation(ShaderProgram, "view");
GLint projLoc = glGetUniformLocation(ShaderProgram, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
// Draws the triangles
glDrawArrays(GL_TRIANGLES,0, 36);
glBindVertexArray(0); // Deactivate the Vertex Array Object
glutSwapBuffers(); // Flips the the back buffer with the front buffer every frame. Similar to GL FLush
}
/*Creates the Shader program*/
void UCreateShader()
{
// Vertex shader
GLint vertexShader = glCreateShader(GL_VERTEX_SHADER); // Creates the Vertex Shader
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); // Attaches the Vertex Shader to the source code
glCompileShader(vertexShader); // Compiles the Vertex Shader
// Fragment Shader
GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Creates the Fragment Shader
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);// Attaches the Fragment Shader to the source code
glCompileShader(fragmentShader); // Compiles the Fragment Shader
// Shader program
ShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id
glAttachShader(ShaderProgram, vertexShader); // Attach Vertex Shader to the Shader program
glAttachShader(ShaderProgram, fragmentShader);; // Attach Fragment Shader to the Shader program
glLinkProgram(ShaderProgram); //Link Vertex and Fragment shader, to Shader program
// Delete the Vertex and Fragment shaders once linked
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
/*creates the buffer and array object*/
void UCreateBuffers()
{
//position and color data
GLfloat vertices[] = {
//vertex positions and colors
-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, 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, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f,
};
//Generate buffer id,
glGenVertexArrays(1, &VAO);
glGenBuffers(1,&VBO);
// Activate the Vertex Array Object before binding and setting any VB0s and Vertex Attribute Pointers.
glBindVertexArray(VAO);
// Activate the VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //Copy vertices to VBO
// Set attribute pointer 0 to hold Position data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0); // Enables vertex attribute
// Set attribute pointer 1 to hold Color data
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1); // Enables vertex attribute
glBindVertexArray(0); // Deactivates the VAC, which is good practice
}
//implement the UKeyboard function
void UKeyboard(unsigned char key, GLint x, GLint y)
{
switch(key){
case 'w':
currentKey = key;
cout<<"You Pressed W"<<endl;
break;
case 's':
currentKey = key;
cout<<"You Pressed S"<<endl;
break;
case 'a':
currentKey = key;
cout<<"You Pressed A"<<endl;
break;
case 'd':
currentKey = key;
cout<<"You Pressed D"<<endl;
break;
default:
cout<<"Press a key!"<<endl;
}
}
//implement the UKeyReleased function
void UKeyReleased(unsigned char key, GLint x, GLint y)
{
cout<<"Key Released!"<<endl;
currentKey = '0';
}
//implement UMouseMove function
void UMouseMove(int x, int y)
{
if(mouseDetected)
{
lastMouseX = x;
lastMouseY = y;
mouseDetected = false;
}
//get the direction mouse was moved
mouseXOffset = x - lastMouseX;
mouseYOffset = lastMouseY - y;
//update new coordinates
lastMouseX = x;
lastMouseY = y;
//apply sensitivity
mouseXOffset *= sensitivity;
mouseYOffset *= sensitivity;
//accumulate yaw and pitch
yaw += mouseXOffset;
pitch += mouseYOffset;
//maintain 90 degree pitch
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch > -89.0f)
pitch = -89.0f;
//convert mouse coordinates
front.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw));
front.y = sin(glm::radians(pitch));
front.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw));
}
Start at a camera position, which is translated along the positiv z axis (e.g. (0, 0, 10)). front has to be initialized:
glm::vec3 cameraPosition = glm::vec3(0.0f,0.0f,10.0f);
glm::vec3 CameraUpY = glm::vec3(0.0f,1.0f,0.0f);
glm::vec3 CameraForwardZ = glm::vec3(0.0f,0.0f,-1.0f);
glm::vec3 front = glm::vec3(0.0f,0.0f,-1.0f);
You have to initialize the model matrix variable glm::mat4 model.
The glm API documentation refers to The OpenGL Shading Language specification 4.20.
5.4.2 Vector and Matrix Constructors
If there is a single scalar parameter to a vector constructor, it is used to initialize all components of the constructed vector to that scalar’s value. If there is a single scalar parameter to a matrix constructor, it is used to initialize all the components on the matrix’s diagonal, with the remaining components initialized to 0.0.
This means, that an Identity matrix can be initialized by the single parameter 1.0:
glm::mat4 model(1.0f);
The unit of the angles in OpenGL Mathematics is radian rather than degree. (glm::perspective, glm::rotate):
// Transforms the object
glm::mat4 model(1.0f);
model = glm::translate(model, glm::vec3(0.0, 0.0f, 0.0f)); // Place the object at the center of the 7i,p9rA
model = glm::rotate(model, glm::radians(45.0f), glm::vec3(1.0, 1.0f, 1.0f)); // Rotate the object 45 degrees on the XYZ
model = glm::scale(model, glm::vec3(1.0f, 1.0f, -1.0f)); // Increase the object size by a scale of 2
// Transforms the camera
glm::mat4 view = glm::lookAt(cameraPosition, cameraPosition + CameraForwardZ, CameraUpY); //Moves the world 0.5 units on X and -5 units in Z
// Creates a perspective projection
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
There are some mistakes when front is calculated. pitch < -89.0f rather than pitch > -89.0f. The x axis is sin(glm::radians(yaw)) and the z axis is -cos(glm::radians(yaw)):
//maintain 90 degree pitch
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
//convert mouse coordinates
front.x = cos(glm::radians(pitch)) * sin(glm::radians(yaw));
front.y = sin(glm::radians(pitch));
front.z = cos(glm::radians(pitch)) * -cos(glm::radians(yaw));
Furthermore, the sensitivity seams to be to strong, I recommend to reduce it (e.g. GLfloat sensitivity = 0.05f;).

OpenGL not rendering colors

For some reason the colors are not rendering when I run my program. With the addition of glm, I have been running into issues with some strange images rendering on run. It might be a library, but it is highly doubtful. I have checked and rechecked my includes and libraries. I am using Eclipse.
Here is my code
/*
* Module5.cpp
*
* Created on: Aug 21, 2017
* Author:
*/
#include <iostream>
#include <Gl/glew.h>
#include <GL/freeglut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
using namespace std;
#define WINDOW_TITLE "Window"
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version "\n" #Source
#endif
GLint shaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, VAO; //Global variables for Buffer Object etc.
GLfloat cameraSpeed = 0.0005f;
GLchar currentKey; //will store key pressed
glm::vec3 cameraPosition = glm::vec3(0.0f, 0.0f, 5.0f);
glm::vec3 CameraUpY = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 CameraForwardZ = glm::vec3(0.0f, 0.0f, -1.0f);
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
void UKeyboard(unsigned char key, int x, int y);
void UKeyReleased(unsigned char key, int x, int y);
const GLchar * vertexShaderSource = GLSL(330,
layout(location=0) in vec3 position; //incoming data
layout(location=1) in vec3 color;
out vec4 mobileColor; //Attrib pointer 0
//out vec4 colorFromVShader;
//uniform mat4 primitiveTransform; //transform for shape
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
//gl_Position = primitiveTransform * vertex_Position; //move object on y-axis .5
gl_Position = projection * view * model * vec4(position, 1.0f); //move object on y-axis .5
//colorFromVShader = colorFromVBO;
mobileColor = color;
}
);
const GLchar * fragmentShaderSource = GLSL(440,
in vec3 mobileColor;
out vec4 gpuColor;
void main(){
// gl_FragColor= vec4(1.0, 0.5, 0.0, 1.0);
gpuColor= vec4(mobileColor, 1.0);
}
);
//Main
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WindowWidth, WindowHeight);
glutCreateWindow(WINDOW_TITLE);
glutReshapeFunc(UResizeWindow);
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK)
{
cout << "Failed to initialize glew!" << endl;
return -1;
}
UCreateShader();
UCreateBuffers();
glUseProgram(shaderProgram);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glutDisplayFunc(URenderGraphics);
glutKeyboardFunc(UKeyboard);
glutKeyboardUpFunc(UKeyReleased);
glutMainLoop();
glDeleteVertexArrays(1, &VAO);//cleanup
glDeleteBuffers(1, &VBO);//cleanup
return 0;
}
void UResizeWindow(int w, int h)
{
WindowWidth = w;
WindowHeight = h;
glViewport(0, 0, WindowWidth, WindowHeight);
}
void URenderGraphics(void)
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//clears screen
glBindVertexArray(VAO); //activate vertex array to render the vertices that render our shape
if(currentKey == 'w')
cameraPosition += cameraSpeed * CameraForwardZ;
if(currentKey == 's')
cameraPosition -= cameraSpeed * CameraForwardZ;
if(currentKey == 'a')
cameraPosition -= cameraSpeed * CameraForwardZ;
if(currentKey == 'd')
cameraPosition += cameraSpeed * CameraForwardZ;
glm::mat4 model;
model = glm::translate(model,glm::vec3(0.0f, 0.0f, 0.0));
model = glm::rotate(model, glm::radians(-45.0f), glm::vec3(0.0f, 1.0f, 0.0f)); //rotate shape x-axis by 1.0f
model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f)); //scale shape
glm::mat4 view; //camera
view = glm::lookAt(cameraPosition, cameraPosition + CameraForwardZ, CameraUpY); //move camera back by 5 (z)
glm::mat4 projection;
projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
//projection = glm::ortho(-5.0f, 5.0f, -5.0f, 5.0f, 0.1f, 100.0f);
GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
GLint projLoc = glGetUniformLocation(shaderProgram, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
//apply projection matrix
/*
glm::mat4 newTransform; //references 4 x 4 matrix
newTransform = glm::translate(newTransform, glm::vec3(0.0f, 0.5f, 0.0)); //make square move up y-axis
newTransform = glm::rotate(newTransform, glm::radians(45.0f), glm::vec3(0.0f, 0.0f, 1.0f)); //rotate shape
//newTransform = glm::scale(newTransform, glm::vec3(0.5f, 0.5f, 0.5f)); //rotate shape
GLuint transformInfo = glGetUniformLocation(ProgramId, "primitiveTransform"); //id for shader, name of variable shader
glUniformMatrix4fv(transformInfo, 1, GL_FALSE, glm::value_ptr(newTransform));
*/
glutPostRedisplay();
glDrawArrays(GL_TRIANGLES, 0 , 36);
glBindVertexArray(0);
glutSwapBuffers();
}
void UCreateShader()
{
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
/*void applyDepthSettings() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}*/
void UCreateBuffers()
{
//specify coords for creating square
// Positon and Color data
GLfloat vertices[] = {
// Vertex Positions // Colors
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // Top Right Vertex 0
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // Bottom Right Vertex 1
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // Bottom Left Vertex 2
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // Top Left Vertex 3
-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, // Top Right Vertex 0
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Bottom Right Vertex 1
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Bottom Left Vertex 2
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top Left Vertex 3
-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, 0.0f, 1.0f, // Top Right Vertex 0
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom Right Vertex 1
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom Left Vertex 2
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Top Left Vertex 3
-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, 1.0f, 0.0f, // Top Right Vertex 0
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, // Bottom Right Vertex 1
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, // Bottom Left Vertex 2
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, // Top Left Vertex 3
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, // Top Right Vertex 0
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, // Bottom Right Vertex 1
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // Bottom Left Vertex 2
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // Top Left Vertex 3
-0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f, // Top Right Vertex 0
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f, // Bottom Right Vertex 1
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, // Bottom Left Vertex 2
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, // Top Left Vertex 3
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 1.0f,
};
//generate id's for buffer object
glGenVertexArrays(1, &VAO); //generate for Vertex Array Object
glGenBuffers(1, &VBO); //generate for Vertex Buffer Object
glBindVertexArray(VAO); //activate text array object
glBindBuffer(GL_ARRAY_BUFFER, VBO); //activating VBO buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //pass in size of array from line 128
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);//send data to shader (accepts 6 arguments)GL_FALSE=not using normalization
glEnableVertexAttribArray(0);//enable vertex attribute pointer, starting position of x,y,z
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));//send data to shader (accepts 6 arguments)GL_FALSE=not using normalization
glEnableVertexAttribArray(1);//specify color starting point
glBindVertexArray(0); //deactivate vertex array object (VBO)
}
void UKeyboard(unsigned char key, GLint x, GLint y)
{
switch(key)
{
case'w':
cout<<"You pressed W!" <<endl;
break;
case 's':
cout<<"You pressed S!"<<endl;
break;
case'a':
cout<<"You pressed A!"<<endl;
break;
case 'd':
cout<<"You pressed D!"<<endl;
break;
default:
cout<<"Press a key!"<<endl;
}
}
/*Implements the UKeyReleased function*/
void UKeyReleased(unsigned char key, GLint x, GLint y)
{
cout<<"Key released"<<endl;
}
Your vertex shader does not compile, because mobileColor is of type vec4 and color is of type vec3.
Change:
mobileColor = color;
to:
mobileColor = vec4(color, 1.0);
Note, your shader program was not used, because it was not successfully built. Everything you have drawn was drawn by default OpenGL with the currently set glColor, which is by default white (1,1,1,1).
Whether the compilation of a shader succeeded can be checked by glGetShaderiv, and the error message can be retrieved with glGetShaderInfoLog:
GLint status = GL_TRUE;
glCompileShader( shaderStage );
glGetShaderiv( shaderStage, GL_COMPILE_STATUS, &status );
if ( status == GL_FALSE )
{
GLint logLen;
glGetShaderiv( shaderStage, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen+1 );
GLsizei written;
glGetShaderInfoLog( shaderStage, logLen, &written, log.data() );
std::cout << "compile error:" << std::endl << log.data() << std::endl;
}
Whether a program was linked successfully can be checked by glGetProgramiv, and the error message can be retrieved with glGetProgramInfoLog:
GLint status = GL_TRUE;
glLinkProgram( shaderProgram );
glGetProgramiv( shaderProgram, GL_LINK_STATUS, &status );
if ( status == GL_FALSE )
{
GLint logLen;
glGetProgramiv( shaderProgram, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen+1 );
GLsizei written;
glGetProgramInfoLog( shaderProgram, logLen, &written, log.data() );
std::cout << "link error:" << std::endl << log.data() << std::endl;
}