I have been working on a terrain LOD algorithm, but the primary logic is on the CPU:
I tried to convert most of the logic to the tessellation control and evaluation phases of the opengl pipeline, but nothing is displayed:
I reduced the code to a basic "hello quad" program
#define GLEW_STATIC
#include <glew.h>
#include <glfw3.h>
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
/* Shader Source */
// vertex shader
const GLchar * VS_src[] = {
"#version 430\n"
"layout(location = 0) in vec3 position;\n"
"out vec4 vposition;\n"
"void main()\n"
"{\n"
" vposition = vec4(position, 1.0);\n"
"}\n"
};
// tesselation control shader
const GLchar * TCS_src[] = {
"#version 430\n"
"layout(vertices = 4) out;\n"
"in vec4 vposition[];\n"
"out vec4 tposition[];\n"
"void main()\n"
"{\n"
" tposition[gl_InvocationID] = vposition[gl_InvocationID];\n"
" if (gl_InvocationID == 0)\n"
" {\n"
" float tessLevel = 1.0;\n"
" gl_TessLevelInner[0] = tessLevel;\n"
" gl_TessLevelInner[1] = tessLevel;\n"
" gl_TessLevelOuter[0] = tessLevel;\n"
" gl_TessLevelOuter[1] = tessLevel;\n"
" gl_TessLevelOuter[2] = tessLevel;\n"
" gl_TessLevelOuter[3] = tessLevel;\n"
" }\n"
"}\n"
};
// tesselation evaluation shader
const GLchar * TES_src[] = {
"#version 430\n"
"uniform mat4 mvp;\n"
"layout(quads) in;\n"
"in vec4 tposition[];\n"
"void main()\n"
"{\n"
" float x = gl_TessCoord[0] * (tposition[1].x - tposition[0].x) + tposition[0].x;\n"
" float z = gl_TessCoord[2] * (tposition[1].z - tposition[2].z) + tposition[2].z;\n"
" float y = 0.0;\n"
" gl_Position = mvp * vec4(x, y, z, 1.0);\n"
"}\n"
};
// fragment shader
const GLchar * FS_src[] = {
"#version 430\n"
"out vec3 color;\n"
"void main()\n"
"{\n"
"color = vec3(0.0);\n"
"}\n"
};
/* Link Shaders to Program */
GLuint LoadShaders(const GLchar ** VS, const GLchar ** TCS, const GLchar ** TES, const GLchar ** FS)
{
// Create the shaders
GLuint VS_ID = glCreateShader(GL_VERTEX_SHADER);
GLuint TCS_ID = glCreateShader(GL_TESS_CONTROL_SHADER);
GLuint TES_ID = glCreateShader(GL_TESS_EVALUATION_SHADER);
GLuint FS_ID = glCreateShader(GL_FRAGMENT_SHADER);
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("compiling vertex shader\n");
glShaderSource(VS_ID, 1, VS, NULL);
glCompileShader(VS_ID);
// Check Vertex Shader
glGetShaderiv(VS_ID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VS_ID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(VS_ID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
printf("%s\n", &VertexShaderErrorMessage[0]);
}
// Compile Tess Control Shader
printf("compiling tesselation control shader\n");
glShaderSource(TCS_ID, 1, TCS, NULL);
glCompileShader(TCS_ID);
// Check Tess Control Shader
glGetShaderiv(TCS_ID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(TCS_ID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> TessControlShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(TCS_ID, InfoLogLength, NULL, &TessControlShaderErrorMessage[0]);
printf("%s\n", &TessControlShaderErrorMessage[0]);
}
// Compile Tess Evaluation Shader
printf("compiling tesselation evaluation shader\n");
glShaderSource(TES_ID, 1, TES, NULL);
glCompileShader(TES_ID);
// Check Tess Evaluation Shader
glGetShaderiv(TES_ID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(TES_ID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> TessEvaluationShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(TES_ID, InfoLogLength, NULL, &TessEvaluationShaderErrorMessage[0]);
printf("%s\n", &TessEvaluationShaderErrorMessage[0]);
}
// Compile Fragment Shader
printf("compiling fragment shader\n");
glShaderSource(FS_ID, 1, FS, NULL);
glCompileShader(FS_ID);
// Check Fragment Shader
glGetShaderiv(FS_ID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FS_ID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(FS_ID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
printf("%s\n", &FragmentShaderErrorMessage[0]);
}
// Link the program
printf("linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VS_ID);
glAttachShader(ProgramID, TCS_ID);
glAttachShader(ProgramID, TES_ID);
glAttachShader(ProgramID, FS_ID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
printf("%s\n", &ProgramErrorMessage[0]);
}
glDetachShader(ProgramID, VS_ID);
glDetachShader(ProgramID, TCS_ID);
glDetachShader(ProgramID, TES_ID);
glDetachShader(ProgramID, FS_ID);
glDeleteShader(VS_ID);
glDeleteShader(TCS_ID);
glDeleteShader(TES_ID);
glDeleteShader(FS_ID);
return ProgramID;
}
/* MAIN */
int main()
{
GLFWwindow * window;
if (!glfwInit()) return 0;
glfwWindowHint(GLFW_SAMPLES, 0);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(1600, 900, "Test", NULL, NULL);
if (!window) return 0;
glfwMakeContextCurrent(window);
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
glewExperimental=true;
if (glewInit() != GLEW_OK) return 0;
// Init
glm::mat4 p = glm::perspective(glm::radians(45.0f), 1600.0f / 900.0f, 0.1f, 1000.0f);
// look at <0,0,0> from <20,20,20>
glm::mat4 v = glm::lookAt(glm::vec3(20.0f), glm::vec3(0.0f), glm::vec3(0,1,0));
glm::mat4 m = glm::mat4(1.0f);
glm::mat4 mvp = p * v * m;
// draw 1 quad
std::vector<unsigned int> indices;
std::vector<glm::vec3> vertices;
indices.push_back(0);
indices.push_back(1);
indices.push_back(2);
indices.push_back(3);
vertices.push_back(glm::vec3(-10.0f, 0.0f, -10.0f));
vertices.push_back(glm::vec3( 10.0f, 0.0f, -10.0f));
vertices.push_back(glm::vec3( 10.0f, 0.0f, 10.0f));
vertices.push_back(glm::vec3(-10.0f, 0.0f, 10.0f));
// VAO
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// program
GLuint ProgramID = LoadShaders(VS_src, TCS_src, TES_src, FS_src);
// mvp uniform
GLuint MatrixID = glGetUniformLocation(ProgramID, "mvp");
// Vertex Buffer
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
// Element Buffer
GLuint elementbuffer;
glGenBuffers(1, &elementbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
// loop
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 )
{
glViewport(0, 0, 1600, 900);
glClearColor(0.478f, 0.702f, 0.816f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glUseProgram(ProgramID);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glPatchParameteri(GL_PATCH_VERTICES, 4);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
glDrawElements(GL_PATCHES, indices.size(), GL_UNSIGNED_INT, (void*)0);
glDisableVertexAttribArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
// cleanup
glDeleteVertexArrays(1, &VertexArrayID);
glDeleteProgram(ProgramID);
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &elementbuffer);
glfwTerminate();
return 0;
}
but still nothing is displayed (besides the blue clearcolor background). All shaders compile with no errors and the program is linked with no errors.
When the quads primitive mode is used, then only the first 2 components of gl_TessCoord have a meaning. The 3rd component is 0.0. gl_TessCoord[0] and gl_TessCoord[1] provide normalized 2D coordinates, similar the UV coordinates of textures.
This means that you have to use gl_TessCoord[1] instead of gl_TessCoord[2] in the tessellation evaluation shader:
float x = gl_TessCoord[0] * (tposition[1].x - tposition[0].x) + tposition[0].x;
float z = gl_TessCoord[1] * (tposition[1].z - tposition[2].z) + tposition[2].z;
See Tessellation, Quads
Specification:
GLSL - The OpenGL Shading Language 4.6, 7.1 Built-In Language Variables, page 129:
The variable gl_TessCoord is available only in the tessellation evaluation language. It specifies a threecomponent (u,v,w) vector identifying the position of the vertex being processed by the shader relative to the primitive being tessellated.
OpenGL 4.6 core profile specification, 11.2.2.2 Quad Tessellation, page 416:
If the tessellation primitive mode is quads, a rectangle is subdivided into a collection of triangles covering the area of the original rectangle. First, the original rectangle is subdivided into a regular mesh of rectangles, where the number of rectangles along the u = 0 and u = 1 (vertical) and v = 0 and v = 1 (horizontal) edges are derived from the first and second inner tessellation levels, respectively.
Related
From what I understand, OpenGL always accepts coordinates from -1.0 to 1.0. When the viewport changes, when a window is resized, the distances between points are not preserved.
For example, when the viewport width is 400, the distance between points (0.5,0.0) and (-0.5,0.0) is 200, and when the width is 600, it is 300.
I need to draw a shape (of a scrollbar or something similar), that shouldn't change its width, when the window is resized. I've seen on other posts, that people calculate the floating point coordinates using the window width, but that introduces the problem of floating point accuracy, which can lead to the shape being nearly constant size, but sometimes not exactly.
How to make a shape, that will stay exactly the same width, no matter the width of the window?
The code I'm running is really just a simple triangle appearing on the screen that can be resized. The code is nonetheless a bit long.
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
void onSize (GLFWwindow* window, int width, int height)
{
glViewport (0,0,width, height);
}
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
GLFWwindow* window = glfwCreateWindow(800, 600, "hello", nullptr, nullptr);
glfwMakeContextCurrent(window);
glfwSetWindowSizeCallback(window, onSize);
glewExperimental = GL_TRUE;
glewInit();
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLint success;
GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "error with vertex shader compilation\n" << infoLog << std::endl;
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "error with fragment shader compilation\n" << infoLog << std::endl;
}
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "error with linking program\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f, // Left
0.5f, -0.5f, 0.0f, // Right
0.5f, 0.5f, 0.0f // Top
};
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
So how do I make it so that this triangle has constant width and height regardless of resizing the window?
My answer is related to the phrase in your question: "I need to draw a shape [...], that shouldn't change its width, when the window is resized."
You have to use Orthographic projection.
Add a Uniform variable of type mat4 to the vertex shader and multiply the vertex coordinate with the matrix uniform:
#version 330 core
layout (location = 0) in vec3 position;
uniform mat4 u_projection;
void main()
{
gl_Position = u_projection * vec4(position, 1.0);
}
Define the vertices in pixel unit:
GLfloat vertices[] = {
-100.0f, -100.0f, 0.0f, // Left
100.0f, -100.0f, 0.0f, // Right
100.0f, 100.0f, 0.0f // Top
};
Get the current width and height of the viewport and set the matrix using glm::ortho:
GLint proj_loc = glGetUniformLocation(shaderProgram, "u_projection");
while (!glfwWindowShouldClose(window))
{
int width, height;
glfwGetWindowSize(window, &width, &height);
// [...]
glUseProgram(shaderProgram);
glm::mat4 projection = glm::ortho(
-width/2.0f, width/2.0f, -height/2.0f, height/2.0f, -1.0f, 1.0f);
glUniformMatrix4fv(proj_loc, 1, GL_FALSE, glm::value_ptr(projection));
// [...]
}
Trying to create a random point cloud in 2D. However, I've got this in the end for now : The background color + 1 single 'grey' point in the center. What might have gone wrong here?
I try writing my own simple shader.
Trying to compile shader by myself.
All are supposed to be baby steps.
Also what would be some tips of debugging these issues?
#include <vector>
#include <algorithm>
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLFWwindow* window;
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/norm.hpp>
/* SHADERS */
/* Vertex Shader */
const char *VertexShaderSource="#version 330 core\n"
"layout(location=0) in vec2 pos;\n"
"//layout(location=1) in vec2 da;//distance and angle \n"
"//layout(location=2) in vec4 color;\n"
"\n"
"out vec4 particle_color\n"
"uniform mat4 mvp;\n"
"int main(){\n"
"gl_Position = mvp*vec4(pos, 0.0,1.0));\n"
"//particle_color =;\n"
"}\n";
/* Fragment Shader*/
const char *FragmentShaderSource="#version 330 core\n"
"//in vec4 particle_color;\n"
"out vec4 color;\n"
"//layout(location=2) in vec4 color;\n"
"void main(){\n"
"color = vec4(1.0f,0.0f,0.0f,1.0f);\n"
"}\n";
/* SHADERS END */
// Particle
struct Point{
glm::vec2 pos;
// Create random color in GPU
// unsigned char r,g,b,a;
float distance;
float angle;
};
static const int max_point_number=1000;
Point PointContainer[max_point_number];
int main()
{
// Start GLFW
if(!glfwInit())
{
std::cout<<"Failed to start GLWF\n";
getchar();
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
//glfwWindowHint(GLFW_RESIZABLE,GL,FALSE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(800, 600, "Rotating Points", NULL, NULL);
if(window == NULL)
{
std::cout<<"Initialization of the window failed\n";
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Start GLEW;
glewExperimental = true;
if(glewInit() != GLEW_OK)
{
std::cout<<"Failed to start GLEW\n";
getchar();
return -1;
}
glfwPollEvents();
glClearColor(.0f,0.5f,0.5f,0.0f); // Black is the new orange
// Camera
glm::mat4 Projection = glm::ortho(0.0f,800.0f, 0.0f,600.0f,-5.0f,5.0f); // In world coordinates
glm::mat4 View = glm::lookAt(
glm::vec3(0,0,-1), // Camera is at (0,0,-1), in World Space
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 mvp = Projection * View * Model; // Remember, matrix multiplication is the other way around
// No need to have depth test
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Build and compile shaders
// Vertex Shader
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &VertexShaderSource, NULL);
glCompileShader(vertexShader);
// Fragment Shader
int fragmentShader=glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &FragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// Link Shaders
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
// Delete Shaders after Linking
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
for(auto &p:PointContainer)
{
p.pos.x =rand() % 800;
p.pos.y =rand() % 600;
std::cout<<p.pos.x<<" "<<p.pos.y<<"\n";
}
// Vertex Shader
GLuint tPM = glGetUniformLocation(shaderProgram, "mvp");//mvp
glUniformMatrix4fv(tPM, 1, GL_FALSE, &mvp[0][0]);
GLuint pointsVertexBuffer;
glGenBuffers(1, &pointsVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, pointsVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(PointContainer), PointContainer, GL_STREAM_DRAW); // Start with NULL, update with frames;
do
{
// Clear the screen
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//glDrawArraysInstanced(GL_POINTS, 0, 2, max_point_number);
glBindBuffer( GL_ARRAY_BUFFER, pointsVertexBuffer );
glEnableClientState( GL_VERTEX_ARRAY );
//glEnableClientState( GL_COLOR_ARRAY );
glVertexPointer( 4, GL_FLOAT, sizeof( Point ), (void*)offsetof( Point, pos ) );
//glColorPointer( 4, GL_FLOAT, sizeof( Vertex ), (void*)offsetof( Vertex, color ) );
glDrawArrays( GL_POINTS, 0, max_point_number);
glDisableClientState( GL_VERTEX_ARRAY );
//glDisableClientState( GL_COLOR_ARRAY );
glBindBuffer( GL_ARRAY_BUFFER, 0 ); // Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwWindowShouldClose(window) == 0 );
return 0;
}
Edit:
I edited the code, still gives the same result.
#include <vector>
#include <algorithm>
#include <iostream>`
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLFWwindow* window;
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/norm.hpp>
/* SHADERS */
/* Vertex Shader */
const char *VertexShaderSource=R"(
#version 330 core
layout(location=0) in vec2 pos;
uniform mat4 mvp;
int main(){
gl_Position = mvp*vec4(pos, 0.0,1.0);
}
)";
/* Fragment Shader*/
const char *FragmentShaderSource = R"(
#version 330 core
out vec4 color;
void main(){
color = vec4(1.0f);
}
)";
/* SHADERS END */
// Particle
struct Point{
glm::vec2 pos;
// Create random color in GPU
// unsigned char r,g,b,a;
float distance;
float angle;
};
static const int max_point_number=1000;
Point PointContainer[max_point_number];
int main()
{
// Start GLFW
if(!glfwInit())
{
std::cout<<"Failed to start GLWF\n";
getchar();
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
//glfwWindowHint(GLFW_RESIZABLE,GL,FALSE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(800, 600, "Rotating Points", NULL, NULL);
if(window == NULL)
{
std::cout<<"Initialization of the window failed\n";
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Start GLEW;
glewExperimental = true;
if(glewInit() != GLEW_OK)
{
std::cout<<"Failed to start GLEW\n";
getchar();
return -1;
}
glfwPollEvents();
glClearColor(.0f,0.0f,0.0f,0.0f); // Black is the new orange
// Camera
glm::mat4 Projection = glm::ortho(0.0f,800.0f, 0.0f,600.0f,-5.0f,5.0f); // In world coordinates
glm::mat4 View = glm::lookAt(
glm::vec3(0,0,1), // Camera is at (0,0,-1), in World Space
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 mvp = Projection * View * Model; // Remember, matrix multiplication is the other way around
// No need to have depth test
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Build and compile shaders
// Vertex Shader
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &VertexShaderSource, NULL);
glCompileShader(vertexShader);
// Fragment Shader
int fragmentShader=glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &FragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// Link Shaders
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
// Delete Shaders after Linking
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
for(auto &p:PointContainer)
{
p.pos.x =(rand() % 800)*-1;
p.pos.y =rand() % 600;
std::cout<<p.pos.x<<" "<<p.pos.y<<"\n";
}
// Vertex Shader
GLuint tPM = glGetUniformLocation(shaderProgram, "mvp");//mvp
glUniformMatrix4fv(tPM, 1, GL_FALSE, &mvp[0][0]);
GLuint pointsVertexBuffer;
glGenBuffers(1, &pointsVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, pointsVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(PointContainer), PointContainer, GL_STREAM_DRAW); // Start with NULL, update with frames;
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0 );
glEnableVertexAttribArray( 0 );
do
{
// Clear the screen
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDrawArrays( GL_POINTS, 0, max_point_number);
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwWindowShouldClose(window) == 0 );
return 0;
}
The vertex shader doesn't even compile. A ;is missing affter out vec4 particle_color, the return type of main has to be void and at the end of gl_Position = mvp*vec4(pos, 0.0,1.0)); there is one ) to many.
I recommend to use a Raw string literal:
const char *VertexShaderSource = R"(
#version 330 core
layout(location=0) in vec2 pos;
uniform mat4 mvp;
void main(){
gl_Position = mvp*vec4(pos, 0.0,1.0);
}
)";
Since you use a core profile Context you've to use a Vertex Array Object. e.g.:
GLuint pointsVertexBuffer;
glGenBuffers(1, &pointsVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, pointsVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(PointContainer), PointContainer, GL_STREAM_DRAW); // Start with NULL, update with frames;
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0 );
glEnableVertexAttribArray( 0 );
do
{
// Clear the screen
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDrawArrays( GL_POINTS, 0, max_point_number);
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwWindowShouldClose(window) == 0 );
You've an orthographic projection from (0, 0) to (600, 800), so the view matrix has to be
glm::mat4 View = glm::lookAt(
glm::vec3(0,0,1), // Camera is at (0,0,-1), in World Space
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);
Note, with your view matrix the points are drawn at the left of the viewport, so you can't see them. The point would be drawn in in the rectangle from (0, 0) to (-800, 600).
Change the color of the points in the fragment shader. The red color is hardly to see on the green ground:
const char *FragmentShaderSource = R"(
#version 330 core
out vec4 color;
void main(){
color = vec4(1.0f);
}
)";
I recommend to verify if the shader succeeded to compile by glGetShaderiv. e.g.:
glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &status );
if ( status == GL_FALSE )
{
GLint logLen;
glGetShaderiv( vertexShader, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetShaderInfoLog( vertexShader, logLen, &written, log.data() );
std::cout << "compile error:" << std::endl << log.data() << std::endl;
}
and the program succeeded to link by glGetProgramiv. e.g.:
glGetProgramiv( shaderProgram, GL_LINK_STATUS, &status );
if ( status == GL_FALSE )
{
GLint logLen;
glGetProgramiv( shaderProgram, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetProgramInfoLog( shaderProgram, logLen, &written, log.data() );
std::cout << "link error:" << std::endl << log.data() << std::endl;
}
I've written some OpenGL code in c++ to render a red triangle to the screen. The program uses opengl 3.3 and glsl version 330. I've narrowed down the code that doesn't work to a few .cpp class files or my glsl code. I get no compiler or linker errors (I do get some linker warnings but I dont think those are important). I've given the code in what I believe to be the most likely place for errors to occur.
Renderer.cpp:
#include "Renderer.h"
#include <GL/glew.h>
void Renderer::render(int vbo){
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
}
ShaderProgram.cpp
#pragma warning(disable:4101)
#include "ShaderProgram.h"
#include <fstream>
#include <sstream>
ShaderProgram::ShaderProgram(std::string vertexLocation, std::string fragmentLocation){
programID = glCreateProgram();
vertexID = glCreateShader(GL_VERTEX_SHADER);
fragmentID = glCreateShader(GL_FRAGMENT_SHADER);
createShader(vertexID, vertexLocation);
createShader(fragmentID, fragmentLocation);
glLinkProgram(programID);
GLint success;
glGetProgramiv(programID, GL_LINK_STATUS, &success);
if (success == 0) {
GLchar ErrorLog[1024];
glGetProgramInfoLog(programID, sizeof(ErrorLog), nullptr, ErrorLog);
fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);
}
glValidateProgram(programID);
glUseProgram(programID);
}
void ShaderProgram::createShader(GLint shaderID, std::string srcLocation){
const std::string shaderText = loadShaderSource(srcLocation);
const GLchar* shaderSource = shaderText.data();
glShaderSource(shaderID, 1, &shaderSource, nullptr);
glCompileShader(shaderID);
GLint success;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success);
if (!success) {
GLchar InfoLog[1024];
glGetShaderInfoLog(shaderID, sizeof(InfoLog), nullptr, InfoLog);
fprintf(stderr, "Error compiling shader: '%s'\n", InfoLog);
}
glAttachShader(programID, shaderID);
}
std::string ShaderProgram::loadShaderSource(std::string location){
std::ifstream file (location);
std::string source;
std::stringstream stringStream;
if (!file.is_open()){
throw std::runtime_error("Could not open file " + location);
}
stringStream << file.rdbuf();
source = stringStream.str();
return source;
}
Entity.cpp
#include "Entity.h"
Entity::Entity(){
vertices[0] = glm::vec3(-1.0f, -1.0f, 0.0f);
vertices[1] = glm::vec3(1.0f, -1.0f, 0.0f);
vertices[2] = glm::vec3(0.0f, 1.0f, 0.0f);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
}
int Entity::getID(){
return vbo;
}
GLSL Code:
Vertex Shader:
#version 330
layout (location = 0) in vec3 position;
void main(){
gl_Position = vec4(0.5 * position.x, 0.5 * position.y, position.z, 1.0);
}
Fragment Shader:
#version 330
out vec4 colour;
void main(){
colour = vec4(1.0, 0.0, 0.0, 1.0);
}
you cant use glm::vec3 like this.Reference to it doesn't provide you anything.Start of its real array obtained :
glm::vec3 k;
float* t= &k[0];
But i doubt you can do something worth with it too.
use just float GLfloat array.
I have written a simple openGL program to draw a triangle on the screen. I have done debugging with glGetError() and now there is no error in the code but when I try to run it only a black screen comes up.
here is my code. I am using GLFW for window creation.
#include<glew.h>
#include<glfw3.h>
#include<stdio.h>
int main(int argc, char ** argv)
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
float vertices[] = {
0.0f, 0.5f,
0.5f, -0.5f,
-0.5f, -0.5f
};
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
const GLchar * vs =
"#version 150\n"
"in vec2 position;\n"
"void main() {\n"
"vec4 gl_Position = vec4( position , 0.0 , 1.0 );\n"
"}";
const GLchar * fs =
"#version 150\n"
"out vec4 out_color; \n"
"void main() { \n"
"out_color = vec4(1.0, 1.0, 1.0, 1.0);\n"
"}";
GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vsh, 1, &vs, NULL);
glCompileShader(vsh);
GLint status;
glGetShaderiv(vsh, GL_COMPILE_STATUS, &status);
if (status == GL_TRUE) printf("Vertex Shader Compiled success\n");
GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fsh, 1, &fs, NULL);
glCompileShader(fsh);
glGetShaderiv(fsh, GL_COMPILE_STATUS, &status);
if (status == GL_TRUE) printf("Fragment Shader Compiled success\n");
GLuint sp = glCreateProgram();
glAttachShader(sp, vsh);
glAttachShader(sp, fsh);
glBindFragDataLocation(sp, 0, "out_color");
glBindAttribLocation(sp,1,"position");
glLinkProgram(sp);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glUseProgram(sp);
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Update
I have narrowed down the issue to just one line of code
GLint pos = glGetAttribLocation(sp, "position") //sp is shader program
The problem is it is returning -1. I have read in tutorials that if you don't use a variable it will be optimized out by the compiler.I have used the position in the code then why it is getting thrown away. Below is my vertex shader.
const GLchar * vs =
"#version 150\n"
"in vec2 position;\n"
"void main() {\n"
"vec4 gl_Position = vec4( position , 0.0 , 1.0 );\n"
"}";
just add these lines after
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
I mean use location 0 instead of 1
hope this helps
I'm new to both stack overflow and OpenGL.
I'm trying to create my first little 3d program with custom shaders, but i have a problem with the various matrices that are required. I don't know exactly what causes complete black screen, if it is that i load uniforms incorrectly or that I'm failing at calculating the matrices. Anyway, I post the code down here and if anyone can help it would be amazing.
Main Cpp file
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <GL\glew.h>
#include <GL\glut.h>
#include <glm\glm.hpp>
#include <glm\vec3.hpp>
#include <glm\mat4x4.hpp>
#include <glm\gtc\matrix_transform.hpp>
#include <glm\gtc\type_ptr.hpp>
GLuint programID, vbo;
using namespace glm;
void loadShaders(){
char vertex_file_path[] = "vertex.glsl";
char fragment_file_path[] = "fragment.glsl";
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path);
if (VertexShaderStream.is_open()){
std::string Line = "";
while (std::getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
}
else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
getchar();
throw new std::runtime_error("Shaders not found");
}
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if (FragmentShaderStream.is_open()){
std::string Line = "";
while (std::getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
if (Result == GL_FALSE){
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char * VertexShaderErrorMessage = new char[InfoLogLength + 1];
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, VertexShaderErrorMessage);
std::cout << VertexShaderErrorMessage << std::endl;
printf("Could not compile vertex shader: %s\n", VertexShaderErrorMessage);
getchar();
throw new std::runtime_error("Could not compile vertex shader");
}
// Compile Fragment Shader
std::cout << "Compiling shader : " << fragment_file_path << std::endl;
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
if (Result == GL_FALSE){
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
char * FragmentShaderErrorMessage = new char[InfoLogLength + 1];
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, FragmentShaderErrorMessage);
printf("Could not compile fragment shader: %s\n", FragmentShaderErrorMessage);
getchar();
throw new std::runtime_error("Could not compile fragment shader");
}
// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
if (Result == GL_FALSE){
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
printf("%s\n", &ProgramErrorMessage[0]);
throw new std::runtime_error("Could not compile program");
}
glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
programID = ProgramID;
}
void loadMatrices(){
GLuint modelLoc = glGetUniformLocation(programID, "model");
GLuint viewLoc = glGetUniformLocation(programID, "view");
GLuint projLoc = glGetUniformLocation(programID, "projection");
mat4 model = scale(mat4(1.0f), vec3(1.0f));
mat4 view = lookAt(vec3(0.0f, 0.0f, 2.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f));
mat4 projection = perspective(45.0f, 16.0f / 9.0f, 0.01f, 100.0f);
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, value_ptr(projection));
}
void renderLoop(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
0,
(void *) 0
);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
int _tmain(int argc, _TCHAR* argv[])
{
int MY_ZERO = 0;
glutInit(&MY_ZERO, NULL);
glutInitWindowSize(1280, 720);
glutInitDisplayMode(GLUT_DOBULE);
glutCreateWindow("Test");
glewExperimental = true;
glewInit();
glutIdleFunc(renderLoop);
glutDisplayFunc(renderLoop);
glMatrixMode(GL_PROJECTION);
glEnable(GL_DEPTH_TEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections
glDepthFunc(GL_LEQUAL);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_BLEND);
gluPerspective(75.0f, 16.0f / 9, 0.1f, 100.0f);
std::cout << "Setting blendFunc..." << std::endl;
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
loadShaders();
loadMatrices();
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
float vals[] = {
0.0f, 1.0f, -10.0f,
1.0f, 1.0f, -10.0f,
1.0f, 0.0f, -10.0f
};
glBufferData(GL_ARRAY_BUFFER, sizeof(vals), vals, GL_STATIC_DRAW);
glutMainLoop();
system("pause");
return 0;
}
Vertex Shader
layout (location = 0) in vec3 pos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(){
gl_Position = projection * vec4(pos, 1.0f);
}
Fragment Shader
void main(){
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}
There are several general aspects of the code which need improvement; e.g.
⊗ it can throw but doesn't catch and cleanup:
// there's no try/catch block enclosing this
throw new std::runtime_error("Could not compile vertex shader");
⊗ it's ready to leak:
char * VertexShaderErrorMessage = new char[InfoLogLength + 1];
/* ... */
throw new std::runtime_error("Could not compile vertex shader");
⊗ it needlessly consumes CPU and GPU time
glutIdleFunc(renderLoop); // boosts the frame rate for performance
// meters only
and so on, e.g. unrolling the shader creation and error handling loop violates DRY.
From an OpenGL-specific pov, there are several things which are not ok.
⊗ This
mat4 view = lookAt(vec3(0.0f, 0.0f, 2.0f),
vec3(0.0f, 0.0f, 0.0f),
vec3(0.0f, 1.0f, 0.0f));
(rightfully) prepares to step back back 2 units with the cam; but that matrix is not used in the shader
void main(){
gl_Position = projection * vec4(pos, 1.0f);
}
⊗ The shaders are first created and attached to the program, but on success deleted and detached again from the program which is intended to be used
glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
⊗ These calls
glMatrixMode(GL_PROJECTION);
/* ... */
gluPerspective(75.0f, 16.0f / 9, 0.1f, 100.0f);
/* ... */
glMatrixMode(GL_MODELVIEW);
are meant for the (deprecated) fixed pipeline; which is not used here, and
⊗ there is no glClear() call in the code
There may be more things to attend to, but this is what I see on the first look.
We can have a deeper look into the code it if those things are dealt with first.
Solved!
The problem was that I wasn't using the program that holds the uniforms, so it failed to load them. Thanks to #BDL I started watching for OpenGL errors and i found GL_INVALID_OPERATION after every glUniformMatrix4fv. Poor debugging on my part. Thanks to everyone that helped
TL;DR put glUseProgram(program) before any glUniformMatrix4fv()