OpenGL: how to draw a axis indicator at the top right corner - opengl

I am rendering 3d scene with OpenGL. Users are allowed to orbit the scene. Besides the objects in the scene, I want to draw a axis indicator at the top right or bottom left corner to show the current roation status.
Something like the viewport widget at the top right corner in Blender.
Can anyone tell me the direction to do it?

The way I would do it is to:
First- Render your scene;
Second- Render the axis indicator (view cube) on its own to a texture attachment in a frame buffer.
Third- Render the resulting texture to a quad in the top-right of your screen.
Something similar to this: https://learnopengl.com/Advanced-OpenGL/Framebuffers

Very briefly explained, once you have a 3D axis, you start by drawing the 3D axis at camera.Position + camera.Front * smallDist, so it always draws at the center of the screen.
Then, you use glViewport(...) to set the viewport to the corner of the screen, and draw the axis. You can also use eg. glLineWidth(3.0f) to make the lines stand out more.
Here's a rough idea:
#include <iostream>
#include <vector>
#include <math.h>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/ext.hpp>
// camera.h is from basic camera learnopengl tutorial
#include "camera.h"
using glm::mat4;
using glm::vec3;
using glm::radians;
using glm::lookAt;
using std::vector;
void processInput(GLFWwindow *window);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
float lastX = SCR_WIDTH / 2.0f;
float lastY = SCR_HEIGHT / 2.0f;
bool firstMouse = true;
// timing
float deltaTime = 0.0f; // time between current frame and last frame
float lastFrame = 0.0f;
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
class Line {
int shaderProgram;
unsigned int VBO, VAO;
vector<float> vertices;
vec3 startPoint;
vec3 endPoint;
mat4 MVP = mat4(1.0);
vec3 lineColor;
public:
Line(vec3 start, vec3 end) {
startPoint = start;
endPoint = end;
lineColor = vec3(1,1,1);
const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"uniform mat4 MVP;\n"
"void main()\n"
"{\n"
" gl_Position = MVP * vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"uniform vec3 color;\n"
"void main()\n"
"{\n"
" FragColor = vec4(color, 1.0f);\n"
"}\n\0";
// vertex shader
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// check for shader compile errors
// fragment shader
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// check for shader compile errors
// link shaders
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// check for linking errors
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
vertices = {
start.x, start.y, start.z,
end.x, end.y, end.z,
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices)*vertices.size(), vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
int setMVP(mat4 mvp) {
MVP = mvp;
return 1;
}
int setColor(vec3 color) {
lineColor = color;
return 1;
}
int draw() {
glUseProgram(shaderProgram);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "MVP"), 1, GL_FALSE, &MVP[0][0]);
glUniform3fv(glGetUniformLocation(shaderProgram, "color"), 1, &lineColor[0]);
glBindVertexArray(VAO);
glDrawArrays(GL_LINES, 0, 2);
return 1;
}
~Line() {
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
}
};
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, "drawing lines", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwMakeContextCurrent(window);
glfwSetCursorPosCallback(window, mouse_callback);
// glad: load all OpenGL function pointers
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
camera.Position = vec3(0,0,3);
camera.MovementSpeed = 0.01f;
// 3d lines example
Line line1(vec3(0,0,0), vec3(0.04,0,0));
line1.setColor(vec3(1,0,0));
Line line2(vec3(0,0,0), vec3(0,0.04,0));
line2.setColor(vec3(0,1,0));
Line line3(vec3(0,0,0), vec3(0,0,0.04));
line3.setColor(vec3(0,0,1));
Line line4(vec3(0,0,0), vec3(10,0,0));
line4.setColor(vec3(1,0,0));
Line line5(vec3(0,0,0), vec3(0,10,0));
line5.setColor(vec3(0,1,0));
Line line6(vec3(0,0,0), vec3(0,0,10));
line6.setColor(vec3(0,0,1));
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float) SCR_WIDTH / (float)SCR_HEIGHT, 0.01f, 1000.0f);
// render loop
// -----------
while (!glfwWindowShouldClose(window))
{
float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
// input
// -----
processInput(window);
// render
// ------
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.01f, 1000.0f);
glm::mat4 view = camera.GetViewMatrix();
float ar = (float)SCR_WIDTH / (float)SCR_HEIGHT;
float fov = 45.0f;
float nearDist = 0.01f;
float Hnear = 2.0f * tan(glm::radians(fov/2)) * nearDist;
float Wnear = Hnear * ar;
glm::vec3 axisPosition = camera.Position + glm::normalize(camera.Front) * 0.2f;
line1.setMVP(projection * view * glm::translate(glm::mat4(1.0f), axisPosition));
line2.setMVP(projection * view * glm::translate(glm::mat4(1.0f), axisPosition));
line3.setMVP(projection * view * glm::translate(glm::mat4(1.0f), axisPosition));
glViewport(SCR_WIDTH-SCR_WIDTH/10.0f,SCR_HEIGHT-SCR_HEIGHT/10.0f,SCR_WIDTH/10.0f,SCR_HEIGHT/10.0f);
glLineWidth(3.0f);
line1.draw();
line2.draw();
line3.draw();
glLineWidth(1.0f);
glViewport(0,0,SCR_WIDTH, SCR_HEIGHT);
line4.setMVP(projection * view);
line5.setMVP(projection * view);
line6.setMVP(projection * view);
line4.draw();
line5.draw();
line6.draw();
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
glfwTerminate();
return 0;
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
camera.ProcessKeyboard(FORWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);
}
// glfw: whenever the mouse moves, this callback is called
// -------------------------------------------------------
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 since y-coordinates go from bottom to top
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);
}
Result:

