Directx 9 Rotate Textured Vertex - c++

I used vertexes to draw textures and did not have a problem but now i am trying to rotate some textures and getting black screen.
This is my initial code to draw texture with vertex.
struct CUSTOM_VERTEX { FLOAT X, Y, Z, RHW, U, V; };
#define CUSTOM_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1 )
CUSTOM_VERTEX vertices[4] =
{ //X, Y, Z, RHW, U, V
100.0f, 100.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1000.0f, 100.0f, 0.0f, 1.0f, 1.0f, 0.0f,
100.0f, 750.0f, 0.0f, 1.0f, 0.0f, 1.0f,
1000.0f, 750.0f, 0.0f, 1.0f, 1.0f, 1.0f
};
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
d3d9device->CreateVertexBuffer(4 * sizeof(CUSTOM_VERTEX),
0,
CUSTOM_FVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
VOID* pVoid;
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
d3d9device->SetFVF(CUSTOM_FVF);
d3d9device->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOM_VERTEX));
d3d9device->SetTexture(0, d3d9texture);
d3d9device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
I read that RHW describes pre-transformed vertices. Then i changed CUSTOM_VERTEX, CUSTOM_FVF and added SetTransform.
struct CUSTOM_VERTEX { FLOAT X, Y, Z, U, V; };
#define CUSTOM_FVF (D3DFVF_XYZ | D3DFVF_TEX1 )
CUSTOM_VERTEX vertices[4] =
{ //X, Y, Z, U, V
100.0f, 100.0f, 0.0f, 0.0f, 0.0f,
1000.0f, 100.0f, 0.0f, 1.0f, 0.0f,
100.0f, 750.0f, 0.0f, 0.0f, 1.0f,
1000.0f, 750.0f, 0.0f, 1.0f, 1.0f
};
//CreateVertexBuffer, memcpy, SetFVF and SetStreamsource are the same as above
D3DXMATRIX worldMatrix;
D3DXMatrixRotationZ(&worldMatrix, D3DXToRadian(90));
d3d9device->SetTransform(D3DTS_WORLD, &worldMatrix);
//SetTexture and DrawPrimitive are the same as above
I also tried adding view and projection matrix.
D3DXMATRIX viewMatrix;
D3DXMatrixLookAtLH(&viewMatrix,
&D3DXVECTOR3 (0.0f, 0.0f, 10.0f),
&D3DXVECTOR3 (0.0f, 0.0f, 0.0f),
&D3DXVECTOR3 (0.0f, 1.0f, 0.0f));
d3d9device->SetTransform(D3DTS_VIEW, &viewMatrix);
D3DXMATRIX projectionMatrix;
D3DXMatrixPerspectiveFovLH(&projectionMatrix,
D3DXToRadian(45),
width / height,
1.0f,
1000.0f);
d3d9device->SetTransform(D3DTS_PROJECTION, &projectionMatrix);
I changed pEye and pAt inputs of D3DXMatrixLookAtLH method to center of vertex but again black screen.

My problem was using the same points for both pre-transformed (RHW) and non pre-transformed vertices.
Solved problem like below.
struct CUSTOM_VERTEX { FLOAT X, Y, Z, U, V; };
#define CUSTOM_FVF (D3DFVF_XYZ | D3DFVF_TEX1 )
float halfBackBufferWidth = backBufferWidth / 2.0f;
float halfBackBufferHeight = backBufferHeight / 2.0f;
CUSTOM_VERTEX vertices[4] =
{ //X, Y, Z, U, V
{ halfBackBufferWidth - 100.0f, halfBackBufferHeight - 100.0f, 0.0f, 0.0f, 0.0f },
{ halfBackBufferWidth - 1000.0f, halfBackBufferHeight - 100.0f, 0.0f, 1.0f, 0.0f },
{ halfBackBufferWidth - 100.0f, halfBackBufferHeight - 750.0f, 0.0f, 0.0f, 1.0f },
{ halfBackBufferWidth - 1000.0f, halfBackBufferHeight - 750.0f, 0.0f, 1.0f, 1.0f }
};
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
d3d9device->CreateVertexBuffer(4 * sizeof(CUSTOM_VERTEX),
0,
CUSTOM_FVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
VOID* pVoid;
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
d3d9device->SetFVF(CUSTOM_FVF);
d3d9device->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOM_VERTEX));
D3DXMATRIX worldMatrix;
D3DXMatrixRotationZ(&worldMatrix, D3DXToRadian(45));
d3d9device->SetTransform(D3DTS_WORLD, &worldMatrix);
D3DXMATRIX viewMatrix;
D3DXMatrixLookAtLH(&viewMatrix,
&D3DXVECTOR3 (0.0f, 0.0f, halfBackBufferHeight),
&D3DXVECTOR3 (0.0f, 0.0f, 0.0f),
&D3DXVECTOR3 (0.0f, 1.0f, 0.0f));
d3d9device->SetTransform(D3DTS_VIEW, &viewMatrix);
D3DXMATRIX projectionMatrix;
D3DXMatrixPerspectiveFovLH(&projectionMatrix,
D3DXToRadian(90),
backBufferWidth / backBufferHeight,
1.0f,
halfBackBufferHeight);
d3d9device->SetTransform(D3DTS_PROJECTION, &projectionMatrix);
d3d9device->SetTexture(0, d3d9texture);
d3d9device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
I dont want to add light so I disable it. If I dont disable it, I get black screen.
d3d9device->SetRenderState(D3DRS_LIGHTING, FALSE);

Related

Problem with changing class variables' value

