Adding glm::ortho matrix causes sprites to disappear - opengl

I can get two images to display as expected when not applying any kind of orthographic projection. However, when trying to add an orthographic projection matrix to my verts using glm::ortho(), my sprites disappear. My code is as follows (tried removing irrelevant code):
Sprite.cpp
Sprite::Sprite()
{
vboID = 0;
}
Sprite::~Sprite()
{
//Clean up sprite buffers on GPU when done with sprite
if (vboID != 0)
glDeleteBuffers(1, &vboID);
}
void Sprite::Init(float x, float y, float width, float height, Blz::string imageFilePath)
{
this->x = x;
this->y = y;
this->width = width;
this->height = height;
if (vboID == 0)
glGenBuffers(1, &vboID);
texture = Blz::OpenGL::LoadImage(imageFilePath);
Vector3D vertexData[6]{
Vector3D {x + width, y + height, 0.0f},
Vector3D {x, y + height, 0.0f },
Vector3D {x, y, 0.0f},
Vector3D {x, y, 0.0f},
Vector3D {x + width, y, 0.0f},
Vector3D {x + width, y + height, 0.0f},
};
for (int i = 0; i < 6; ++i)
{
vertexData[i].color.r = 0;
vertexData[i].color.g = 155;
vertexData[i].color.b = 200;
};
vertexData[0].setUV(1.0f, 1.0f);
vertexData[1].setUV(0.0f, 1.0f);
vertexData[2].setUV(0.0f, 0.0f);
vertexData[3].setUV(0.0f, 0.0f);
vertexData[4].setUV(1.0f, 0.0f);
vertexData[5].setUV(1.0f, 1.0f);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Sprite::Draw()
{
glBindTexture(GL_TEXTURE_2D, texture.id);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3D), (void*)offsetof(Vector3D, position));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vector3D), (void*)offsetof(Vector3D, textCoordinate));
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
main.cpp
int main(int agrc, char** argv)
{
window.Initialize();
glm::mat4 projectionMatrix = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, -1.0f, 1.0f);
p_sprites.push_back(new Sprite());
p_sprites.back()->Init(0.0f, 0.0f, .5f, .5f, "CharImage.png");
p_sprites.push_back(new Sprite());
p_sprites.back()->Init(-0.4f, 0.0f, .5f, .5f, "CharImage.png");
GameState gamestate{ GameState::PLAY };
SDL_Event evnt;
Blz::OpenGL::ShaderProgram colorShaderProgram("Source/GameEngine/Shaders/VertexShader.glsl", "Source/GameEngine/Shaders/FragmentShader.glsl");
colorShaderProgram.Compile();
colorShaderProgram.AddAttribute("vertexPosition");
colorShaderProgram.AddAttribute("textCoord");
colorShaderProgram.Link();
colorShaderProgram.Bind();
//Get uniform from Shader and send texture info to shader
GLuint uniformLocation = colorShaderProgram.GetUniformLocation("basicTexture");
glUniform1i(uniformLocation, 0);
//Get uniform location from shader
GLuint ProjectMatrixUniformLocation = colorShaderProgram.GetUniformLocation("projectionMatrix");
while (gamestate != GameState::EXIT)
{
ProcessInput();
//Send down projectionMatrix resulting from glm::ortho() call
glUniformMatrix4fv(ProjectMatrixUniformLocation, 1, GL_FALSE, &projectionMatrix[0][0]);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (uint32 i = 0; i < p_sprites.size(); ++i)
p_sprites[i]->Draw();
SDL_GL_SwapWindow(window)
}
return 0;
}
Vertex Shader
#version 430
in vec3 vertexPosition;
in vec2 textCoord;
out vec2 TextureCoord;
uniform mat4 projectionMatrix;
void main()
{
vec4 position = vec4(vertexPosition, 1.0f);
gl_Position = projectionMatrix * position;
TextureCoord = textCoord;
};
Fragment Shader
#version 430
out vec4 daColor;
in vec2 TextureCoord;
uniform sampler2D basicTexture;
void main()
{
vec4 texel = texture(basicTexture, TextureCoord);
daColor = texel;
};

Related

Rotated GLSL texture is pixelated