Related

Camera movement in OpenGL raymarched scene

I'm working on a project with OpenGL that uses raymarched graphics and I've run into some trouble controlling the camera.
The scene is generated entirely inside the vertex shader, which is rendered on a 4-vertex plane situated in front of the viewport. My input function gets key-presses and and mouse movement from the user and calculates the translation and rotation of the camera which gets passed into the fragment shader.
The problem is that the rotation and movement of the camera behaves very strangely. Not only does simultaneous pitch and yaw cause the camera to roll (even though I'm using quaternions to calculate rotation), but the camera movement (WASD) seems to only move along the world's X and Z axes rather than the camera's relative axes.
Any help with fixing this would be greatly appreciated.
main.cpp:
#include <iostream>
#include <string>
#include <glad/glad.h>
#include <glfw/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "readshader.h"
#include "input.h"
#define GLM_SWIZZLE_XYZ
#define WIDTH 640
#define HEIGHT 480
using namespace std;
using namespace glm;
int main() {
GLFWwindow* window;
//Vertex array for screen plane
float vertices[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f
};
unsigned int vbo;
unsigned int vao;
unsigned int vs;
unsigned int fs;
unsigned int shader_prog;
//Game logic variables
vec3 camera_pos = vec3(0.0f, 0.0f, 0.0f);
quat camera_rot = quat(0.0f, 0.0f, 0.0f, 0.0f);
vec2 screen_size = vec2(float(WIDTH), float(HEIGHT));
float delta_time = 0.0;
float last_time = 0.0;
unsigned int a_camera_pos;
unsigned int a_camera_rot;
unsigned int a_screen_size;
unsigned int a_delta_time;
//Read shader code from GLSL files
string vs_str = readShader("vert_pass.glsl");
string fs_str = readShader("frag_raymarch_test.glsl");
const char* vs_source = vs_str.c_str();
const char* fs_source = fs_str.c_str();
//Initialize GLFW and create window
glfwInit();
window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
glViewport(0, 0, WIDTH, HEIGHT);
//Set GLFW input parameters
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
glfwSetCursorPosCallback(window, mouseCallback);
//Create VAO and VBO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//Compile shaders and create shader program
vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vs_source, NULL);
glCompileShader(vs);
fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fs_source, NULL);
glCompileShader(fs);
shader_prog = glCreateProgram();
glAttachShader(shader_prog, vs);
glAttachShader(shader_prog, fs);
glLinkProgram(shader_prog);
glDetachShader(shader_prog, vs);
glDetachShader(shader_prog, fs);
glDeleteShader(vs);
glDeleteShader(fs);
glUseProgram(shader_prog);
//Setup attribute arrays and uniform variables for vertex shader
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0);
a_camera_pos = glGetUniformLocation(shader_prog, "vert_camera_pos");
a_camera_rot = glGetUniformLocation(shader_prog, "vert_camera_rot");
a_screen_size = glGetUniformLocation(shader_prog, "vert_screen_size");
a_delta_time = glGetUniformLocation(shader_prog, "vert_delta_time");
//Main event loop
while (!glfwWindowShouldClose(window)) {
//Calculate delta time
delta_time = glfwGetTime() - last_time;
last_time = glfwGetTime();
//Pass game information to shader program
glProgramUniform3fv(shader_prog, a_camera_pos, 1, value_ptr(camera_pos));
glProgramUniform4fv(shader_prog, a_camera_rot, 1, value_ptr(camera_rot));
glProgramUniform2fv(shader_prog, a_screen_size, 1, value_ptr(screen_size));
glProgramUniform1f(shader_prog, a_delta_time, delta_time);
//Process user input
input(window, &camera_pos, &camera_rot, delta_time);
//Rendering procedure
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glfwSwapBuffers(window);
}
//Cleanup and exit
glDeleteProgram(shader_prog);
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
input.h:
#pragma once
#include <iostream>
#include <glfw/glfw3.h>
#include <glm/glm.hpp>
#define GLM_SWIZZLE_XYZW
#define SPEED 5.0
#define SENS 0.001
using namespace glm;
float camera_pitch = 0.0;
float camera_yaw = 0.0;
bool first = true;
float lastx = 0.0;
float lasty = 0.0;
float offsetx;
float offsety;
void input(GLFWwindow* window, vec3* camera_pos, quat* camera_rot, float delta_time) {
float step = SPEED * delta_time;
vec3 camera_fwd = vec3(0.0f, 0.0f, -1.0f);
vec3 camera_up = vec3(0.0f, 1.0f, 0.0f);
vec3 camera_right = vec3(-1.0f, 0.0f, 0.0f);
quat quatx;
quat quaty;
glfwPollEvents();
//Build rotation quaternion from camera angles
quatx = angleAxis(camera_yaw, camera_up);
quaty = angleAxis(camera_pitch, camera_right);
*camera_rot = quatx * quaty;
//Update camera axis positions
camera_fwd = *camera_rot * camera_fwd * conjugate(*camera_rot);
camera_right = *camera_rot * camera_right * conjugate(*camera_rot);
//Check keyboard presses
if (glfwGetKey(window, GLFW_KEY_W)) {
*camera_pos -= camera_fwd * step;
}
if (glfwGetKey(window, GLFW_KEY_S)) {
*camera_pos += camera_fwd * step;
}
if (glfwGetKey(window, GLFW_KEY_A)) {
*camera_pos -= normalize(cross(camera_fwd, camera_up)) * step;
}
if (glfwGetKey(window, GLFW_KEY_D)) {
*camera_pos += normalize(cross(camera_fwd, camera_up)) * step;
}
if (glfwGetKey(window, GLFW_KEY_SPACE)) {
*camera_pos += camera_up * step;
}
if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL)) {
*camera_pos -= camera_up * step;
}
}
void mouseCallback(GLFWwindow* window, double posx, double posy) {
if (first) {
lastx = -posx;
lasty = -posy;
first = false;
}
offsetx = -posx - lastx;
offsety = lasty + posy;
lastx = -posx;
lasty = -posy;
offsetx *= SENS;
offsety *= SENS;
camera_yaw += offsetx;
camera_pitch += offsety;
if (camera_pitch > 89.0) {
camera_pitch = 89.0;
}
if (camera_pitch < -89.0) {
camera_pitch = -89.0;
}
}
vertex_pass.glsl:
#version 460
//Passes variables from attributes to next shader
layout(location = 0) in vec3 pos;
uniform vec3 vert_camera_pos;
uniform vec4 vert_camera_rot;
uniform vec2 vert_screen_size;
uniform float vert_delta_time;
out vec3 camera_pos;
out vec4 camera_rot;
out vec2 screen_size;
out float delta_time;
void main() {
gl_Position = vec4(pos, 1.0);
camera_pos = vert_camera_pos;
camera_rot = vert_camera_rot;
screen_size = vert_screen_size;
delta_time = vert_delta_time;
}
frag_raymarch_test.glsl:
#version 460
#define MAX_STEPS 100
#define MAX_DIST 10000.0
#define SURF_DIST 0.001
#define NORMAL_SAMPLE_SIZE 0.001
#define TAU 6.283185
#define PI 3.141592
in vec3 camera_pos;
in vec4 camera_rot;
in vec2 screen_size;
in float delta_time;
out vec3 color;
vec3 rotateVector(vec4 quat, vec3 vec) {
return vec + 2.0 * cross(cross(vec, quat.xyz) + quat.w * vec, quat.xyz);
}
//SDF
float getSD(vec3 p) {
vec4 s = vec4(0, 1, 6, 1);
float sphere_dist = length(p - s.xyz) - s.w;
float plane_dist = p.y;
float d = min(sphere_dist, plane_dist);
return d;
}
float getDist(vec3 p) {
float dist = 0;
//SDF
dist = getSD(p);
return dist;
}
float raymarch(vec3 ro, vec3 rd) {
float dist = 0.0;
for(int i = 0; i < MAX_STEPS; i++) {
vec3 p = ro + rd * dist;
dist += getDist(p);
if(dist >= MAX_DIST || dist <= SURF_DIST) {
break;
}
}
return dist;
}
void main() {
vec2 uv = (gl_FragCoord.xy - 0.5 * screen_size) / screen_size.y;
//vec3 ro = vec3(0.0, 1.0, 0.0);
//vec3 ro = camera_pos;
vec3 ro = camera_pos;
vec3 fd = normalize(vec3(uv.x, uv.y, 1.0));
vec3 rd = rotateVector(camera_rot, fd);
color = vec3(raymarch(ro, rd) / 6.0);
}
Figured it out. I went back to using Euler angles instead of quaternions and using them to compute a forward vector for the camera. The problem was that, in the fragment shader, I was using the camera_fwd vector for the look at point when I should have been using camera_pos + camera_fwd.