I have a problem. I'm working on a OpenGL project and I need to access a class variable by the class method. I got it done, but then changed some code and now it's not working and i cannot get it done. It's all about Yaw and Pitch variables. If i change them in their class method (e.g. ProccesMouseInput) they don't change their values, but I had already tried it in main function and then they do... Here's my code.
Camera.h
#pragma once
#include <glm/glm.hpp>
#include <glm/vec3.hpp>
#include <glm/gtc/matrix_transform.hpp>
enum class movement_direction{
FORWARD,
BACKWARD,
LEFT,
RIGHT,
UP,
DOWN
};
class Camera {
private:
glm::vec3 m_Position;
glm::vec3 m_Front;
glm::vec3 m_Up;
glm::vec3 m_Right;
glm::vec3 m_WorldUp;
float m_MouseSensitivity;
float MovementSpeed = 2.5f;
float MouseSensitivity = 0.1f;
float FOV = 45.0f;
float Yaw;
float Pitch;
public:
Camera(glm::vec3 pos, glm::vec3 up, float yaw, float pitch);
Camera(float PosX, float PosY, float PosZ, float UpX, float UpY, float UpZ, float yaw, float pitch);
void ProcessMouseInput(float offsetX, float offsetY, bool constrainPitch);
void ProcessKeyboardInput(movement_direction direction, float deltaTime);
void ProcessScrollInput(float offsetX, float offsetY);
void UpdateCameraVectors();
glm::mat4 GetViewMatrix();
};
Camera.cpp
#include "Camera.h"
#include <iostream>
Camera::Camera(glm::vec3 pos = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = -90.0f, float pitch = 0.0f)
: m_Position(pos), m_Up(up), m_WorldUp(up), Yaw(yaw), Pitch(pitch), m_MouseSensitivity(MouseSensitivity)
{
UpdateCameraVectors();
}
Camera::Camera(float PosX, float PosY, float PosZ, float UpX, float UpY, float UpZ, float yaw, float pitch)
: m_Position(glm::vec3(PosX, PosY, PosZ)), m_Up(glm::vec3(UpX, UpY, UpZ)), m_WorldUp(glm::vec3(UpX, UpY, UpZ)), Yaw(yaw), Pitch(pitch), m_MouseSensitivity(MouseSensitivity)
{
UpdateCameraVectors();
}
void Camera::ProcessMouseInput(float offsetX, float offsetY, bool constrainPitch = true)
{
Yaw += offsetX * m_MouseSensitivity;
Pitch += offsetY * m_MouseSensitivity;
if (constrainPitch)
{
if (Pitch < -89.0f)
Pitch = -89.0f;
if (Pitch > 89.0f)
Pitch = 89.0f;
}
UpdateCameraVectors();
}
void Camera::ProcessKeyboardInput(movement_direction direction, float deltaTime)
{
float velocity = MovementSpeed * deltaTime;
if (direction == movement_direction::FORWARD)
m_Position += m_Front * velocity;
if (direction == movement_direction::BACKWARD)
m_Position -= m_Front * velocity;
if (direction == movement_direction::LEFT)
m_Position -= m_Right * velocity;
if (direction == movement_direction::RIGHT)
m_Position += m_Right * velocity;
if (direction == movement_direction::UP)
m_Position += m_WorldUp * velocity;
if (direction == movement_direction::DOWN)
m_Position -= m_WorldUp * velocity;
}
void Camera::ProcessScrollInput(float offsetX, float offsetY)
{
}
void Camera::UpdateCameraVectors()
{
glm::vec3 direction;
direction.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
direction.y = sin(glm::radians(Pitch));
direction.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
m_Front = glm::normalize(direction);
m_Right = glm::normalize(glm::cross(m_Front, m_WorldUp));
m_Up = glm::normalize(glm::cross(m_Right, m_Front));
}
glm::mat4 Camera::GetViewMatrix()
{
return glm::lookAt(m_Position, m_Position + m_Front, m_Up);
}
Application.cpp
/* Including GLEW */
#include <GL/glew.h>
/* Including GLFW */
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include "vendor/stb_image/stb_image.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <string>
#include <conio.h>
#include "Shader.h"
#include "Camera.h"
void processInput(GLFWwindow* window);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double offsetX, double offsetY);
const int SCR_WIDTH = 800;
const int SCR_HEIGHT = 600;
float deltaTime = 0.0f;
float currentFrame = 0.0f;
float lastFrame = 0.0f;
float lastX = SCR_WIDTH / 2;
float lastY = SCR_HEIGHT / 2;
bool firstMouse = true;
float fov = 45.0f;
Camera main_camera(glm::vec3(0.0f, 0.0f, -3.0f), glm::vec3(0.0f, 1.0f, 0.0f), -90.0f, 0.0f);
int main(void)
{
GLFWwindow* window;
/* Initializing the library */
if (!glfwInit())
{
std::cout << "Failed to initialize GLFW.\n";
return -1;
}
/* Creating a windowed mode window and its OpenGL context */
window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Hello World", NULL, NULL);
if (!window)
{
std::cout << "Failed to open GLFW window.\n";
glfwTerminate();
return -1;
}
/* Making the window's context current */
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
std::cout << "Failed to initialize GLEW\n";
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
/* Getting the version of GL */
std::cout << "Using GL Version: " << glGetString(GL_VERSION) << std::endl;
float vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
};
glm::vec3 cubes_positions[]{
glm::vec3( 0.0f, 0.0f, 0.0f),
glm::vec3( 2.0f, 5.0f, -15.0f),
glm::vec3(-1.5f, -2.2f, -2.5f),
glm::vec3(-3.8f, -2.0f, -12.3f),
glm::vec3( 2.4f, -0.4f, -3.5f),
glm::vec3(-1.7f, 3.0f, -7.5f),
glm::vec3( 1.3f, -2.0f, -2.5f),
glm::vec3( 1.5f, 2.0f, -2.5f),
glm::vec3( 1.5f, 0.2f, -1.5f),
glm::vec3(-1.3f, 1.0f, -1.5f)
};
/* VERTEX ARRAY */
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
/* VERTEX BUFFER */
unsigned int VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
/* VERTEX LAYOUT */
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
/* LOADING TEXTURES */
// --- first texture object ---
unsigned int texture1;
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
float borderColor1[]{
0.1f, 0.1f, 0.0f, 1.0f
};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor1);
int width, height, channelsNr;
unsigned char* data = stbi_load("res/textures/container.jpg", &width, &height, &channelsNr, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture\n";
}
stbi_image_free(data);
// --- second texture object ---
unsigned int texture2;
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
float borderColor2[]{
0.1f, 0.1f, 0.0f, 1.0f
};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor2);
stbi_set_flip_vertically_on_load(true);
data = stbi_load("res/textures/awesomeface.png", &width, &height, &channelsNr, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
else
{
std::cout << "Failed to load texture\n";
}
stbi_image_free(data);
/* BINDING BEFORE THE DRAW CALL */
// --- shader ---
Shader basic("res/shaders/Basic.glsl");
basic.Bind();
basic.SetUniform1i("texture1", 0);
basic.SetUniform1i("texture2", 1);
glEnable(GL_DEPTH_TEST);
// --- texture ---
glBindTexture(GL_TEXTURE_2D, texture2);
// --- vertex array object ---
glBindVertexArray(VAO);
float value = 0.5f;
basic.SetUniform1f("mix_value", 0.2f);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
currentFrame = (float)glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
processInput(window);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.f, 0.2f, 0.2f, 1.f);
/* Render here */
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glm::mat4 projection = glm::perspective(glm::radians(fov), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
basic.SetUniformMatrix4fv("proj", 1, glm::value_ptr(projection));
glm::mat4 view = main_camera.GetViewMatrix();
basic.SetUniformMatrix4fv("view", 1, glm::value_ptr(view));
for (int i = 0; i < (sizeof(cubes_positions) / sizeof(glm::vec3)); i++)
{
float angle = 20.0f * i;
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, cubes_positions[i]);
model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.0f, 0.0f));
basic.SetUniformMatrix4fv("model", 1, glm::value_ptr(model));
glDrawArrays(GL_TRIANGLES, 0, 36);
}
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
main_camera.ProcessKeyboardInput(movement_direction::FORWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
main_camera.ProcessKeyboardInput(movement_direction::BACKWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
main_camera.ProcessKeyboardInput(movement_direction::LEFT, deltaTime);
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
main_camera.ProcessKeyboardInput(movement_direction::RIGHT, deltaTime);
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
main_camera.ProcessKeyboardInput(movement_direction::UP, deltaTime);
if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
main_camera.ProcessKeyboardInput(movement_direction::DOWN, deltaTime);
}
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
if (firstMouse)
{
lastX = (float)xpos;
lastY = (float)ypos;
firstMouse = false;
}
float offsetX = (float)xpos - lastX;
float offsetY = lastY - (float)ypos;
lastX = (float)xpos;
lastY = (float)ypos;
main_camera.ProcessMouseInput(offsetX, offsetY, true);
}
void scroll_callback(GLFWwindow* window, double offsetX, double offsetY)
{
fov -= (float)offsetY;
if (fov < 1.0f)
fov = 1.0f;
if (fov > 90.0f)
fov = 90.0f;
}
I finally fixed it! It was something to do with multiplication of offsetX and offsetY by m_MouseSensitivity. For some reason it wasn't initializing right and thus was assigned to 0. By multiplying by zero you get zero so Yaw and Pitch didn't change. Thank you for the help <3