I've made a program that displays some textures depending on the given input and can rotate, resize and move the textures depending on the given input. The program works perfectly fine but when I rotate the textures the edges appear to be pixelated, like this:
Is there a way for me to smoothen out these edges?
Here are my shaders and texture classes:
texture.vs:
#version 300 es
precision mediump float;
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
uniform mat4 transform;
void main()
{
gl_Position = transform * vec4(aPos, 1.0f);
ourColor = aColor;
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
texture.fs
#version 300 es
precision mediump float;
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCoord;
// texture sampler
uniform sampler2D texture1;
void main()
{
FragColor = texture(texture1, TexCoord);
}
Here is my texture.cpp:
Texture::Texture(int x, int y, int w, int h, int gw, int gh)
{
pos.TL_x = _VERTICIZE_X(x, gw);
pos.TL_y = -_VERTICIZE_Y(y, gh);
pos.TR_x = _VERTICIZE_X(x + w, gw);
pos.TR_y = -_VERTICIZE_Y(y, gh);
pos.BL_x = _VERTICIZE_X(x, gw);
pos.BL_y = -_VERTICIZE_Y(y + h, gh);
pos.BR_x = _VERTICIZE_X(x + w, gw);
pos.BR_y = -_VERTICIZE_Y(y + h, gh);
}
void set_max_z(int z)
{
max_z = z;
}
int Texture::init(float ang_rad, float z)
{
shader = Shader("./src/opengl/shaders/image.vs", "./src/opengl/shaders/image.fs");
this->angle = ang_rad;
// build and compile our shader zprogram
// ------------------------------------
// set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------
float vertices[32] = {
// positions // colors // texture coords
pos.TR_x, pos.TR_y, _VERTICIZE_Z(z, max_z), 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, // top right
pos.BR_x, pos.BR_y, _VERTICIZE_Z(z, max_z), 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, // bottom right
pos.BL_x, pos.BL_y, _VERTICIZE_Z(z, max_z), 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // bottom left
pos.TL_x, pos.TL_y, _VERTICIZE_Z(z, max_z), 1.0f, 1.0f, 1.0f, 0.0f, 0.0f // top left
};
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
glEnable(GL_DEPTH_TEST);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
// color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
// load and create a texture
// -------------------------
// texture 1
// ----------
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
// -------------------------------------------------------------------------------------------
shader.use(); // don't forget to activate/use the shader before setting uniforms!
// either set it manually like so:
glUniform1i(glGetUniformLocation(shader.ID, "texture"), 0);
return 0;
}
void Texture::render(int w, int h, uint8_t *buffer)
{
// If having trouble doing multiple textures, add "+ index to Active Texture."
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glGenerateMipmap(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glm::mat4 transform = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
transform = glm::translate(transform, glm::vec3(0.0f, 0.0f, 0.0f));
transform = glm::rotate(transform, glm::radians(this->angle), glm::vec3(0.0f, 0.0f, 1.0f));
// get matrix's uniform location and set matrix
shader.use();
unsigned int transformLoc = glGetUniformLocation(shader.ID, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
Texture::~Texture()
{
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
}
void Texture::framebuffer_size_callback(GLFWwindow *window, int width, int height)
{
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}
(_VERTICIZE just calculates points)
I'm using ubuntu, GLAD, GLFW.
This appears to be a classic example of Aliasing. We can fix this by enabling MSAA.
GLFW has an inbuilt way of doing that. Put this before you create the window:
glfwWindowHint(GLFW_SAMPLES, 4); /* if effect is not strong enough, change to 8 */
Edit -
You have to call glfwWindowHint(GLFW_SAMPLES, 4) in between glfwInit and glfwCreateWindow.
Also, in case OpenGL doesn't enable multisampling by default, do
glEnable(GL_MULTISAMPLE);

Dashed line in OpenGL3?

I'm currently porting an old OpenGL 1.1 application which makes use of wireframe models to OpenGL 3.0.
In 1.1 following code is used to create a dashed line:
glPushAttrib(GL_ENABLE_BIT);
glLineStipple(1, 0x0F0F);
glEnable(GL_LINE_STIPPLE);
Here as usual the parameters are pushed to the stack in order to influence all following drawing operations.
My question: how is this done in OpenGL3 where this stack is no longer used? How can I set up my lines to be dashed (probably before handing the coordinates over to glBufferData()?
For separate line segments, this is not very complicated at all. For example drawing the GL_LINES primitives.
The trick is to know the start of the line segment in the fragment shader. This is quite simple by using the flat interpolation qualifier.
The vertex shader has to pass the normalized device coordinate to the fragment shader. Once with default interpolation and once with no (flat) interpolation. This causes that in the fragment shade, the first input parameter contains the NDC coordinate of the actual position on the line and the later the NDC coordinate of the start of the line.
#version 330
layout (location = 0) in vec3 inPos;
flat out vec3 startPos;
out vec3 vertPos;
uniform mat4 u_mvp;
void main()
{
vec4 pos = u_mvp * vec4(inPos, 1.0);
gl_Position = pos;
vertPos = pos.xyz / pos.w;
startPos = vertPos;
}
Additionally to the varying inputs, the fragment shader has uniform variables. u_resolution contains the width and the height of the viewport. u_dashSize contains the length of the line and u_gapSize the length of a gap in pixel.
So the length of the line from the start to the actual fragment can be calculated:
vec2 dir = (vertPos.xy-startPos.xy) * u_resolution/2.0;
float dist = length(dir);
And fragments on the gap can be discarded, by the discard command.
if (fract(dist / (u_dashSize + u_gapSize)) > u_dashSize/(u_dashSize + u_gapSize))
discard;
Fragment shader:
#version 330
flat in vec3 startPos;
in vec3 vertPos;
out vec4 fragColor;
uniform vec2 u_resolution;
uniform float u_dashSize;
uniform float u_gapSize;
void main()
{
vec2 dir = (vertPos.xy-startPos.xy) * u_resolution/2.0;
float dist = length(dir);
if (fract(dist / (u_dashSize + u_gapSize)) > u_dashSize/(u_dashSize + u_gapSize))
discard;
fragColor = vec4(1.0);
}
For the following simple demo program I've used the GLFW API for creating a window, GLEW for loading OpenGL and GLM -OpenGL Mathematics for the math. I don't provide the code for the function CreateProgram, which just creates a program object, from the vertex shader and fragment shader source code:
#include <GL/glew.h>
#include <GL/gl.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <GLFW/glfw3.h>
#include <vector>
#define _USE_MATH_DEFINES
#include <math.h>
int main(void)
{
if (glfwInit() == GLFW_FALSE)
return 0;
GLFWwindow *window = glfwCreateWindow(400, 300, "OGL window", nullptr, nullptr);
if (window == nullptr)
return 0;
glfwMakeContextCurrent(window);
glewExperimental = true;
if (glewInit() != GLEW_OK)
return 0;
GLuint program = CreateProgram(vertShader, fragShader);
GLint loc_mvp = glGetUniformLocation(program, "u_mvp");
GLint loc_res = glGetUniformLocation(program, "u_resolution");
GLint loc_dash = glGetUniformLocation(program, "u_dashSize");
GLint loc_gap = glGetUniformLocation(program, "u_gapSize");
glUseProgram(program);
glUniform1f(loc_dash, 10.0f);
glUniform1f(loc_gap, 10.0f);
std::vector<float> varray{
-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1,
-1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1
};
std::vector<unsigned int> iarray{
0, 1, 1, 2, 2, 3, 3, 0,
4, 5, 5, 6, 6, 7, 7, 4,
0, 4, 1, 5, 2, 6, 3, 7
};
GLuint bo[2], vao;
glGenBuffers(2, bo);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, bo[0] );
glBufferData(GL_ARRAY_BUFFER, varray.size()*sizeof(*varray.data()), varray.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, iarray.size()*sizeof(*iarray.data()), iarray.data(), GL_STATIC_DRAW);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 5.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 project;
int vpSize[2]{0, 0};
while (!glfwWindowShouldClose(window))
{
int w, h;
glfwGetFramebufferSize(window, &w, &h);
if (w != vpSize[0] || h != vpSize[1])
{
vpSize[0] = w; vpSize[1] = h;
glViewport(0, 0, vpSize[0], vpSize[1]);
project = glm::perspective(glm::radians(90.0f), (float)w/(float)h, 0.1f, 10.0f);
glUniform2f(loc_res, (float)w, (float)h);
}
static float angle = 1.0f;
glm::mat4 modelview( 1.0f );
modelview = glm::translate(modelview, glm::vec3(0.0f, 0.0f, -3.0f) );
modelview = glm::rotate(modelview, glm::radians(angle), glm::vec3(1.0f, 0.0f, 0.0f));
modelview = glm::rotate(modelview, glm::radians(angle*0.5f), glm::vec3(0.0f, 1.0f, 0.0f));
angle += 0.5f;
glm::mat4 mvp = project * modelview;
glUniformMatrix4fv(loc_mvp, 1, GL_FALSE, glm::value_ptr(mvp));
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_LINES, (GLsizei)iarray.size(), GL_UNSIGNED_INT, nullptr);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Things get a bit more complicated, if the goal is to draw a dashed line along a polygon. For example drawing a GL_LINE_STRIP primitive.
The length of the line cannot be calculated in the shader program, without knowing all the primitives of the line. Even if all the primitives would be known (e.g. SSBO), then the calculation would have to be done in a loop.
I decided to add an additional attribute to the shader program, which contains the "distance" from the start of the line to the vertex coordinate. By "distance" is meant the length of the projected polygon on to the viewport.
This causes that the vertex shader and fragment shader is even simpler:
Vertex shader:
#version 330
layout (location = 0) in vec3 inPos;
layout (location = 1) in float inDist;
out float dist;
uniform mat4 u_mvp;
void main()
{
dist = inDist;
gl_Position = u_mvp * vec4(inPos, 1.0);
}
Fragment shader:
#version 330
in float dist;
out vec4 fragColor;
uniform vec2 u_resolution;
uniform float u_dashSize;
uniform float u_gapSize;
void main()
{
if (fract(dist / (u_dashSize + u_gapSize)) > u_dashSize/(u_dashSize + u_gapSize))
discard;
fragColor = vec4(1.0);
}
In the demo program the inDist attribute is calculated on the CPU. Each vertex coordinate is transformed by the model, view, projection matrix. Finally it is transformed from normalized device space to window space. The XY distance between adjacent coordinates of the line strip is calculated and the lengths are summed along the line strip and assigned to the corresponding attribute value:
int w = [...], h = [...]; // window widht and height
glm::mat4 mpv = [...]; // model view projection matrix
std::vector<glm::vec3> varray{ [...] }; // array of vertex
std::vector<float> darray(varray.size(), 0.0f); // distance attribute - has to be computed
glm::mat4 wndmat = glm::scale(glm::mat4(1.0f), glm::vec3((float)w/2.0f, (float)h/2.0f, 1.0f));
wndmat = glm::translate(wndmat, glm::vec3(1.0f, 1.0f, 0.0f));
glm::vec2 vpPt(0.0f, 0.0f);
float dist = 0.0f;
for (size_t i=0; i < varray.size(); ++i)
{
darray[i] = dist;
glm::vec4 clip = mvp * glm::vec4(varray[i], 1.0f);
glm::vec4 ndc = clip / clip.w;
glm::vec4 vpC = wndmat * ndc;
float len = i==0 ? 0.0f : glm::length(vpPt - glm::vec2(vpC));
vpPt = glm::vec2(vpC);
dist += len;
}
Demo program:
int main(void)
{
if (glfwInit() == GLFW_FALSE)
return 0;
GLFWwindow *window = glfwCreateWindow(800, 600, "OGL window", nullptr, nullptr);
if (window == nullptr)
return 0;
glfwMakeContextCurrent(window);
glewExperimental = true;
if (glewInit() != GLEW_OK)
return 0;
GLuint program = CreateProgram(vertShader, fragShader);
GLint loc_mvp = glGetUniformLocation(program, "u_mvp");
GLint loc_res = glGetUniformLocation(program, "u_resolution");
GLint loc_dash = glGetUniformLocation(program, "u_dashSize");
GLint loc_gap = glGetUniformLocation(program, "u_gapSize");
glUseProgram(program);
glUniform1f(loc_dash, 10.0f);
glUniform1f(loc_gap, 10.0f);
std::vector<glm::vec3> varray;
for (size_t u=0; u <= 360; ++u)
{
double a = u*M_PI/180.0;
double c = cos(a), s = sin(a);
varray.emplace_back(glm::vec3((float)c, (float)s, 0.0f));
}
std::vector<float> darray(varray.size(), 0.0f);
GLuint bo[2], vao;
glGenBuffers(2, bo);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, bo[0] );
glBufferData(GL_ARRAY_BUFFER, varray.size()*sizeof(*varray.data()), varray.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, bo[1] );
glBufferData(GL_ARRAY_BUFFER, darray.size()*sizeof(*darray.data()), darray.data(), GL_STATIC_DRAW);
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 5.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 project, wndmat;
int vpSize[2]{0, 0};
while (!glfwWindowShouldClose(window))
{
int w, h;
glfwGetFramebufferSize(window, &w, &h);
if (w != vpSize[0] || h != vpSize[1])
{
vpSize[0] = w; vpSize[1] = h;
glViewport(0, 0, vpSize[0], vpSize[1]);
project = glm::perspective(glm::radians(90.0f), (float)w/(float)h, 0.1f, 10.0f);
glUniform2f(loc_res, (float)w, (float)h);
wndmat = glm::scale(glm::mat4(1.0f), glm::vec3((float)w/2.0f, (float)h/2.0f, 1.0f));
wndmat = glm::translate(wndmat, glm::vec3(1.0f, 1.0f, 0.0f));
}
static float angle = 1.0f;
glm::mat4 modelview( 1.0f );
modelview = glm::translate(modelview, glm::vec3(0.0f, 0.0f, -2.0f) );
modelview = glm::rotate(modelview, glm::radians(angle), glm::vec3(1.0f, 0.0f, 0.0f));
modelview = glm::rotate(modelview, glm::radians(angle*0.5f), glm::vec3(0.0f, 1.0f, 0.0f));
angle += 0.5f;
glm::mat4 mvp = project * modelview;
glm::vec2 vpPt(0.0f, 0.0f);
float dist = 0.0f;
for (size_t i=0; i < varray.size(); ++i)
{
darray[i] = dist;
glm::vec4 clip = mvp * glm::vec4(varray[i], 1.0f);
glm::vec4 ndc = clip / clip.w;
glm::vec4 vpC = wndmat * ndc;
float len = i==0 ? 0.0f : glm::length(vpPt - glm::vec2(vpC));
vpPt = glm::vec2(vpC);
dist += len;
}
glBufferSubData(GL_ARRAY_BUFFER, 0, darray.size()*sizeof(*darray.data()), darray.data());
glUniformMatrix4fv(loc_mvp, 1, GL_FALSE, glm::value_ptr(mvp));
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)varray.size());
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
See also
glLineStipple deprecated in OpenGL 3.1
OpenGL ES - Dashed Lines

Model, view and projection matrix do not want to work well for opengl glsl

I am trying to make my first cube using open gl. Unfortunately I stucked in easy rotation. This is how it should look:
Instead I am getting those weird, do not even know how to called it : https://youtu.be/0A5Hi-8bygE
Vertex shader
#version 330 core
layout (location = 0) in vec2 a_position;
layout (location = 1) in vec2 a_uv;
layout (location = 2) in vec4 a_color;
out vec2 v_fragmentPosition;
out vec2 v_fragmentUV;
out vec4 v_fragmentColor;
uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_projection;
void main()
{
gl_Position = u_projection * u_view * u_model * vec4(a_position, 0.0, 1.0);
v_fragmentPosition = a_position;
v_fragmentUV = vec2(a_uv.x, 1 - a_uv.y);
v_fragmentColor = a_color;
}
Fragment
#version 330 core
out vec4 outColor;
in vec2 v_fragmentPosition;
in vec2 v_fragmentUV;
in vec4 v_fragmentColor;
void main()
{
outColor = v_fragmentColor;
}
Main
#include <glad.h>
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>
#include <iostream>
#include "Mesh.h"
#include "Shader.h"
int main(int argc,char*args[])
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_Window* window = SDL_CreateWindow("fdas", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL);
SDL_GLContext context = SDL_GL_CreateContext(window);
gladLoadGLLoader(SDL_GL_GetProcAddress);
glEnable(GL_DEPTH_TEST);
Shader shader;
std::string vertex = shader.LoadFromFile("vertex.shader");
std::string fragment = shader.LoadFromFile("fragment.shader");
shader.CreateShaderProgram(vertex.c_str(), fragment.c_str());
shader.useProgram();
Mesh mesh;
mesh.CreateVertexArray();
bool quit = false;
SDL_Event event;
while (!quit)
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
exit(0);
}
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 model;
model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 view;
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
glm::mat4 projection;
projection = glm::perspective(glm::radians(45.0f), 1280 / 720.0f, 0.1f, 100.0f);
GLint u_model = shader.GetUniformLocation("u_model");
GLint u_view = shader.GetUniformLocation("u_view");
GLint u_projection = shader.GetUniformLocation("u_projection");
glUniformMatrix4fv(u_model, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(u_view, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(u_projection, 1, GL_FALSE, glm::value_ptr(projection));
Rect destRect = { -0.5f, -0.5f, 1.0f, 1.0f };
Rect uvRect = { 0.0f, 0.0f, 1.0f, 1.0f };
ColorRGBA color = { 255, 255, 128, 255 };
mesh.CreateQuad(destRect, uvRect, color);
mesh.Draw(0);
SDL_GL_SwapWindow(window);
}
return 0;
}
Mesh
void Mesh::CreateVertexArray()
{
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, uv));
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, color));
glBindVertexArray(0);
}
void Mesh::CreateQuad(Rect destRect, Rect uvRect, ColorRGBA color)
{
vertex[0].color = color; // topleft
vertex[0].setPosition(destRect.x, destRect.y + destRect.h);
vertex[0].setUV(uvRect.x, uvRect.y + uvRect.h);
vertex[1].color = color;
vertex[1].setPosition(destRect.x, destRect.y); // bottom left
vertex[1].setUV(uvRect.x, uvRect.y);
vertex[2].color = color;
vertex[2].setPosition(destRect.x + destRect.w, destRect.y); // bottom right
vertex[2].setUV(uvRect.x + uvRect.w, uvRect.y);
vertex[3].color = color;
vertex[3].setPosition(destRect.x + destRect.w, destRect.y + destRect.h); // top right
vertex[3].setUV(uvRect.x + uvRect.w, uvRect.y + uvRect.h);
GLuint indices[6] = {
0, 1, 2,
2, 3, 0
};
glBindVertexArray(vao);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(vertex), NULL, GL_STATIC_DRAW); // orphan the buffer
glBufferSubData(GL_ARRAY_BUFFER, 0, 6 * sizeof(vertex), vertex);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLuint), NULL, GL_STATIC_DRAW); // orphan the buffer
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 6 * sizeof(GLuint), indices);
glBindVertexArray(0);
}
void Mesh::Draw(GLuint texture)
{
glBindVertexArray(vao);
// glEnable(GL_CULL_FACE);
// glCullFace(GL_FRONT);
//glFrontFace(GL_CW);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
}
Vertex
struct Rect {
float x, y;
float w, h;
};
struct Position {
float x, y;
};
struct UV {
float u, v;
};
struct ColorRGBA {
GLubyte r, g, b, a;
};
class Vertex
{
public:
Vertex();
~Vertex();
void setPosition(float x, float y);
void setcolor(ColorRGBA color);
void setUV(float u, float v);
UV uv;
ColorRGBA color;
Position position;
};
I will not show shader class, because there is all good with it.
I know it, because I did an experiment.
I created a new uniform in fragment class called u_expColor and set outColor = u_expColor and a quad's color changed.
Also I created uniform vec4 u_expPos in vertex shader and said gl_Position = e_expPos and it created quad with no problems.
Only if I want to create/multiply position by mvp in vertex shader there is a problem like on the you tube video.
How to fix it?
I have fixed it thanks http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/#putting-it-all-together. I saw he had
glm::mat4 model = glm::mat4(1.0f)
and it was all I had to do.