How I can avoid in OpenGL disappearing lines using a shader?

So I'm drawing some lines by just using a fragment shader. The vertex it's just an empty quad.
The issue I have is that when I zoom out the camera and the lines get smaller they sometimes appear and disappear and I don't understand why.
This is how it looks without zooming
and this is how it looks when the camera is far away from them
The more far away I get from them the more artefacts appear.
This is how my vertex shader looks
#version 330 core
layout(location = 0) in vec2 _position;
out vec2 position;
uniform mat4 uCameraView;
void main() {
gl_Position = uCameraView * vec4(_position.x, _position.y, 0.0f, 1.0f);
position = _position;
}
And this is the fragment
#version 330 core
in vec2 position;
uniform vec4 uGridColor;
uniform float uTileSize;
uniform float uGridBorderSize;
out vec4 fragColor;
void main() {
vec2 uv = mod(position, uTileSize);
vec2 border = mod(uv + (uGridBorderSize / 2.0), uTileSize);
border -= mod(uv - (uGridBorderSize / 2.0), uTileSize);
if (length(border) > uTileSize - uGridBorderSize) {
fragColor = uGridColor;
} else {
fragColor = vec4(0.0);
}
}
Why it's this happening? maybe is something related to antialiasing? My OpenGL setup it's just the default one.
Your current code is making a binary decision "yes line" / "no line". However beyond a certain point (line width < pixel width) you're effectivly dealing with spatial frequencies above the Nyquist limit.
Instead of using a binary "yes"/"no" you need to calculate the pixel coverage, i.e. how much line is inside a pixel. For that you'd normally use a unsigned distance function (UDF). Here's some GLSL code for UDF lines in pixel space (you can also use them in normalized space, but then you'll have to adjust the smoothstep parameters). Try this on https://shadertoy.com
float lsd(vec2 a, vec2 b, vec2 p, float w){
w *= 0.5;
vec2 n = normalize(b-a);
float l = length(b-a);
float t = dot((p-a),n);
float d = length((a-p)+t*n);
float e = min(length(p-a)+w, length(p-b)+w);
return (t > w && t < l-w) ? d : e;
}
float line(vec2 a, vec2 b, float width, vec2 fragcoord){
return max(0., 1.-smoothstep(0., 1., lsd(a, b, fragcoord, width)-0.5*width));
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float l =
line(vec2(8.,8.), vec2(128.,33.), 1., fragCoord)
+ line(vec2(33.,220.), vec2(260.,20.), 4., fragCoord);
fragColor = vec4(l,l,l,1.0);
}
It is hard to tell based on your shaders alone, so here is an example of how to zoom and pan around a line grid. It uses a projection matrix to zoom which looks slightly different to how you implemented the zoom, but the important bit is that it doesn't have any artefacts of lines thinning when zooming/panning.
Here is a demonstration, hopefully the GIF shows it, but the grid lines are constant thickness as you zoom in and out:
#include <iostream>
#include <vector>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/string_cast.hpp>
using std::vector;
using glm::mat4;
using glm::vec3;
using glm::vec4;
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;
float lastX = SCR_WIDTH / 2.0f;
float lastY = SCR_HEIGHT / 2.0f;
bool firstMouse = true;
// timing
float deltaTime = 0.0f;
float lastFrame = 0.0f;
vec3 rayCast(double xpos, double ypos, mat4 projection, mat4 view) {
// converts a position from the 2d xpos, ypos to a normalized 3d direction
float x = (2.0f * xpos) / SCR_WIDTH - 1.0f;
float y = 1.0f - (2.0f * ypos) / SCR_HEIGHT;
float z = 1.0f;
vec3 ray_nds = vec3(x, y, z);
vec4 ray_clip = vec4(ray_nds.x, ray_nds.y, -1.0f, 1.0f);
// eye space to clip we would multiply by projection so
// clip space to eye space is the inverse projection
vec4 ray_eye = inverse(projection) * ray_clip;
// convert point to forwards
ray_eye = vec4(ray_eye.x, ray_eye.y, -1.0f, 0.0f);
// world space to eye space is usually multiply by view so
// eye space to world space is inverse view
vec4 inv_ray_wor = (inverse(view) * ray_eye);
vec3 ray_wor = vec3(inv_ray_wor.x, inv_ray_wor.y, inv_ray_wor.z);
ray_wor = normalize(ray_wor);
return ray_wor;
}
class Line {
int shaderProgram;
unsigned int VBO, VAO;
vector<float> vertices;
vec3 startPoint;
vec3 endPoint;
mat4 MVP;
vec3 lineColor;
public:
Line(vec3 start, vec3 end) {
startPoint = start;
endPoint = end;
lineColor = vec3(1,1,1);
const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"uniform mat4 MVP;\n"
"void main()\n"
"{\n"
" gl_Position = MVP * vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"uniform vec3 color;\n"
"void main()\n"
"{\n"
" FragColor = vec4(color, 1.0f);\n"
"}\n\0";
// vertex shader
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// check for shader compile errors
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// fragment shader
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// check for shader compile errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// link shaders
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// check for linking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
vertices = {
start.x, start.y, start.z,
end.x, end.y, end.z,
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
int setMVP(mat4 mvp) {
MVP = mvp;
}
int setColor(vec3 color) {
lineColor = color;
}
int draw() {
glUseProgram(shaderProgram);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "MVP"), 1, GL_FALSE, &MVP[0][0]);
glUniform3fv(glGetUniformLocation(shaderProgram, "color"), 1, &lineColor[0]);
glBindVertexArray(VAO);
glDrawArrays(GL_LINES, 0, 2);
return 0;
}
~Line() {
// optional: de-allocate all resources once they've outlived their purpose:
// ------------------------------------------------------------------------
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
}
};
vec3 cameraPos = glm::vec3(0.0f, 0.0f, 15.0f);
vec3 cameraFront = glm::vec3(0,0,-1);
mat4 model = mat4(1.0);
glm::mat4 view;
glm::mat4 projection;
float scrollSpeed = 2.0f;
float fov = 45.0f;
int main()
{
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
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "grid", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
Line x(vec3(0,0,0), vec3(1,0,0));
x.setColor(vec3(1,0,0));
Line y(vec3(0,0,0), vec3(0,1,0));
y.setColor(vec3(0,1,0));
std::vector<Line*> grid = {};
for (int i = -5; i < 6; i++) {
grid.push_back(new Line(vec3(-5, i, 0), vec3(5,i, 0)));
}
for (int j = -5; j < 6; j++) {
grid.push_back(new Line(vec3(j, -5, 0), vec3(j,5, 0)));
};
while (!glfwWindowShouldClose(window))
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
view = glm::lookAt(cameraPos, cameraPos + cameraFront, vec3(0,1,0));
projection = glm::perspective(glm::radians(fov), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
for (int i = 0; i < grid.size(); i++) {
grid[i]->setMVP(projection * view * model);
grid[i]->draw();
}
glfwSwapBuffers(window);
glfwPollEvents();
}
for (int i = 0; i < grid.size(); i++) {
delete grid.at(i);
}
glfwTerminate();
return 0;
}
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
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;
lastX = xpos;
lastY = ypos;
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE);
if (state == GLFW_PRESS)
{
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
cameraPos -= scrollSpeed * glm::vec3(xoffset/(float)SCR_WIDTH, yoffset/(float)SCR_WIDTH, 0);
} else {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
firstMouse = true;
}
}
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
cameraPos += (float)yoffset * rayCast(lastX, lastY, projection, view);
}