How to use keyboard and mouse input to navigate a figure

I'm working on a project involving viewing a 3D from different viewpoints using mouse and keyboard input. When I submitted my first draft, I received the following feedback:
"Your object did not react to any of the buttons I pressed to change the camera view! The object of this project is to have the user control the camera by being able to change different views but your object didn't give me that ability!"
I currently have it coded to zoom in on the object when pressing the up key and out when pressing the down key. The camera view is supposed to move up and down when moving the mouse.
I've tried using some previous code that involved the cameraPosition variable, but it does not function properly when utilized in the pressSpecialKey function or in the rendering function.
/*Header Inclusions*/
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
//GLM Math Header Inclusions
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
//SOIL image loader Inclusion
#include "SOIL2/SOIL2.h"
using namespace std; //Standard namespace
#define WINDOW_TITLE "Final Project: Spoon" //Window title Macro
/*Shader program Macro*/
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version "\n" #Source
#endif
//Global variable declarations
int view_state = 1;
/*Variable declarations for shader, window size initialization, buffer and array objects*/
GLint spoonShaderProgram, lampShaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, SpoonVAO, LightVAO, texture;
GLfloat cameraSpeed = 0.0005f; //Movement speed per frame
//TODO: Remove unnessary code
GLchar currentKey; //Will store key pressed
GLfloat lastMouseX = 400, lastMouseY = 300; //Locks mouse cursor at the center of the screen
GLfloat mouseXOffset, mouseYOffset, yaw = 0.0f, pitch = 0.0f; //mouse offset, yaw, and pitch variables
GLfloat sensitivity = 0.5f; //Used for mouse / camera rotation sensitivity
bool mouseDetected = true; //Initially true when mouse movement is detected
//Global vector declarations
glm::vec3 cameraPosition = glm::vec3(-2.0f, 1.0f, 2.0f); //Initial camera position.
glm::vec3 CameraUpY = glm::vec3(0.0f, 1.0f, 0.0f); //Temporary y unit vector
glm::vec3 CameraForwardZ = glm::vec3(0.0f, 0.0f, -1.0f); //Temporary z unit vector
glm::vec3 front; //Temporary z unit vector for mouse
//Subject position and scale
glm::vec3 spoonPosition(0.0f, 0.0f, 0.0f);
glm::vec3 spoonScale(2.0f);
//spoon and light color
glm::vec3 objectColor(1.0f, 1.0f, 1.0f);
glm::vec3 lightColor(1.0f, 1.0f, 1.0f);
//Light position and scale
glm::vec3 lightPosition(0.5f, 0.5f, 3.0f);
glm::vec3 lightScale(0.3f);
/*Function prototypes*/
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
void pressSpecialKey(int key, int xx, int yy);
void UMouseMove(int x, int y);
void UGenerateTexture(void);
/*Spoon Vertex Shader Course Code*/
const GLchar * spoonVertexShaderSource = GLSL(330,
layout (location = 0) in vec3 position; //Vertex data from Vertex Attrib Pointer 0
layout (location = 1) in vec3 normal; //VAP for normals from Vertex Attrib Pointer 1
layout (location = 2) in vec2 textureCoordinate; //Texture vertex data from Vertex Attrib Pointer 2
out vec3 FragmentPos; //For outgoing color / pixels to fragment shader
out vec3 Normal; //For outgoing normals to fragment shader
out vec2 mobileTextureCoordinate;
//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); //transforms vertices to clip coordinates
FragmentPos = vec3(model * vec4(position, 1.0f)); //Gets fragment / pixel position in world space only (exclude view and projection)
Normal = mat3(transpose(inverse(model))) * normal; //get normal vectors in world space only and exclude normal translation properties
mobileTextureCoordinate = vec2(textureCoordinate.x, 1 - textureCoordinate.y); //flips the texture horizontal
}
);
/*Spoon Fragment Shader Source Code*/
const GLchar * spoonFragmentShaderSource = GLSL(330,
in vec3 FragmentPos; //For incoming fragment position
in vec3 Normal; //For incoming normals
in vec2 mobileTextureCoordinate;
out vec4 spoonColor; //For outgoing spoon color to the GPU
//Uniform / Global variables for object color, light color, light position, and camera/view position
uniform vec3 lightColor;
uniform vec3 lightPos;
uniform vec3 viewPosition;
uniform sampler2D uTexture; //Useful when working with multiple textures
void main(){
/*Phong lighting model calculations to generate ambient, diffuse, and specular components*/
//Calculate Ambient Lighting
float ambientStrength = 0.1f; //Set ambient or global lighting strength
vec3 ambient = ambientStrength * lightColor; //Generate ambient light color
//Calculate Diffuse Lighting
vec3 norm = normalize(Normal); //Normalize vectors to 1 unit
vec3 lightDirection = normalize(lightPos - FragmentPos); //Calculate distance (light direction) between light source and fragments/pixels on
float impact = max(dot(norm, lightDirection), 0.0); //Calculate diffuse impact by generating dot product of normal and light
vec3 diffuse = impact * lightColor; //Generate diffuse light color
//Calculate Specular lighting
float specularIntensity = 1.6f; //Set specular light strength
float highlightSize = 128.0f; //Set specular highlight size
vec3 viewDir = normalize(viewPosition - FragmentPos); //Calculate view direction
vec3 reflectDir = reflect(-lightDirection, norm); //Calculate reflection vector
//Calculate specular component
float specularComponent = pow(max(dot(viewDir, reflectDir), 0.0), highlightSize);
vec3 specular = specularIntensity * specularComponent * lightColor;
//Calculate phong result
vec3 objectColor = texture(uTexture, mobileTextureCoordinate).xyz;
vec3 phong = (ambient + diffuse) * objectColor + specular;
spoonColor = vec4(phong, 1.0f); //Send lighting results to GPU
}
);
/*Lamp Shader Source Code*/
const GLchar * lampVertexShaderSource = GLSL(330,
layout (location = 0) in vec3 position; //VAP position 0 for vertex position data
//Uniform / 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); //Transforms vertices into clip coordinates
}
);
/*Lamp Fragment Shader Source Code*/
const GLchar * lampFragmentShaderSource = GLSL(330,
out vec4 color; //For outgoing lamp color (smaller spoon) to the GPU
void main()
{
color = vec4(1.0f); //Set color to white (1.0f, 1.0f, 1.0f) with alpha 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();
UGenerateTexture();
glClearColor(0.8f, 0.8f, 0.8f, 1.0f); //Set background color
glutDisplayFunc(URenderGraphics);
glutSpecialFunc(pressSpecialKey); //Detects key press
glutPassiveMotionFunc(UMouseMove);
glutMainLoop();
//Destroys Buffer objects once used
glDeleteVertexArrays(1, &SpoonVAO);
glDeleteVertexArrays(1, &LightVAO);
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
GLint uTextureLoc, lightColorLoc, lightPositionLoc, viewPositionLoc;
/*********Use the Spoon Shader to activate the Spoon Vertex Array Object for rendering and transforming*********/
glUseProgram(spoonShaderProgram);
glBindVertexArray(SpoonVAO);
CameraForwardZ = front; //Replaces camera forward vector with Radians normalized as a unit vector
//Transforms the object
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); //Place the object at the center of the viewport
model = glm::rotate(model, 45.0f, glm:: vec3(0.0, 1.0f, 0.0f)); //Rotate the object 45 degrees on the X
model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f)); //Increase the object size by a scale of 2
//Transform the camera
glm::mat4 view;
view = glm::lookAt(cameraPosition - CameraForwardZ, cameraPosition, CameraUpY);
//Creates a perspective projection
glm::mat4 projection;
if(view_state == 1){
projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
}else if(view_state == 0){
projection = glm::ortho(-5.0f, 5.0f, -5.0f, 5.0f, 0.1f, 100.0f);
}
//Reference matrix uniforms from the spoon Shader program
GLint modelLoc = glGetUniformLocation(spoonShaderProgram, "model");
GLint viewLoc = glGetUniformLocation(spoonShaderProgram, "view");
GLint projLoc = glGetUniformLocation(spoonShaderProgram, "projection");
//Pass matrix data to the spoon Shader program's matrix uniforms
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));
//Reference matrix uniforms from the spoon Shader program for the spoon color, light color, light position, and camera position
uTextureLoc = glGetUniformLocation(spoonShaderProgram, "uTexture");
lightColorLoc = glGetUniformLocation(spoonShaderProgram, "lightColor");
lightPositionLoc = glGetUniformLocation(spoonShaderProgram, "lightPos");
viewPositionLoc = glGetUniformLocation(spoonShaderProgram, "viewPosition");
//Pass color, light, and camera data to the spoon Shader programs corresponding uniforms
glUniform1i(uTextureLoc, 0); // texture unit 0
glUniform3f(lightColorLoc, lightColor.r, lightColor.g, lightColor.b);
glUniform3f(lightPositionLoc, lightPosition.x, lightPosition.y, lightPosition.z);
glUniform3f(viewPositionLoc, cameraPosition.x, cameraPosition.y, cameraPosition.z);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glDrawArrays(GL_TRIANGLES, 0, 126); //Draw the primitives / spoon
glBindVertexArray(0); //Deactivate the spoon Vertex Array Object
/***************Use the Lamp Shader and activate the Lamp Vertex Array Object for rendering and transforming ************/
glUseProgram(lampShaderProgram);
glBindVertexArray(LightVAO);
//Transform the smaller spoon used as a visual cue for the light source
model = glm::translate(model, lightPosition);
model = glm::scale(model, lightScale);
//Reference matrix uniforms from the Lamp Shader program
modelLoc = glGetUniformLocation(lampShaderProgram, "model");
viewLoc = glGetUniformLocation(lampShaderProgram, "view");
projLoc = glGetUniformLocation(lampShaderProgram, "projection");
//Pass matrix uniforms from the Lamp Shader Program
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));
//Draws the triangles
glDrawArrays(GL_TRIANGLES, 0, 126);
glBindVertexArray(0); //Deactivate the Vertex Array Object
glutPostRedisplay();
glutSwapBuffers(); //Flips the back buffer with the front buffer every frame. Similar to GL Flush
}
/*Creates the Shader program*/
void UCreateShader()
{
//Spoon Vertex shader
GLint spoonVertexShader = glCreateShader(GL_VERTEX_SHADER); //Create the Vertex shader
glShaderSource(spoonVertexShader, 1, &spoonVertexShaderSource, NULL); //Attaches the vertex shader to the source code
glCompileShader(spoonVertexShader); //Compiles the Vertex shader
//Spoon Fragment shader
GLint spoonFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); //Create the Fragment shader
glShaderSource(spoonFragmentShader, 1, &spoonFragmentShaderSource, NULL); //Attaches the Fragment shader to the source code
glCompileShader(spoonFragmentShader); //Compiles the Fragment shader
//Spoon Shader program
spoonShaderProgram = glCreateProgram(); //Creates the Shader program and returns an id
glAttachShader(spoonShaderProgram, spoonVertexShader); //Attach Vertex shader to the Shader program
glAttachShader(spoonShaderProgram, spoonFragmentShader); //Attach Fragment shader to the Shader program
glLinkProgram(spoonShaderProgram); //Link Vertex and Fragment shaders to Shader program
//Delete the Vertex and Fragment shaders once linked
glDeleteShader(spoonVertexShader);
glDeleteShader(spoonFragmentShader);
//Lamp Vertex shader
GLint lampVertexShader = glCreateShader(GL_VERTEX_SHADER); //Creates the Vertex shader
glShaderSource(lampVertexShader, 1, &lampVertexShaderSource, NULL); //Attaches the Vertex shader to the source code
glCompileShader(lampVertexShader); //Compiles the Vertex shader
//Lamp Fragment shader
GLint lampFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); //Creates the Fragment shader
glShaderSource(lampFragmentShader, 1, &lampFragmentShaderSource, NULL); //Attaches the Fragment shader to the source code
glCompileShader(lampFragmentShader); //Compiles the Fragment shader
//Lamp Shader Program
lampShaderProgram = glCreateProgram(); //Creates the Shader program and returns an id
glAttachShader(lampShaderProgram, lampVertexShader); //Attach Vertex shader to the Shader program
glAttachShader(lampShaderProgram, lampFragmentShader); //Attach Fragment shader to the Shader program
glLinkProgram(lampShaderProgram); //Link Vertex and Fragment shaders to the Shader program
//Delete the lamp shaders once linked
glDeleteShader(lampVertexShader);
glDeleteShader(lampFragmentShader);
}
void UCreateBuffers()
{
GLfloat vertices[] = {
//Position //Normals //Texture //Point Name
//Front of Scoop //Positive Z
-0.4f, 0.05f, 0.1f, 0.0f, 0.0f, 1.0f, 0.3f, 1.0f, //Q
-0.4f, -0.1f, 0.1f, 0.0f, 0.0f, 1.0f, 0.3f, 0.0f, //R
-0.6f, 0.1f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, //U
-0.4f, 0.05f, 0.1f, 0.0f, 0.0f, 1.0f, 0.3f, 1.0f, //Q
-0.2f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f, 0.6f, 1.0f, //W
-0.4f, -0.1f, 0.1f, 0.0f, 0.0f, 1.0f, 0.3f, 0.0f, //R
-0.4f, -0.1f, 0.1f, 0.0f, 0.0f, 1.0f, 0.3f, 0.0f, //R
-0.2f, -0.1f, 0.1f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, //A
-0.2f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f, 0.6f, 1.0f, //W
-0.2f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f, 0.6f, 1.0f, //W
-0.2f, -0.1f, 0.1f, 0.0f, 0.0f, 1.0f, 0.6f, 0.0f, //A_1
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, //A
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, //A
-0.2f, -0.1f, 0.1f, 0.0f, 0.0f, 1.0f, 0.6f, 1.0f, //A_1
0.0f, -0.05f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, //B
//Bottom of Scoop Slant //Negative X
-0.6f, 0.1f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.6f, //U
-0.6f, 0.1f, -0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.3f, //V
-0.4f, -0.1f, 0.1f, -1.0f, 0.0f, 0.0f, 0.3f, 1.0f, //R
-0.4f, -0.1f, 0.1f, -1.0f, 0.0f, 0.0f, 0.3f, 1.0f, //R
-0.4f, -0.1f, -0.2f, -1.0f, 0.0f, 0.0f, 0.3f, 0.0f, //T
-0.6f, 0.1f, -0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.3f, //V
//Bottom of Scoop //Negative Y
-0.4f, -0.1f, -0.2f, 0.0f, -1.0f, 0.0f, 0.3f, 0.0f, //T
-0.4f, -0.1f, 0.1f, 0.0f, -1.0f, 0.0f, 0.3f, 1.0f, //R
-0.2f, -0.1f, -0.2f, 0.0f, -1.0f, 0.0f, 0.6f, 0.0f, //B_1
-0.2f, -0.1f, -0.2f, 0.0f, -1.0f, 0.0f, 0.6f, 0.0f, //B_1
-0.4f, -0.1f, 0.1f, 0.0f, -1.0f, 0.0f, 0.3f, 1.0f, //R
-0.2f, -0.1f, 0.1f, 0.0f, -1.0f, 0.0f, 0.6f, 1.0f, //A_1
-0.2f, -0.1f, 0.1f, 0.0f, -1.0f, 0.0f, 0.6f, 1.0f, //A_1
-0.2f, -0.1f, -0.2f, 0.0f, -1.0f, 0.0f, 0.3f, 0.0f, //B_1
0.0f, -0.05f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.6f, //B
-0.2f, -0.1f, -0.2f, 0.0f, -1.0f, 0.0f, 0.6f, 0.0f, //B_1
0.0f, -0.05f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.6f, //B
0.0f, -0.05f, -0.1f, 0.0f, -1.0f, 0.0f, 1.0f, 0.3f, //D
//Back of Scoop //Negative Z
-0.6f, 0.1f, -0.1f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, //V
-0.4f, 0.05f, -0.2f, 0.0f, 0.0f, -1.0f, 0.3f, 1.0f, //S
-0.4f, -0.1f, -0.2f, 0.0f, 0.0f, -1.0f, 0.3f, 0.0f, //T
-0.4f, 0.05f, -0.2f, 0.0f, 0.0f, -1.0f, 0.3f, 1.0f, //S
-0.4f, -0.1f, -0.2f, 0.0f, 0.0f, -1.0f, 0.3f, 0.0f, //T
-0.2f, -0.1f, -0.2f, 0.0f, 0.0f, -1.0f, 0.6f, 0.0f, //B_1
-0.4f, 0.05f, -0.2f, 0.0f, 0.0f, -1.0f, 0.3f, 1.0f, //S
-0.2f, -0.1f, -0.2f, 0.0f, 0.0f, -1.0f, 0.6f, 0.0f, //B_1
-0.2f, 0.0f, -0.2f, 0.0f, 0.0f, -1.0f, 0.6f, 1.0f, //Z
-0.2f, 0.0f, -0.2f, 0.0f, 0.0f, -1.0f, 0.6f, 1.0f, //Z
-0.2f, -0.1f, -0.2f, 0.0f, 0.0f, -1.0f, 0.6f, 0.0f, //B_1
0.0f, 0.0f, -0.1f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, //C
0.0f, 0.0f, -0.1f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, //C
-0.2f, -0.1f, -0.2f, 0.0f, 0.0f, -1.0f, 0.6f, 0.0f, //B_1
0.0f, -0.05f, -0.1f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, //D
//Top of Scoop //Positive Y
-0.6f, 0.1f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.3f, //U
-0.6f, 0.1f, -0.1f, 0.0f, 1.0f, 0.0f, 0.0f, 0.6f, //V
-0.4f, 0.05f, -0.2f, 0.0f, 1.0f, 0.0f, 0.3f, 1.0f, //S
-0.6f, 0.1f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.3f, //U
-0.4f, 0.05f, -0.2f, 0.0f, 1.0f, 0.0f, 0.3f, 1.0f, //S
-0.4f, 0.05f, 0.1f, 0.0f, 1.0f, 0.0f, 0.3f, 0.0f, //Q
-0.4f, 0.05f, -0.2f, 0.0f, 1.0f, 0.0f, 0.3f, 1.0f, //S
-0.4f, 0.05f, 0.1f, 0.0f, 1.0f, 0.0f, 0.3f, 0.0f, //Q
-0.2f, 0.0f, -0.2f, 0.0f, 1.0f, 0.0f, 0.6f, 1.0f, //Z
-0.4f, 0.05f, 0.1f, 0.0f, 1.0f, 0.0f, 0.3f, 0.0f, //Q
-0.2f, 0.0f, -0.2f, 0.0f, 1.0f, 0.0f, 0.6f, 1.0f, //Z
-0.2f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f, 0.6f, 0.0f, //W
-0.2f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f, 0.6f, 0.0f, //W
-0.2f, 0.0f, -0.2f, 0.0f, 1.0f, 0.0f, 0.6f, 1.0f, //Z
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.3f, //A
-0.2f, 0.0f, -0.2f, 0.0f, 1.0f, 0.0f, 0.6f, 1.0f, //Z
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.3f, //A
0.0f, 0.0f, -0.1f, 0.0f, 1.0f, 0.0f, 1.0f, 0.6f, //C
//Front of Handle //Positive Z
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.1f, //A
0.0f, -0.05f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, //B
0.6f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, //E
0.6f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, //E
0.0f, -0.05f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, //B
0.6f, -0.1f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, //F
//Bottom of Handle //Negative Y
0.0f, -0.05f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, //B
0.0f, -0.05f, -0.1f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, //D
0.6f, -0.1f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, //F
0.0f, -0.05f, -0.1f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, //D
0.6f, -0.1f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, //F
0.6f, -0.1f, -0.1f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, //H
//Back of Handle //Negative Z
0.0f, 0.0f, -0.1f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, //C
0.0f, -0.05f, -0.1f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, //D
0.6f, 0.0f, -0.1f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, //G
0.0f, -0.05f, -0.1f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, //D
0.6f, 0.0f, -0.1f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, //G
0.6f, -0.1f, -0.1f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, //H
//Top of Handle //Positive Y
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, //A
0.0f, 0.0f, -0.1f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, //C
0.6f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, //E
0.0f, 0.0f, -0.1f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, //C
0.6f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, //E
0.6f, 0.0f, -0.1f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, //G
//Grip Connection //Negative X
0.6f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, //I
0.6f, 0.0f, -0.2f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, //J
0.6f, -0.1f, 0.1f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, //K
0.6f, 0.0f, -0.2f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, //J
0.6f, -0.1f, 0.1f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, //K
0.6f, -0.1f, -0.2f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, //L
//Front to Grip //Positive Z
0.6f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, //I
1.0f, 0.0f, 0.05f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, //M
0.6f, -0.1f, 0.1f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, //K
1.0f, 0.0f, 0.05f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, //M
0.6f, -0.1f, 0.1f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, //K
1.0f, -0.1f, 0.05f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, //N
//Bottom to Grip //Negative Y
0.6f, -0.1f, 0.1f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, //K
1.0f, -0.1f, 0.05f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, //N
0.6f, -0.1f, -0.2f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, //L
1.0f, -0.1f, 0.05f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, //N
0.6f, -0.1f, -0.2f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, //L
1.0f, -0.1f, -0.15f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, //P
//Back to Grip //Negative Z
0.6f, 0.0f, -0.2f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, //J
0.6f, -0.1f, -0.2f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, //L
1.0f, 0.0f, -0.15f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, //O
0.6f, -0.1f, -0.2f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, //L
1.0f, 0.0f, -0.15f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, //O
1.0f, -0.1f, -0.15f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, //P
//Top to Grip //Positive Y
1.0f, 0.0f, -0.15f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, //O
1.0f, 0.0f, 0.05f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, //M
0.6f, 0.0f, -0.2f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, //J
1.0f, 0.0f, 0.05f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0, //M
0.6f, 0.0f, -0.2f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, //J
0.6f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, //I
//Base of Grip //Positive X
1.0f, 0.0f, 0.05f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, //M
1.0f, -0.1f, 0.05f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, //N
1.0f, 0.0f, -0.15f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, //O
1.0f, -0.1f, 0.05f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, //N
1.0f, 0.0f, -0.15f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, //O
1.0f, -0.1f, -0.15f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f //P
};
//Generate buffer ids
glGenVertexArrays(1, &SpoonVAO);
glGenBuffers(1, &VBO);
//Activate the Vertex Array Object before binding and setting any VBOs and Vertex Attribute Pointers.
glBindVertexArray(SpoonVAO);
//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, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0); //Enables vertex attribute
//Set attribute pointer 1 to hold Normal data
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1); //Enables vertex attribute
//Set attribute pointer 2 to hold Texture coordinate data
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glBindVertexArray(0); //Deactivate the Spoon VAO which is good practice
}
void pressSpecialKey(int key, int xx, int yy)
{
switch(key){
//Zoom object in
case GLUT_KEY_UP:
front.x += 0.1f;
front.y += 0.1f;
front.z += 0.1f;
break;
//Zoom object out
case GLUT_KEY_DOWN:
front.x -= 0.1f;
front.y -= 0.1f;
front.z -= 0.1f;
break;
//Change view to orthogonal state
case GLUT_KEY_LEFT:
view_state = 0;
break;
//Change view to perspective state
case GLUT_KEY_RIGHT:
view_state = 1;
break;
}
}
/*Implements the UMouseMove function*/
void UMouseMove(int x, int y)
{
//Immediately replaces center locked coordinated with new mouse coordinates
if(mouseDetected)
{
lastMouseX = x;
lastMouseY = y;
mouseDetected = false;
}
//Gets the direction the mouse was moved in x and y
mouseXOffset = x - lastMouseX;
mouseYOffset = lastMouseY - y; //Inverted Y
//Updates with new mouse coordinates
lastMouseX = x;
lastMouseY = y;
//Applies sensitivity to mouse direction
mouseXOffset *= sensitivity;
mouseYOffset *= sensitivity;
//Accumulates the yaw and pitch variables
yaw += mouseXOffset;
pitch += mouseYOffset;
//Maintains a 90 degree pitch for gimbal lock
if(pitch > 89.0f)
pitch = 89.0f;
if(pitch < -89.0f)
pitch = -89.0f;
//Converts mouse coordinates / degrees into Radians, then to vectors
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));
}
/*Generate and load the texture*/
void UGenerateTexture(){
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
int width, height;
unsigned char* image = SOIL_load_image("spoon.jpg", &width, &height, 0, SOIL_LOAD_RGB); //Loads texture file
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); //Unbind the texture
}
Expected: Spoon in center of the screen, mousemovement changes the camera view (horizontally and vertically), up arrow causes camera to zoom in, and down arrow causes camera to zoom out.
Actual: Spoon not in center. Mousemovement causes the object to move (horizontally and vertically). Arrows not detected (?).
Zooming at perspective projection can be achieved by shifting the the camera position along the line of sight:
void pressSpecialKey(int key, int xx, int yy)
{
switch(key){
case GLUT_KEY_UP: cameraPosition += front * 0.1f; break;
case GLUT_KEY_DOWN: cameraPosition -= front * 0.1f; break;
// [...]
}
or by changing the field of view angle:
float fov_angle = 45.0f;
projection = glm::perspective(glm::radians(fov_angle),
(GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
void pressSpecialKey(int key, int xx, int yy)
{
switch(key){
case GLUT_KEY_UP: fov_angle -= 0.1f; break;
case GLUT_KEY_DOWN: fov_angle += 0.1f; break;
// [...]
}
If you want to keep the spoon in the center of the view ant to orbit around the spoon, then you've to change the camera position according to the viewing direction:
void UMouseMove(int x, int y)
{
// [...]
cameraPosition = - front * glm::length( cameraPosition );
}
The matrices of the OpenGL Mathematics (GLM) have to be initialized. An identity matrix can be initialized by the single parameter 1.0:
e.g.
glm::mat4 model(1.0f);
The angles which are passed to the OpenGL Mathematics (GLM) library functions have to be set in radians rather than degrees. (In glm version 0.9.4 or less this was different).
glm::perspective():
LM_FUNC_DECL tmat4x4<T, defaultp> glm::perspective(T fovy, T aspect, T near, T far)
Creates a matrix for a symetric perspective-view frustum based on the default handedness.
Parameters
fovy Specifies the field of view angle in the y direction. Expressed in radians.
glm::rotate()
GLM_FUNC_DECL mat<4, 4, T, Q> glm::rotate (mat< 4, 4, T, Q > const & m, T angle, vec<3, T, Q> const & axis)
Builds a rotation 4 * 4 matrix created from an axis vector and an angle.
Parameters
angle Rotation angle expressed in radians.
Initialize the matrices and use glm::radians() to convert from degree to radians:
//Transforms the object
glm::mat4 model(1.0f); // <--- init
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); //Place the object at the center of the viewport
// model = glm::rotate(model, 45.0f, glm:: vec3(0.0, 1.0f, 0.0f));
model = glm::rotate(model, glm::radians(45.0f), glm:: vec3(0.0, 1.0f, 0.0f));
model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f)); //Increase the object size by a scale of 2
//Transform the camera
glm::mat4 view(1.0f); // <--- init
view = glm::lookAt(cameraPosition - CameraForwardZ, cameraPosition, CameraUpY);
//Creates a perspective projection
glm::mat4 projection(1.0f); // <--- init
if(view_state == 1){
// projection = glm::perspective(45.0f,
(GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
projection = glm::perspective(glm::radians(45.0f),
(GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);
} else if(view_state == 0){
projection = glm::ortho(-5.0f, 5.0f, -5.0f, 5.0f, 0.1f, 100.0f);
}

Perspective Matrix not drawing object correctly

My perspective matrix is doing a weird thing where it makes my 3d pyramid look like a trapezoid.
This is the effect im getting
Angle 1
Angle 2
If I rotate the pyramid this effect is consistent so I don't think it has anything to do with my vertices. What is causing this effect to occur?
Animation Loop:
//enables depth testing
glEnable(GL_DEPTH_TEST);
//creates aspect ratio variable
float aspect = 500.0f / 500.0f;
//enables projection matrix
glm::mat4 pmat = glm::perspective(70.0f, aspect, 0.01f, 1000.0f);
//enables view matrix
glm::vec3 eye(0, -1, 2);
glm::vec3 center(0, 0, 0);
glm::vec3 up(0, 1, 0);
glm::mat4 vmat = glm::lookAt(eye, center, up);
while (!glfwWindowShouldClose(mWindow)) //animation loop
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 mvp = pmat * vmat * tmat;
glUniformMatrix4fv(uTransform, 1, GL_FALSE, glm::value_ptr(mvp));
for (int i = 0; i <= numberofshapes; i++)
{
glBindVertexArray(shapes[i].vao);
glDrawArrays(shapes[i].drawtype, 0, shapes[i].numOfvertices);
}
if (w == true) {
tmat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.001f, 0.0f)) * tmat;
}if (a == true) {
tmat = glm::translate(glm::mat4(1.0f), glm::vec3(-0.001f, 0.0f, 0.0f)) * tmat;
}if (s == true) {
tmat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -0.001f, 0.0f)) * tmat;
}if (d == true) {
tmat = glm::translate(glm::mat4(1.0f), glm::vec3(0.001f, 0.0f, 0.0f)) * tmat;
}if (r == true) {
tmat = glm::rotate(glm::mat4(1.0f), glm::radians(0.1f), glm::vec3(0.0f, 1.0f, 0.0f)) * tmat;
}
glfwSwapBuffers(mWindow);
counter += 1;
glfwPollEvents();
}
Vertex Arrays:
vertex vertices[] = {
mkVert(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f),
mkVert(-0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f),
mkVert(0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f)
};
//SECOND OBJECT
vertex vertices2[] = {
mkVert(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f),
mkVert(-0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f),
mkVert(-0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f)
};
//THIRD OBJECT
vertex vertices3[] = {
mkVert(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f),
mkVert(0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f),
mkVert(0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f)
};
vertex vertices4[] = {
mkVert(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f),
mkVert(0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f),
mkVert(-0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f)
};
Just fyi my window is 500x500, I dont know if that would cause this effect.
Your camera is pointing at your pyramid from below. I guess your brain expected to look at it from above!? Especially with just a wireframe, this can get confusing. So here's a GIF of a pyramid being looked at from below:

OpenGL - Going 3D

I have a script that I am unable to make fully 3D. So far on ortho the background shows up only. In perspective, almost nothing shows up but when I move the camera it does change color.
projection = glm::perspective(glm::radians(44.0f), static_cast<GLfloat>(Width) / static_cast<GLfloat>(Height), 0.1f, 100.0f);
projection = glm::ortho(0.0f, static_cast<GLfloat>(Width), static_cast<GLfloat>(Height), 0.0f, -1.0f, 1.0f);
See below for images:
Image 1:
3D version - Ortho
Image 2:
3D version - Ortho
Image 3:
2D version - Stable and works perfectly
Here is my code that creates and renders sprites:
#ifndef SPRITE_H
#define SPRITE_H
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "ShaderClass.h"
#include "TextureClass.h"
class Sprite
{
public:
Shader shader;
// Set up Vertex Array Object && Vertex Buffer Object
GLuint VAO,
VBO;
// Constructor
Sprite(Shader &shader){ this->shader = shader; setBuffers(); }
// Deconstructor
~Sprite(){ glDeleteVertexArrays(1, &VAO); }
// Initializes and configures the buffers and vertex attributes
void setBuffers()
{
// Define vertices for the sprite
GLfloat vertices[] = {
// x y z u v
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.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,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.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, 0.0f, 1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
//
// OpenGL buffers
// Initialization code using Vertex Array Object (VAO) (done once (unless the object frequently changes))
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// Copy our vertices array in a buffer for OpenGL to use
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Bind Vertex Array Object
glBindVertexArray(VAO);
//Attributes
glEnableVertexAttribArray(0); // location = 0
glVertexAttribPointer(
0, // location = 0
3, // 3 components (x, y, z)
GL_FLOAT, GL_FALSE,
5 * sizeof(GLfloat), // stride: 5 * float (x, y, z, u, v)
(GLvoid*)0); // offset: 0
glEnableVertexAttribArray(1); // location = 1
glVertexAttribPointer(
1, // location = 1
2, // 2 components (u, v)
GL_FLOAT, GL_FALSE,
5 * sizeof(GLfloat), // stride: 5 * float (x, y, z, u, v)
(GLvoid*)(3 * sizeof(GLfloat))); // offset: 3 * float (x, y, z)
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//Unbind the VAO
glBindVertexArray(0);
}
// Renders the sprite
void DrawSprite(Texture &texture, glm::vec2 position, glm::vec2 size = glm::vec2(10, 10), GLfloat rotate = 0.0f, glm::vec3 colour = glm::vec3(1.0f))
{
// Apply the shader
this->shader.Use();
// Transform the object
glm::mat4 transformObject;
transformObject = glm::translate(transformObject, glm::vec3(position, 0.0f));
transformObject = glm::translate(transformObject, glm::vec3(0.5f * size.x, 0.5f * size.y, 0.0f));
transformObject = glm::rotate(transformObject, rotate, glm::vec3(0.0f, 0.0f, 1.0f));
transformObject = glm::translate(transformObject, glm::vec3(-0.5f * size.x, -0.5f * size.y, 0.0f));
transformObject = glm::scale(transformObject, glm::vec3(size, 1.0f));
this->shader.SetVector3f("spriteColour", colour);
this->shader.SetMatrix4("transformObject", transformObject);
glActiveTexture(GL_TEXTURE0);
// Bind the appropriate texture to *this* model
texture.Bind();
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36 * 5);
glBindVertexArray(0);
}
};
#endif
These are the shaders that I am using:
Vertex shader:
#version 440 core
layout (location = 0) in vec3 Position;
layout (location = 1) in vec2 texCoord;
out vec2 TexCoords;
uniform mat4 transformObject;
uniform mat4 view;
uniform mat4 projection;
void main()
{
TexCoords = vec2(texCoord.x, texCoord.y);
gl_Position = projection * view * transformObject * vec4(Position.x, Position.y, Position.z, 1.0);
}
Fragment shader:
#version 440 core
in vec2 TexCoords;
out vec4 colour;
uniform sampler2D tex;
uniform vec3 spriteColour;
void main()
{
colour = vec4(spriteColour, 1.0) * texture(tex, TexCoords);
}