How to create a rectangular grid (of triangles) in openGL?

I'm using OpenGL, GLFW and GLEW to create a simulation of water waves for a school project. I'm using a textured grid and will manipulate said grid in the vertex shader.
I tried to create the grid by adapting the GeometryGenerator class in Frank Luna's book "Introduction to 3D Game Programming". I created the function but it gives me an odd scalene triangle instead of the grid.
Can anyone suggest a fix or a different function which would work better?
Here are the relevant snippets of code:
struct vertex
{
GLfloat x, y, z;
GLfloat u, v;
};
struct index
{
GLuint a, b, c;
};
struct MeshData
{
std::vector<vertex> Vertices;
std::vector<index> Indices;
//std::vector<GLuint> Indices;
};
void CreateGrid(float width, float depth, int m, int n, MeshData& meshData)
{
int vertexCount = m*n;
int faceCount = (m-1)*(n-1)*2;
// Create the vertices.
float halfWidth = 0.5f*width;
float halfDepth = 0.5f*depth;
float dx = width / (n-1);
float dz = depth / (m-1);
float du = 1.0f / (n-1);
float dv = 1.0f / (m-1);
meshData.Vertices.resize(vertexCount);
for(GLfloat i = 0.0f; i < m; ++i)
{
GLfloat z = halfDepth - i*dz;
for(GLfloat j = 0.0f; j < n; ++j)
{
//code
GLfloat x = -halfWidth + j*dx;
meshData.Vertices[i*n+j].x = x;
meshData.Vertices[i*n+j].y = 0.0f;
meshData.Vertices[i*n+j].z = z;
meshData.Vertices[i*n+j].u = j*du;
meshData.Vertices[i*n+j].v = i*dv;
//vertex temp = {x, 0.0f, z, j*du, i*dv};
//meshData.Vertices.push_back(temp);
}
}
//indices
meshData.Indices.resize(faceCount);
GLuint offset = 0;
for(GLuint i = 0; i < m-1; ++i)
{
for(GLuint j = 0; j < n-1; ++j)
{
//offset = x * m;
index temp =
{
i*n+j,
i*n+j+1,
(i+1)*n+j
};
index temp_2 =
{
(i+1)*n+j,
i*n+j+1,
(i+1)*n+j+1
};
meshData.Indices.push_back(temp);
meshData.Indices.push_back(temp_2);
}
}
}
Also passing the data to the VAO.
#pragma region "object_initialization"
// Set the object data (buffers, vertex attributes)
MeshData grid;
CreateGrid(30, 20, 2.0f, 3.0f, grid);
// Setup plane VAO
GLuint planeVAO, planeVBO, planeEBO;
glGenVertexArrays(1, &planeVAO);
glGenBuffers(1, &planeVBO);
glGenBuffers(1, &planeEBO);
glBindVertexArray(planeVAO);
glBindBuffer(GL_ARRAY_BUFFER, planeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(grid.Vertices) * grid.Vertices.size(), &grid.Vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, planeEBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(grid.Indices) * grid.Indices.size(), &grid.Indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glBindVertexArray(0);
// Load textures
GLuint floorTexture = loadTexture("C://path to.../brushwater.png");
#pragma endregion
Here is the rendering code as requested:
while(!glfwWindowShouldClose(window))
{
// Set frame time
GLfloat currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// Check and call events
glfwPollEvents();
Do_Movement();
// Clear the colorbuffer
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw objects
shader.Use();
glm::mat4 model;
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(camera.Zoom, (float)screenWidth/(float)screenHeight, 0.1f, 100.0f);
glUniformMatrix4fv(glGetUniformLocation(shader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(shader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
// Floor
glBindVertexArray(planeVAO);
glBindTexture(GL_TEXTURE_2D, floorTexture);
model = glm::mat4();
glUniformMatrix4fv(glGetUniformLocation(shader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
// Swap the buffers
glfwSwapBuffers(window);
}
And the shaders:
Vertex Shader
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoords;
out vec2 TexCoords;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
TexCoords = texCoords;
}
Fragment Shader
#version 430 core
in vec2 TexCoords;
out vec4 color;
uniform sampler2D texture1;
void main()
{
color = texture(texture1, TexCoords);
}
My outputs are either textured scalene triangles or just a blank background.
Thanks in advanced for reading it though, and thanks for your help!

Porting openGL calls to shaders results in 2D ortho not working as expected anymore

Further Details
I am trying to render a texture in 2D using OpenGL and encountering some problems with the orthogonal projection matrix:
Its pretty much just a straightforward port of the old code using the GL functions thus I have no idea what I'm doing wrong here that I get a strangely stretched output from a plane
Thus the question is: how can I get it "flattened" to a 2D level that I'm able to draw a 2D texture again?
I already tried to change the matrix to a perspective which resulted in showing nothing
Adding a view matrix to change the angle also did not helped
X39
The Code & Shaders
VAO generation
glGenVertexArrays(1, &texture2D_vao);
glBindVertexArray(texture2D_vao);
GLuint vertBufferID, indexBufferID;
glGenBuffers(1, &vertBufferID);
glGenBuffers(1, &indexBufferID);
struct Vec2 { float x, y; };
struct Vec3 { float x, y, z; };
struct Vert { Vec3 pos; Vec2 tex; };
std::array<Vert, 4> verts = { {
{ { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f } },
{ { 1.0f, 1.0f, 0.0f }, { 1.0f, 0.0f } },
{ { 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f } },
{ { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f } }
} };
std::array<unsigned int, 6> indexies = { { 0, 1, 2, 3} };
// Vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, vertBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vert) * verts.size(), verts.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0); // Matches layout (location = 0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vert), 0);
glEnableVertexAttribArray(1); // Matches layout (location = 1)
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vert), (GLvoid*)sizeof(Vec3));
// Index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indexies.size(), indexies.data(), GL_STATIC_DRAW);
glBindVertexArray(0);
Draw Function
void GuiBase::drawTexture2D(::X39::Singletons::MATERIAL* mat, unsigned int textureIndex, double tPosX, double tPosY, double tWidth, double tHeight, double uiPosX, double uiPosY, double uiWidth, double uiHeight, Shader& shad)
{
::X39::Singletons::TEXTURE* texture = mat->textures[textureIndex];
::X39::Singletons::MaterialManager::getInstance().loadMaterial(mat, textureIndex);
::glm::mat4 scaleMatrix = ::glm::scale(::glm::mat4(1.0f), ::glm::vec3((float)uiWidth, (float)uiHeight, 1.0f));
std::array<float, 6> uvManipulation = { tPosX, tPosY, tWidth, tHeight, texture->width, texture->height };
glm::mat4 projectionMatrix = glm::ortho(
(float)0,
(float)::X39::GlobalObject::getInstance().render_width / (float)::X39::GlobalObject::getInstance().render_height,
(float)0,
(float)::X39::GlobalObject::getInstance().render_height / (float)::X39::GlobalObject::getInstance().render_width,
0.0f,
100.0f
);
glBindVertexArray(texture2D_vao);
shad.setUniformMatrix4fv("scaleMatrix", 1, GL_FALSE, &scaleMatrix[0][0], -1);
shad.setUniformMatrix4fv("projectionMatrix", 1, GL_FALSE, &projectionMatrix[0][0], -1);
shad.setUniform1fv("UV_Manipulators", 6, uvManipulation.data(), -1);
shad.setUniform3fv("worldPosition", 1, &glm::vec3(
uiPosX,
uiPosY,
0
)[0], -1);
shad.setUniform1i("textureSampler", texture->textureUnit, -1);
glDrawElements(GL_QUADS, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
Vertex Shader
#version 440
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV_modelspace;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 scaleMatrix;
uniform vec3 worldPosition;
out vec2 UV;
uniform float[6] UV_Manipulators;
void main()
{
gl_Position = scaleMatrix * vec4((vertexPosition_modelspace + worldPosition), 1) * projectionMatrix;
vec2 newUV = vertexUV_modelspace;
if(newUV.x > 0)
{
newUV.x = (UV_Manipulators[0] + UV_Manipulators[2]) / UV_Manipulators[4];
}
else
{
newUV.x = (UV_Manipulators[0]) / UV_Manipulators[4];
}
if(newUV.y > 0)
{
newUV.y = (UV_Manipulators[1] + UV_Manipulators[3]) / UV_Manipulators[5];
}
else
{
newUV.y = (UV_Manipulators[1]) / UV_Manipulators[5];
}
UV = newUV;
}