In Modern OpenGL, drawing filled circle with GL_TRIANGLE weird z-axis behaviour

I am trying to draw filled circle in modern opengl using GL_TRIANGLE. I am filling circle array for circle vertices, and then I am filling points array using circle vertices to use vertices in triangle.I am using vec4(homogeneous coordinates) and setting vertices z-axis value to 0.0 and using default projection which should be from -1 to 1 ranges for each axis. But somehow, I am getting all screen painted with color instead of circle. Weirdly when I set z-axis value of points other than [0-0.4] range, I can get circle be drawn and when I increase the value of z, it acts like perspective and no matter what I have set to radius, it is getting smaller when z is increased. I could not figure out why z value acts like that.
using namespace Angel;
const int NumVertices = 90;
const double PI = 3.141592653589793238463;
const GLint width = 500;
const GLint height = 500;
vec4 points[NumVertices];
vec4 colors[NumVertices];
vec4 circle[30];
vec4 color = { 1.0,0.0,0.0,1.0 };
vec4 center = { 0.0,0.0,0.0,1.0 };
GLfloat radius = 0.5;
int Index = 0;
void triangle(int b, int c) {
colors[Index] = color; points[Index] = center; Index++;
colors[Index] = color; points[Index] = circle[b%30]; Index++;
colors[Index] = color; points[Index] = circle[c%30]; Index++;
}
void fill() {
for (int i = 0; i < 30; i++)
{
float angle = 2 * PI * i / 30;
vec4 point;
point.x = center.x + (GLfloat)cos(angle) * radius;
point.y = center.y + (GLfloat)sin(angle) * radius;
point.z = 0.0 ; // PROBLEM !!
circle[i] = point;
}
for (int i = 0; i <= 29; i++) {
triangle(i, i + 1);
}
}
void init()
{
fill();
// Create a vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create and initialize a buffer object
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors),
NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(colors), colors);
// Load shaders and use the resulting shader program
GLuint program = InitShader("vshader.glsl", "fshader.glsl");
glUseProgram(program);
// set up vertex arrays
GLuint vPosition = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(0));
GLuint vColor = glGetAttribLocation(program, "vColor");
glEnableVertexAttribArray(vColor);
glVertexAttribPointer(vColor, 4, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(sizeof(points)));
glEnable(GL_DEPTH_TEST);
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, NumVertices);
glutSwapBuffers();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutInitWindowPosition(100, 100);
glutCreateWindow("PirateFace");
glewExperimental = GL_TRUE;
glewInit();
init();
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
vertex shader :
#version 150
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
void main()
{
gl_Position = vPosition;
color = vColor;
}
fragment shader :
#version 150
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}
I am using vec4(homogeneous coordinates)
You need to properly initialize the w component of your vec4 values to 1.0.
Note that you do not need to store homogenous coordinates in your input vertex arrays in most scenarios. You can keep the in vec4 in the vertex shader and just use 3-dimensional vectors as input, and the GL will automatically extend the vector to (x,y,z,1).