OpenGL - translation stretches and distorts sprite

I am loosely following the very handy tutorial at opengl-tutorial.org. I've been able to create a mesh, draw a sprite to it, and rotate and scale that mesh perfectly fine.
However, I'm running into some issues when trying to translate the mesh. (pictures below)
Here's an update function on the sprite:
Transform* transform = static_cast<Transform*>(owner->GetComponent(CID_TRANSFORM));
glUseProgram(shaderID_);
glm::mat4 projection = glm::perspective(45.0f , 4.0f / 3.0f, 0.1f, 100.0f);
glm::mat4 view = glm::lookAt(
glm::vec3(3, 3, 3),
glm::vec3(0, 0, 0),
glm::vec3(0, 1, 0)
);
glm::mat4 model = transform->GetModelMatrix();
glm::mat4 mvp = projection * view * model;
GLuint matrixID = glGetUniformLocation(shaderID_, "MVP");
glUniformMatrix4fv(matrixID, 1, GL_FALSE, &mvp[0][0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_);
glUniform1i(samplerID_, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer_);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvBuffer_);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_TRIANGLES, 0, 3 * 2);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
And here's the getModelMatrix function:
glm::mat4 Transform::GetModelMatrix()
{
glm::mat4 trans = glm::mat4(
1.0f, 0.0f, 0.0f, translation.x,
0.0f, 1.0f, 0.0f, translation.y,
0.0f, 0.0f, 1.0f, translation.z,
0.0f, 0.0f, 0.0f, 1.0f);
float xCos = glm::cos(rotation.x);
float xSin = glm::sin(rotation.x);
float yCos = glm::cos(rotation.y);
float ySin = glm::sin(rotation.y);
float zCos = glm::cos(rotation.z);
float zSin = glm::sin(rotation.z);
glm::mat4 xRotation = glm::mat4(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, xCos, -xSin, 0.0f,
0.0f, xSin, xCos, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
glm::mat4 yRotation = glm::mat4(
yCos, 0.0f, ySin, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
-ySin, 0.0f, yCos, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
glm::mat4 zRotation = glm::mat4(
zCos, -zSin, 0.0f, 0.0f,
zSin, zCos, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
glm::mat4 rot = xRotation * yRotation * zRotation;
glm::mat4 sca = glm::mat4(
scale.x, 0.0f, 0.0f, 0.0f,
0.0f, scale.y, 0.0f, 0.0f,
0.0f, 0.0f, scale.z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
return trans * rot * sca;
}
Here is the sprite at the origin viewed from (3, 3, 3).
Here is the sprite translated to (1, 0, 0) viewed from (3, 3, 3).
Matching OpenGL, GLM stores matrices in column major order. The constructors also expect elements to be specified in the same order.
However, your translation matrix is specified in row major order:
glm::mat4 trans = glm::mat4(
1.0f, 0.0f, 0.0f, translation.x,
0.0f, 1.0f, 0.0f, translation.y,
0.0f, 0.0f, 1.0f, translation.z,
0.0f, 0.0f, 0.0f, 1.0f);
To specify the matrix in the correct column major order, this needs to be:
glm::mat4 trans = glm::mat4(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
translation.x, translation.y, translation.z, 1.0f);