My OpenGL engine draws a given scene into a Framebuffer Object, then uses its color attachment as a texture. It is then put on a square in the viewport.
The problem is that I see a strange visual artifact:
The square is built with
glm::vec2 square[4];
square[0] = glm::vec2(0.f, 0.f);
square[1] = glm::vec2(engWidth, 0.f);
square[2] = glm::vec2(0.f, engHeight);
square[3] = glm::vec2(engWidth, engHeight);
glm::vec2 texcoords[4];
texcoords[0] = glm::vec2(0.f, 0.f);
texcoords[1] = glm::vec2(1.f, 0.f);
texcoords[2] = glm::vec2(0.f, 1.f);
texcoords[3] = glm::vec2(1.f, 1.f);
glGenBuffers(2, Buffer2D);
glBindBuffer(GL_ARRAY_BUFFER, Buffer2D[0]);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(glm::vec2), square, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, Buffer2D[1]);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(glm::vec2), texcoords, GL_STATIC_DRAW);
orthographicProj = glm::ortho(0.f, (float)engWidth, 0.f, (float)engHeight, -1.f, 1.f);
Where engWidth and engHeight are the actual window size.
Then the frame is rendered with
shaderProgram->setMatrix("Clip", orthographicProj);
glBindBuffer(GL_ARRAY_BUFFER, Buffer2D[0]);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, Buffer2D[1]);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Vertex and fragment shaders for the final phase are simple
const char *frontVertexShader = R"(
#version 440 core
uniform mat4 Clip;
layout(location = 0) in vec2 Position;
layout(location = 1) in vec2 TexCoord;
out vec2 Tex_Coord;
void main() {
gl_Position = Clip * vec4(Position, 0.0, 1.0);
Tex_Coord = TexCoord;
}
)";
const char *frontFragmentShader = R"(
#version 440 core
in vec2 Tex_Coord;
uniform sampler2D sampler;
out vec4 Fragment;
void main() {
Fragment = texture(sampler, Tex_Coord);
}
)";
I tried using triangles instead a triangle strip but with the same result.
Any idea? I can post more code if needed.
I don't know if this will help, but for what it's worth this is what I do for a full screen quad:
(Note the vertex has no texture component - it's just -1 to 1).
v[0].x = -1.f; v[0].y = -1.f; v[0].z = 0.f;
v[1].x = -1.f; v[1].y = 1.f; v[1].z = 0.f;
v[2].x = 1.f; v[2].y = -1.f; v[2].z = 0.f;
v[3].x = 1.f; v[3].y = 1.f; v[3].z = 0.f;
The vertex shader is simply:
void main()
{
attrib_Fragment_Texture = attrib_Position.xy * 0.5 + 0.5;
gl_Position = vec4(attrib_Position.xy, 0.0, 1.0);
}
With the following pixel shader:
void main(void)
{
Out_Colour = texture2D(Map_Diffuse, attrib_Fragment_Texture);
}
You don't need an orthographic projection matrix.
Found it! I forgot to call glClear on the backbuffer and for a strange reason only some pixel presented the issue.
Related
So, I'm a beginner learning graphics programmer. I'm working on a program for camera movement. I think there's something wrong with the vertex shader. The program runs with no errors but the screen is completely blank. Here is the vertex shader I'm using:
#version 330
in vec4 vPosition;
out vec4 vColor;
uniform mat4 model_view;
uniform mat4 projection;
void main()
{
vec4 pos = projection * model_view * vPosition / vPosition.w;
gl_Position = pos;
vColor = vPosition;
}
If I switch the shader back to basic version:
#version 330
in vec4 vPosition;
out vec4 vColor;
void
main()
{
gl_Position = vPosition;
vColor = vPosition;
}
The program runs and renders a triangle successfully. So, I'm pretty sure the error is with the shader.
The shader is called in the initialize function:
void initialize(void)
{
glClearColor(1.0, 1.0, 1.0, 1.0); // white background
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), points, GL_STATIC_DRAW);
// Load shaders and use the resulting shader program
GLuint program = InitShader("res/shaders/vshader21.glsl", "res/shaders/fshader21.glsl");
model_view = glGetUniformLocation(program, "model_view");
projection = glGetUniformLocation(program, "projection");
glUseProgram(program);
// Initialize the vertex position attribute from the vertex shader
GLuint loc = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
}
the 'points' in glBufferData is as follows:
const int WIDTH = 500, HEIGHT = 500;
/* Positions */
vec4 points[] = {
vec4(0.5,0.5, 1, 1),
vec4(-0.5,0.5, 1, 1),
vec4(0.5,-0.5, 1, 1) ,
vec4(-0.5,-0.5, 1, 1)
};
model_view and projection are of GLuint type in main application and global.
I set the uniform variables (position, model_view) in the display functions.
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT); // clear the window
glPointSize(20.0);
// Projection transformation parameters
GLfloat left = -1.0, right = 1.0;
GLfloat bottom = -1.0, top = 1.0;
GLfloat zNear = 0, zFar = 3.0;
mat4 p = Ortho(left, right, bottom, top, zNear, zFar);
glUniformMatrix4fv(projection, 1, GL_TRUE, p);
vec4 eye(0.0, 0.0, -1.0, 1.0);
vec4 at(0.0, 0.0, 0.0, 1.0);
vec4 up(0.0, 1.0, 0.0, 0.0);
mat4 mv = LookAt(eye, at, up);
glUniformMatrix4fv(model_view, 1, GL_TRUE, mv);
glDrawArrays(GL_TRIANGLES, 0, 3); // draw the points
glFlush();
}
What could possibly be going wrong?
The explicit division by the .w component is superfluous.
vec4 pos = projection * model_view * vPosition / vPosition.w;
vec4 pos = projection * model_view * vPosition;
Note, the Perspective divide is automatically performed after clipping.
Since the vector is multiplied to the uniforms form the right, you do not have to transpose the matrices:
glUniformMatrix4fv(projection, 1, GL_TRUE, p);
glUniformMatrix4fv(projection, 1, GL_FALSE, p);
glUniformMatrix4fv(model_view, 1, GL_TRUE, mv);
glUniformMatrix4fv(model_view, 1, GL_FALSE, mv);
See GLSL Programming/Vector and Matrix Operations
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.
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!
I seem to have broken the shaders in my program, here is their code:
vertex shader
#version 330 core
uniform mat4 camera;
uniform mat4 model;
layout(location = 0) in vec3 vert;
layout(location = 1) in vec3 vertNormal;
out vec3 fragVert;
out vec3 fragNormal;
void main() {
// Pass some variables to the fragment shader
fragNormal = vertNormal;
fragVert = vert;
// Apply all matrix transformations to vert
gl_Position = camera * model * vec4(vert, 1);
}
fragment shader
#version 150 core
uniform mat4 model;
uniform vec3 cameraPosition;
// material settings
uniform float materialShininess;
uniform vec3 materialSpecularColor;
uniform vec3 materialColor;
uniform struct Light {
vec3 position;
vec3 intensities; //a.k.a the color of the light
float attenuation;
float ambientCoefficient;
} light;
in vec3 fragNormal;
in vec3 fragVert;
out vec4 finalColor;
void main() {
vec3 normal = normalize(transpose(inverse(mat3(model))) * fragNormal);
vec3 surfacePos = vec3(model * vec4(fragVert, 1));
vec4 surfaceColor = vec4(materialColor, 1);
vec3 surfaceToLight = normalize(light.position - surfacePos);
vec3 surfaceToCamera = normalize(cameraPosition - surfacePos);
//ambient
vec3 ambient = light.ambientCoefficient * surfaceColor.rgb * light.intensities;
//diffuse
float diffuseCoefficient = max(0.0, dot(normal, surfaceToLight));
vec3 diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities;
//specular
float specularCoefficient = 0.0;
if(diffuseCoefficient > 0.0)
specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normal))), materialShininess);
vec3 specular = specularCoefficient * materialSpecularColor * light.intensities;
//attenuation
float distanceToLight = length(light.position - surfacePos);
float attenuation = 1.0 / (1.0 + light.attenuation * pow(distanceToLight, 2));
//linear color (color before gamma correction)
vec3 linearColor = ambient + attenuation*(diffuse + specular);
//final color (after gamma correction)
vec3 gamma = vec3(1.0/2.2);
finalColor = vec4(pow(linearColor, gamma), surfaceColor.a);
}
I have an asset that I am loading from an obj file, then drawing it like such:
void OpenGLView::run()
{
initializeAndSetupWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "PhongBunny");
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
loadBunnyAsset();
AssetInstance bunny1;
bunny1.asset = bunny;
bunny1.position = glm::vec3(2.0f, 2.0f, 2.0f);
bunny1.scale = glm::vec3(1.0f, 1.0f, 1.0f);
do{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
loadUniforms(bunny1);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, bunny.vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, bunny.normalBuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bunny.elementBuffer);
glDrawElements(GL_TRIANGLES, bunny.elementsSize, GL_UNSIGNED_INT, (void*)0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glfwSwapBuffers(window);
glfwPollEvents();
} while (!glfwWindowShouldClose(window));
glfwDestroyWindow(window);
glfwTerminate();
}
with this being the function to load uniforms:
void OpenGLView::loadUniforms(AssetInstance assetInstance)
{
Asset* asset = &assetInstance.asset;
glUseProgram(asset->shaderProgramID);
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 1000.0f);
glm::mat4 camera = Projection * getViewMatrix();
glm::mat4 model = translate(assetInstance.position) * scale(assetInstance.position);
GLuint cameraID = glGetUniformLocation(asset->shaderProgramID, "camera");
GLuint modelID = glGetUniformLocation(asset->shaderProgramID, "model");
GLuint cameraPositionID = glGetUniformLocation(asset->shaderProgramID, "cameraPosition");
GLuint lightPositionID = glGetUniformLocation(asset->shaderProgramID, "light.position");
GLuint lightIntensitiesID = glGetUniformLocation(asset->shaderProgramID, "light.intensities");
GLuint lightAttenuationID = glGetUniformLocation(asset->shaderProgramID, "light.attenuation");
GLuint lightAmbientCoefficientID = glGetUniformLocation(asset->shaderProgramID, "light.ambientCoefficient");
GLuint materialColorID = glGetUniformLocation(asset->shaderProgramID, "materialColor");
GLuint materialShininessID = glGetUniformLocation(asset->shaderProgramID, "materialShininess");
GLuint materialSpecularColorID = glGetUniformLocation(asset->shaderProgramID, "materialSpecularColor");
glUniformMatrix4fv(cameraID, 1, GL_FALSE, &camera[0][0]);
glUniformMatrix4fv(modelID, 1, GL_FALSE, &model[0][0]);
glUniform3fv(cameraPositionID, 1, &cameraPosition[0]);
glUniform3fv(lightPositionID, 1, &light.position[0]);
glUniform3fv(lightIntensitiesID, 1, &light.intensities[0]);
glUniform1f(lightAttenuationID, light.attenuation);
glUniform1f(lightAmbientCoefficientID, light.ambientCoefficient);
glUniform3fv(materialColorID, 1, &assetInstance.materialColor[0]);
glUniform1f(materialShininessID, assetInstance.materialShininess);
glUniform3fv(materialSpecularColorID, 1, &assetInstance.materialSpecularColor[0]);
}
and some setup being done here:
OpenGLView::OpenGLView()
{
light.position = glm::vec3(0.0f, 7.0f, 3.0f);
light.intensities = glm::vec3(0.3f, 0.3, 0.3f);
light.attenuation = 0.3f;
light.ambientCoefficient = 0.005f;
cameraPosition = glm::vec3(5.0f, 3.0f, 8.0f);
}
For a while I had the bunny1's position set to 0, 0, 0 which caused it to not be drawn at all, I can't figure out why that is? Then when I changed it to 1, 1, 1 it started to draw, but now my key_callback function (which rotates and scales the bunny) stopped working. Also, here are my translate and scale functions:
glm::mat4 OpenGLView::translate(glm::vec3 position)
{
return glm::translate(glm::mat4(), position);
}
glm::mat4 OpenGLView::scale(glm::vec3 size)
{
return glm::scale(glm::mat4(), size);
}
and I can't figure out why changing bunny1.position seems to scale the bunny instead of translating its position?
The reason why your bunny's scale changes when changing bunny1.position is because you scale your bunny by bunny1.position:
glm::mat4 model = translate(assetInstance.position) * scale(assetInstance.position);
That might also be the reason why the bunny disapears when setting it's position to (0,0,0) since you then scale it to 0.
I am using GLM to manage my matrices, but I am running in to some problems that make no sense to me. When I set the projection matrix to anything other than an identity matrix, I can't see the square I am trying to draw. If it is an identity it will work. Something similiar happens with my view matrix. If I try and translate past -1 or +1 the square will dissapear, otherwise it seems to have no effects.
There are no OpenGL errors, GLSL linker/compiler errors, and glGetUniformLocation returns a valid location. Also the shader program is correctly being used.
Also I have tested the shader to see if it is getting the correct values passed to each of the matrices (by changing the color of the square if the value is correct).
Here's how I set up the projection matrix:
projectionMatrix = glm::perspective(60.0f, (float)windowWidth / (float)windowHeight, 0.1f, 100.0f);
And here's my draw function:
void OpenGLContext::render(void) {
glViewport(0, 0, windowWidth, windowHeight); // Set the viewport size to fill the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Clear required buffers
//Set up matrices
viewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -5.0f));
modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(.5f));
shader->bind();
int projectionMatrixLocation = glGetUniformLocation(shader->id(), "projectionMatrix");
int viewMatrixLocation = glGetUniformLocation(shader->id(), "viewMatrix");
int modelMatrixLocation = glGetUniformLocation(shader->id(), "modelMatrix");
glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix[0][0]);
glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]);
glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]);
glBindVertexArray(vaoID[0]);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
shader->unbind();
SwapBuffers(hdc);
}
Here's the shader.vert
#version 150 core
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
in vec3 in_Position;
in vec3 in_Color;
out vec3 pass_Color;
void main(void)
{
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_Position, 1.0);
pass_Color = in_Color;
}
Here's shader.frag
#version 150 core
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
in vec3 pass_Color;
out vec4 out_Color;
void main(void)
{
out_Color = vec4(pass_Color, 1.0);
}
Sorry forgot about what i'm drawing:
void OpenGLContext::createSquare(void)
{
float* vertices = new float[18];
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]);
glBindVertexArray(vaoID[0]);
glGenBuffers(1, vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID[0]);
glBufferData(GL_ARRAY_BUFFER, 18 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
glVertexAttribPointer((GLuint) 0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0); // Disable our Vertex Array Object
glBindVertexArray(0);
delete [] vertices;
}
Setting my matrices like this results in nothing being drawn on the screen. Like I said if I set the projection and view matrices to an identity it will work. The scaling on the modelMatrix seems to always work as well.
There is no attribute on position 1 (in_Color). If you just left it out of this question, then the problem are the locations, which you are not defining in the shaders. I've never actually tested it without the location part, but I think it's necessary, at least for multiple values: you should use e.g. layout(location = 0) in in_Position.