Create a triangle that continuously rotates around it’s y-axis in OpenGl

Im wondering how to rotate a OpenGL triangle around its Y-Axis in OpenGL,
Ive been able to translate the triangle from object space to clip space.
Im wondering if anyone has any experience with this issue and may be able to lend a hand.
Main.cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <Windows.h>
using namespace std;
using namespace glm;
const int windowWidth = 1024;
const int windowHeight = 768;
GLuint VBO;
const int NUMVERTS = 3;
GLuint gModelToWorldTransformLocation;
GLuint gWorldToViewTransformLocation;
GLuint gProjectionTransformLocation;
struct SimpleVertex
{
vec3 pos;
vec4 colour;
};
static void renderSceneCallBack()
{
static mat4 modelToWorldTransform = mat4(1.0f);
static mat4 worldToViewTransform = lookAt(
vec3(0.0f,0.0f,3.0f), // position of your camera, in world space
vec3(0.0f,0.0f,0.0f), // look at in world space
vec3(0.0f,1.0f,0.0f) // Camera up direction (set to 0,-1,0 to look upside-down)
);
static mat4 projectionTransform = perspective(45.0f, (float)windowWidth / (float)windowHeight, 1.0f, 100.0f);
glUniformMatrix4fv(gModelToWorldTransformLocation, 1, GL_FALSE, &modelToWorldTransform[0][0]);
glUniformMatrix4fv(gWorldToViewTransformLocation, 1, GL_FALSE, &worldToViewTransform[0][0]);
glUniformMatrix4fv(gProjectionTransformLocation, 1, GL_FALSE, &projectionTransform[0][0]);
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(SimpleVertex), 0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(SimpleVertex), (const GLvoid*)12);
glDrawArrays(GL_TRIANGLES, 0, NUMVERTS);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glutSwapBuffers();
}
static void initializeGlutCallbacks()
{
glutDisplayFunc(renderSceneCallBack);
glutIdleFunc(renderSceneCallBack);
}
static void createVertexBuffer()
{
// Create some vertices to put in our VBO.
// Create vertex buffer
SimpleVertex vertices[] =
{
{vec3(-0.5f, -0.5f, 0.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)},
{vec3(0.5f, -0.5f, 0.0f), vec4(0.0f, 1.0f, 0.0f, 1.0f)},
{vec3( 0.0f, 0.5f, 0.0f), vec4(0.0f, 0.0f, 1.0f, 1.0f)}
};
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(SimpleVertex) * 3, vertices, GL_STATIC_DRAW);
}
static void addShader(GLuint shaderProgram, const char* pShaderText, GLenum shaderType)
{
GLuint shaderObj = glCreateShader(shaderType);
if (shaderObj == 0)
{
cerr<<"Error creating shader type "<<shaderType<<endl;
exit(0);
}
const GLchar* p[1];
p[0] = pShaderText;
GLint Lengths[1];
Lengths[0]= strlen(pShaderText);
glShaderSource(shaderObj, 1, p, Lengths);
glCompileShader(shaderObj);
GLint success;
glGetShaderiv(shaderObj, GL_COMPILE_STATUS, &success);
if (!success)
{
GLchar InfoLog[1024];
glGetShaderInfoLog(shaderObj, 1024, NULL, InfoLog);
cerr<<"Error compiling shader type "<<shaderType<<": "<<InfoLog<<endl;
exit(1);
}
glAttachShader(shaderProgram, shaderObj);
}
const string readFileToString(char* filename)
{
ifstream file (filename, ios::in);
if (file.is_open())
{
stringstream continut;
continut << file.rdbuf();
continut << '\0';
return continut.str();
}
return "";
}
static void buildShaders()
{
GLuint shaderProgram = glCreateProgram();
if (shaderProgram == 0)
{
cerr<<"Error creating shader program\n";
exit(1);
}
string VS = readFileToString("vertexShader.glsl");
string FS = readFileToString("fragmentShader.glsl");
addShader(shaderProgram, VS.c_str(), GL_VERTEX_SHADER);
addShader(shaderProgram, FS.c_str(), GL_FRAGMENT_SHADER);
GLint success = 0;
GLchar errorLog[1024] = { 0 };
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (success == 0)
{
glGetProgramInfoLog(shaderProgram, sizeof(errorLog), NULL, errorLog);
cerr<<"Error linking shader program: "<<errorLog<<endl;
exit(1);
}
glValidateProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_VALIDATE_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(shaderProgram, sizeof(errorLog), NULL, errorLog);
cerr<<"Error linking shader program: "<<errorLog<<endl;
exit(1);
}
glUseProgram(shaderProgram);
gModelToWorldTransformLocation = glGetUniformLocation(shaderProgram, "gModelToWorldTransform");
//assert(gModelToWorldTransformLocation != 0xFFFFFFFF);
gWorldToViewTransformLocation = glGetUniformLocation(shaderProgram, "gWorldToViewTransform");
//assert(gWorldToViewTransformLocation != 0xFFFFFFFF);
gProjectionTransformLocation = glGetUniformLocation(shaderProgram, "gProjectionTransform");
//assert(gProjectionTransformLocation != 0xFFFFFFFF);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(windowWidth, windowHeight);
glutInitWindowPosition(100, 100);
glutCreateWindow("Transformations");
initializeGlutCallbacks();
// Must be done after glut is initialized!
GLenum res = glewInit();
if (res != GLEW_OK)
{
cerr<<"Error: "<<glewGetErrorString(res)<<"\n";
return 1;
}
buildShaders();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Create a vertex buffer
createVertexBuffer();
glutMainLoop();
return 0;
}
VertexShader
#version 330
layout (location = 0) in vec3 Position;
layout (location = 1) in vec4 Colour;
out vec4 Colour0;
uniform mat4 gModelToWorldTransform;
uniform mat4 gWorldToViewTransform;
uniform mat4 gProjectionTransform;
void main()
{
vec4 vertexPositionInModelSpace = vec4(Position, 1);
vec4 vertexInWorldSpace = gModelToWorldTransform * vertexPositionInModelSpace;
vec4 vertexInViewSpace = gWorldToViewTransform * vertexInWorldSpace;
vec4 vertexInHomogeneousClipSpace = gProjectionTransform * vertexInViewSpace;
gl_Position = vertexInHomogeneousClipSpace;
Colour0 = Colour;
}
FragmentShader
#version 330
in vec4 Colour0;
out vec4 FragColor;
void main()
{
FragColor = Colour0;
}
You can have a float variable for rotation and create rotation matrix from it once then store it. Every frame you should have the world matrix updated like this: modelToWorldTransform = rotationTransform * modelToWorldTransform; See wikipedia for creating the rotation matrix around y: http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
EDIT: I suppose your having trouble with affine transformations. To move (no matter how - translate, rotate) an object in the world, you have to apply a transformation to it.
Currently, you are applying one transformation, which is translation to the position 0, 0, 3.
So far, so good. But your triangle is static(it doesn't move). So to rotate it, you need to apply another transformation (represented by a matrix, again). But if you always apply one and the same rotation, the triangle will be rotated against its original transform but it won't move once again. So you need to apply a rotation every frame, store the result in the modeltoworldtransform and then on next frame repeat the step. e.g in the renderCallback:
static mat4 modelToWorldTransform = mat4(1.0f);
static mat4 rotationTransform = <rotation by the described in wiki way>;
modelToWorldTransform = rotationTransform * modelToWorldTransform;
Also, order of multiplying matrices matters, because their multiplication (which we use to get transform from object to camera space) is not commutative and A * B is different from B * A. I highly recommend you to read more about linear algebra and it will help you understand what happens "behind the scenes". Many books about graphics for game devs explain it in a pretty good and understandable way. "Mathematics for 3D Game Programming and Computer Graphics" by Eric Lengyel kicks ass. It even helped me when I studied maths in university ;).

OpenGL GLM Matrix Calculations Not Working

OpenGL glm calculations don't seem to work in my program. Nothing moves even when i use the glm translate function to translate the z axis with a variable every frame. Am i missing something?
main.cpp
#define GLEW_STATIC
#define NO_SDL_GLEXT
#include "glew.h"
#include <sdl.h>
#undef main
#include "SDL_opengl.h"
#include "timer.h"
#include <time.h>
#include <shader.h>
using namespace std;
#include <glm/gtc/matrix_projection.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
unsigned int vaoID[1]; // Our Vertex Array Object
unsigned int vboID[1]; // Our Vertex Buffer Object
glm::mat4 projectionMatrix; // Store the projection matrix
glm::mat4 viewMatrix; // Store the view matrix
glm::mat4 modelMatrix; // Store the model matrix
Shader *shader; // Our GLSL shader
float ztransform(0);
bool exited(false);
SDL_Event event;
const int FRAMES_PER_SECOND = 60;
void createSquare(void) {
float* vertices = new float[18]; // Vertices for our square
vertices[0] = -0.5; vertices[1] = -0.5; vertices[2] = 0.0; // Bottom left corner
vertices[3] = -0.5; vertices[4] = 0.5; vertices[5] = 0.0; // Top left corner
vertices[6] = 0.5; vertices[7] = 0.5; vertices[8] = 0.0; // Top Right corner
vertices[9] = 0.5; vertices[10] = -0.5; vertices[11] = 0.0; // Bottom right corner
vertices[12] = -0.5; vertices[13] = -0.5; vertices[14] = 0.0; // Bottom left corner
vertices[15] = 0.5; vertices[16] = 0.5; vertices[17] = 0.0; // Top Right corner
glGenVertexArrays(1, &vaoID[0]); // Create our Vertex Array Object
glBindVertexArray(vaoID[0]); // Bind our Vertex Array Object so we can use it
glGenBuffers(1, vboID); // Generate our Vertex Buffer Object
glBindBuffer(GL_ARRAY_BUFFER, vboID[0]); // Bind our Vertex Buffer Object
glBufferData(GL_ARRAY_BUFFER, 18 * sizeof(GLfloat), vertices, GL_STATIC_DRAW); // Set the size and data of our VBO and set it to STATIC_DRAW
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); // Set up our vertex attributes pointer
glEnableVertexAttribArray(0); // Disable our Vertex Array Object
glBindVertexArray(0); // Disable our Vertex Buffer Object
delete [] vertices; // Delete our vertices from memory
}
void startGL()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_SetVideoMode(800, 600, 32, SDL_OPENGL);
glewInit();
glClearColor(0.4f, 0.0f, 1.0f, 0.0f);
projectionMatrix = glm::perspective(60.0f, (float)800 / (float)600, 0.1f, 100.f); // Create our perspective projection matrix
shader = new Shader("shader.vert", "shader.frag"); // Create our shader by loading our vertex and fragment shader
createSquare();
}
void drawstuff()
{
glViewport(0, 0, 800, 600); // Set the viewport size to fill the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Clear required buffers
viewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, ztransform)); // Create our view matrix which will translate us back 5 units
modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f)); // Create our model matrix which will halve the size of our model
shader->bind(); // Bind our shader
int projectionMatrixLocation = glGetUniformLocation(shader->id(), "projectionMatrix"); // Get the location of our projection matrix in the shader
int viewMatrixLocation = glGetUniformLocation(shader->id(), "viewMatrix"); // Get the location of our view matrix in the shader
int modelMatrixLocation = glGetUniformLocation(shader->id(), "modelMatrix"); // Get the location of our model matrix in the shader
glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix[0][0]); // Send our projection matrix to the shader
glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]); // Send our view matrix to the shader
glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]); // Send our model matrix to the shader
glBindVertexArray(vaoID[0]); // Bind our Vertex Array Object
glDrawArrays(GL_TRIANGLES, 0, 6); // Draw our square
glBindVertexArray(0); // Unbind our Vertex Array Object
shader->unbind(); // Unbind our shader
}
int main (int argc, char* args[])
{
Timer fps;
startGL();
while(exited == false)
{
while( SDL_PollEvent(&event) )
{
if( event.type == SDL_QUIT )
exited = true;
}
drawstuff();
ztransform+=.1
SDL_GL_SwapBuffers();
if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
}
SDL_Quit();
return 0;
}
shader.frag
#version 150 core
in vec3 pass_Color;
out vec4 out_Color;
void main(void)
{
out_Color = vec4(pass_Color, 1.0);
}
shader.vert
#version 150 core
in vec3 in_Position;
in vec3 in_Color;
out vec3 pass_Color;
void main(void)
{
gl_Position = vec4(in_Position, 1.0);
pass_Color = in_Color;
}
You have to apply your transformation in your vertex shader.
you should define in your vertex shader
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
And then apply these transformations to your input position (note: i may have gotten the order wrong)
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_position, 1.0);
Generally though, you would multiply the 3 matrices together in your c++ program and pass in a modelViewProjection matrix.