This question already has an answer here:
light source is not set correctly
(1 answer)
Closed 1 year ago.
I have this picture below that shows the 3D model and the light is not as I expected, I've already tried many ways but I can't figure out how to fix it. my normal vectors are fine
the goemetry:
glGenVertexArrays(1, &VAOArray);
glBindVertexArray(VAOArray);
/* GENERATE THE BUFFERS */
glGenBuffers(1, &bufferArray);
/* SELECT THAT BUFFER TO WORK WITH */
glBindBuffer(GL_ARRAY_BUFFER, bufferArray);
glBufferData(GL_ARRAY_BUFFER, myMeshes.at(j).realPositions.size() * sizeof(float), (GLfloat*)RealPos, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glGenBuffers(1, &normalArray);
glBindBuffer(GL_ARRAY_BUFFER, normalArray);
glBufferData(GL_ARRAY_BUFFER, myMeshes.at(j).realNormals.size()*sizeof(float), (GLfloat*)RealNor, GL_STATIC_DRAW);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(3);
this is my code:
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);
projection = glm::perspective(glm::radians(45.0f), (float)width / (float)heigh, 0.1f, 100.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, transZ)); //this is for scroll mouse
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -2.0f));
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -5.0f));
glUseProgram(programT);
int lightColorLoc = glGetUniformLocation(programT, "lightColor");
glUniformMatrix4fv(lightColorLoc, 1, GL_FALSE, glm::value_ptr(glm::vec3(1.0f, 0.0f, 0.0f)));
int objectColorLoc = glGetUniformLocation(programT, "objectColor");
glUniformMatrix4fv(objectColorLoc, 1, GL_FALSE, glm::value_ptr(glm::vec3(1.0f, 0.5f, 0.31f)));
glm::vec3 lightPos(2.0f, 4.0f, 5.0f);
int lightPosLoc = glGetUniformLocation(programT, "lightPos");
glUniformMatrix4fv(lightPosLoc, 1, GL_FALSE, glm::value_ptr(lightPos));
int projectionLocLight = glGetUniformLocation(programT, "projection");
glUniformMatrix4fv(projectionLocLight, 1, GL_FALSE, glm::value_ptr(projection));
glm::mat4 modelLight = glm::mat4(1.0f);
int modelLocLight = glGetUniformLocation(programT, "model");
glUniformMatrix4fv(modelLocLight, 1, GL_FALSE, glm::value_ptr(modelLight));
glm::mat4 viewLight = glm::mat4(1.0f);
int viewLocLight = glGetUniformLocation(programT, "view");
glUniformMatrix4fv(viewLocLight, 1, GL_FALSE, glm::value_ptr(viewLight));
int viewLoc = glGetUniformLocation(programT, "view");
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
int projectionLoc = glGetUniformLocation(programT, "projection");
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
model = glm::rotate(model, glm::radians(rotX), glm::vec3(1.0f, 0.0f, 0.0f));
model = glm::rotate(model, glm::radians(rotY), glm::vec3(.0f, 1.0f, .0f));
model = glm::rotate(model, glm::radians(rotZ), glm::vec3(.0f, 0.0f, 1.0f));
int modelLoc = glGetUniformLocation(programT, "model");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glGenerateMipmap(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureArray[0]);
glUniform1i(glGetUniformLocation(programT, "ourTexture"), 0);
glBindVertexArray(VAOArray[0]);
glDrawArrays(GL_TRIANGLES, 0, myMeshes.at(0).Indices.size());
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
glfwSetKeyCallback(window, key_callback);
glfwSetScrollCallback(window, scroll_callback);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
}
vertex shader used for this project:
#version 330 core
layout (location = 0) in vec3 RealPos;
layout (location = 1) in vec3 vertex_color;
layout (location = 2) in vec2 vertex_textcoord;
layout (location = 3) in vec3 RealNor;
out vec3 vs_pos;
out vec3 vs_color;
out vec2 vs_text;
out vec3 normal;
out vec3 FragPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
vs_pos = RealPos;
vs_color = vertex_color;
vs_text=vertex_textcoord;
FragPos = vec3(model * vec4(vs_pos, 1.0));
mat3 normalMat = mat3(inverse(transpose(model)));
normal = RealNor * normalMat;
gl_Position = projection * view * model * vec4(vs_pos, 1.0);
}
fragment shader used:
#version 330 core
in vec2 vs_text;
in vec3 normal;
in vec3 FragPos;
uniform vec3 lightPos;
out vec4 gl_FragColor;
uniform vec3 objectColor;
uniform vec3 lightColor;
uniform sampler2D ourTexture;
void main()
{
vec3 norm = normalize(normal);
vec3 lightDir = normalize(lightPos - FragPos);
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
float diff = max(abs(dot(norm, lightDir)), 0.0);
vec3 diffuse = diff * lightColor;
vec3 result = (ambient + diffuse) * objectColor;
gl_FragColor = texture(ourTexture, vs_text) * diff;
}
can someone help me to fix this or maybe guide me to solve it?
thanks
It applies that matrix * vector == vector * (matrix)^T
You are calculating normals via normal = RealNor * normalMat;
This is not equal to normalMat * RealNor which results in wrong normals. So kommutate the expression to normalMat * RealNor and see if it fixes the issue.
Related
I'm making a simple game in OpenGL where there is one player and multiple bubbles, all being spheres. Unfortunately, instancing doesn't work as expected and causes some strange effects. I'm new to instancing and can't see what may be causing a problem.
Draw method in player class:
void Player::draw(glm::mat4 ViewMat, GLfloat aspect, glm::vec3 light, GLfloat zoom)
{
bindProgram();
bindBuffers();
glm::mat4 Projection = glm::perspective(zoom, aspect, 0.1f, 100.0f);
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 MVP = Projection * ViewMat * Model;
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "MVP"), 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "M"), 1, GL_FALSE, &Model[0][0]);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "V"), 1, GL_FALSE, &ViewMat[0][0]);
glUniform3f(glGetUniformLocation(shaderProgram, "origin"), origin.x, origin.y, origin.z);
glUniform3f(glGetUniformLocation(shaderProgram, "lightPosWorld"), light.x, light.y, light.z);
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size() / 3);
}
Static draw method in bubble class:
void Bubble::drawAll(glm::mat4 ViewMat, GLfloat aspect, glm::vec3 light, GLfloat zoom,
std::vector<Bubble *> allInstances)
{
std::vector<float> origins;
uint count = 0;
for (auto b : allInstances)
{
origins.push_back(b->origin.x);
origins.push_back(b->origin.y);
origins.push_back(b->origin.z);
count++;
}
allInstances[0]->bindProgram();
allInstances[0]->bindBuffers();
glBufferData(GL_ARRAY_BUFFER, origins.size() * sizeof(origins), origins.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, originsBuffer);
glVertexAttribPointer(1, // attribute. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void *)0 // array buffer offset
);
glm::mat4 Projection = glm::perspective(zoom, aspect, 0.1f, 100.0f);
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 MVP = Projection * ViewMat * Model;
GLuint programID = allInstances[0]->shaderProgram;
glVertexAttribDivisor(0, 0);
glVertexAttribDivisor(1, 1);
glUniformMatrix4fv(glGetUniformLocation(programID, "MVP"), 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(glGetUniformLocation(programID, "M"), 1, GL_FALSE, &Model[0][0]);
glUniformMatrix4fv(glGetUniformLocation(programID, "V"), 1, GL_FALSE, &ViewMat[0][0]);
glUniform3f(glGetUniformLocation(programID, "lightPosWorld"), light.x, light.y, light.z);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, allInstances[0]->vertices.size() / 3, count);
}
Player vertex shader:
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
uniform mat4 MVP;
uniform mat4 M;
uniform mat4 V;
uniform vec3 origin;
uniform vec3 lightPosWorld;
uniform vec3 cameraPos;
out vec3 vertexPosWorld;
out vec3 vertexNormal;
out vec3 eyeDirectionCamera;
out vec3 lightDirectionCamera;
void main()
{
gl_Position = MVP * vec4(vertexPosition_modelspace + origin,1);
vertexPosWorld = (M * vec4(vertexPosition_modelspace + origin,1)).xyz;
vertexNormal = normalize(vertexPosWorld - origin);
}
Bubble vertex shader:
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 origin;
uniform mat4 MVP;
uniform mat4 M;
uniform mat4 V;
uniform vec3 lightPosWorld;
uniform vec3 cameraPos;
out vec3 vertexPosWorld;
out vec3 vertexNormal;
out vec3 eyeDirectionCamera;
out vec3 lightDirectionCamera;
void main()
{
gl_Position = MVP * vec4(vertexPosition_modelspace + origin,1);
vertexPosWorld = (M * vec4(vertexPosition_modelspace + origin,1)).xyz;
vertexNormal = normalize(vertexPosWorld - origin);
}
This is what I get:
Effect
But I wanted to get two bubbles that look exactly like the player (which draws correctly).
There are 2 issues in the code:
sizeof(origins) is a byte size of std::vector but not its underlying type. It should be sizeof(float).
glBindBuffer should be called before modifying the buffer’s data and properties.
It should help:
glBindBuffer(GL_ARRAY_BUFFER, originsBuffer);
glBufferData(GL_ARRAY_BUFFER, origins.size() * sizeof(float), origins.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, // attribute. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void *)0 // array buffer offset
);
I have this code but the light seems not working correctly, when I render the object it's dark, then when I rotate it, the light source seems to be rotated too. I can't figure out where the problem is. I tried to modify the model for the light but still not working
this is the program:
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);
projection = glm::perspective(glm::radians(45.0f), (float)width / (float)heigh, 0.1f, 100.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, transZ)); //this is for scroll mouse
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -2.0f));
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -5.0f));
glUseProgram(programT);
int lightColorLoc = glGetUniformLocation(programT, "lightColor");
glUniformMatrix4fv(lightColorLoc, 1, GL_FALSE, glm::value_ptr(glm::vec3(1.0f, 0.0f, 0.0f)));
int objectColorLoc = glGetUniformLocation(programT, "objectColor");
glUniformMatrix4fv(objectColorLoc, 1, GL_FALSE, glm::value_ptr(glm::vec3(1.0f, 0.5f, 0.31f)));
glm::vec3 lightPos(2.0f, 4.0f, 5.0f);
int lightPosLoc = glGetUniformLocation(programT, "lightPos");
glUniformMatrix4fv(lightPosLoc, 1, GL_FALSE, glm::value_ptr(lightPos));
int projectionLocLight = glGetUniformLocation(programT, "projection");
glUniformMatrix4fv(projectionLocLight, 1, GL_FALSE, glm::value_ptr(projection));
glm::mat4 modelLight = glm::mat4(1.0f);
int modelLocLight = glGetUniformLocation(programT, "model");
glUniformMatrix4fv(modelLocLight, 1, GL_FALSE, glm::value_ptr(modelLight));
glm::mat4 viewLight = glm::mat4(1.0f);
int viewLocLight = glGetUniformLocation(programT, "view");
glUniformMatrix4fv(viewLocLight, 1, GL_FALSE, glm::value_ptr(viewLight));
int viewLoc = glGetUniformLocation(programT, "view");
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
int projectionLoc = glGetUniformLocation(programT, "projection");
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
model = glm::rotate(model, glm::radians(rotX), glm::vec3(1.0f, 0.0f, 0.0f));
model = glm::rotate(model, glm::radians(rotY), glm::vec3(.0f, 1.0f, .0f));
model = glm::rotate(model, glm::radians(rotZ), glm::vec3(.0f, 0.0f, 1.0f));
int modelLoc = glGetUniformLocation(programT, "model");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glGenerateMipmap(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureArray[0]);
glUniform1i(glGetUniformLocation(programT, "ourTexture"), 0);
glBindVertexArray(VAOArray[0]);
glDrawArrays(GL_TRIANGLES, 0, myMeshes.at(0).Indices.size());
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
glfwSetKeyCallback(window, key_callback);
glfwSetScrollCallback(window, scroll_callback);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
}
the following is my vertex shader:
#version 330 core
layout (location = 0) in vec3 RealPos;
layout (location = 1) in vec3 vertex_color;
layout (location = 2) in vec2 vertex_textcoord;
layout (location = 3) in vec3 RealNor;
out vec3 vs_pos;
out vec3 vs_color;
out vec2 vs_text;
out vec3 normal;
out vec3 FragPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
vs_pos = RealPos;
vs_color = vertex_color;
vs_text=vertex_textcoord;
normal=RealNor;
FragPos = vec3(model * vec4(vs_pos, 1.0));
gl_Position = projection * view * model * vec4(vs_pos, 1.0);
}
and the following is the fragment shader:
#version 330 core
in vec2 vs_text;
in vec3 normal;
in vec3 FragPos;
uniform vec3 lightPos;
out vec4 gl_FragColor;
uniform vec3 objectColor;
uniform vec3 lightColor;
uniform sampler2D ourTexture;
void main()
{
vec3 norm = normalize(normal);
vec3 lightDir = normalize(lightPos - FragPos);
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
vec3 result = (ambient + diffuse) * objectColor;
gl_FragColor = texture(ourTexture, vs_text) * vec4(result,1.0);
}
how can I solve the problem?
The light calculations in the fragment shader are done in world space. Therefore, you have to transform the normal vector with the normal matrix from object space to world space:
mat3 normalMatrix = transpose(inverse(mat3(model)));
normal = normalMatrix * RealNor;
FragPos = vec3(model * vec4(vs_pos, 1.0));
See Why is the transposed inverse of the model view matrix used to transform the normal vectors?
and Why transforming normals with the transpose of the inverse of the modelview matrix?
Imagine a spinner and a reading lamp on a table. Your eyes are the camera. The model matrix models the spinning. This causes different sides of the spinner to be illuminated as it rotates. However, the position of the lamp does not change relative to your position.
The relative position of the lamp changes when you change your position (the position of the eyes). This can be modeled by changing the view matrix.
I am trying to incorporate both normal mapping & cube mapping into a single program, but I am having trouble getting them to render correctly. I am working on a simple exercise to help me with that before going onto something more complexed. I am trying to render both these objects into a single program. They both have different textures and the torus uses cube mapping while the wall uses normal mapping.
These are what they are supposed to look like individually:
Currently, this is what I've got. The torus renders correctly but the wall's textures don't appear.
I am using 2 separate shader programs for this, and it is my first time using more than 1 shader program, for a program. I suspect my issue could be with the initialising of shader variables, or something really obvious that I'm just not getting. I am using two different Vertex structs for the objects.
struct Vertex2
{
GLfloat position[3];
GLfloat normal[3];
GLfloat tangent[3];
GLfloat texCoord[2];
};
Vertex2 g_vertices[] = {
// Front: triangle 1
// vertex 1
-1.0f, 1.0f, 0.0f, // position
0.0f, 0.0f, 1.0f, // normal
1.0f, 0.0f, 0.0f, // tangent
0.0f, 1.0f, // texture coordinate
// vertex 2
-1.0f, -1.0f, 0.0f, // position
0.0f, 0.0f, 1.0f, // normal
1.0f, 0.0f, 0.0f, // tangent
0.0f, 0.0f, // texture coordinate
// vertex 3
1.0f, 1.0f, 0.0f, // position
0.0f, 0.0f, 1.0f, // normal
1.0f, 0.0f, 0.0f, // tangent
1.0f, 1.0f, // texture coordinate
// triangle 2
// vertex 1
1.0f, 1.0f, 0.0f, // position
0.0f, 0.0f, 1.0f, // normal
1.0f, 0.0f, 0.0f, // tangent
1.0f, 1.0f, // texture coordinate
// vertex 2
-1.0f, -1.0f, 0.0f, // position
0.0f, 0.0f, 1.0f, // normal
1.0f, 0.0f, 0.0f, // tangent
0.0f, 0.0f, // texture coordinate
// vertex 3
1.0f, -1.0f, 0.0f, // position
0.0f, 0.0f, 1.0f, // normal
1.0f, 0.0f, 0.0f, // tangent
1.0f, 0.0f, // texture coordinate
};
Main.cpp init function:
static void init(GLFWwindow* window)
{
glEnable(GL_DEPTH_TEST); // enable depth buffer test
glEnable(GL_TEXTURE_2D);
// read the image data
GLint imageWidth[5]; //image width info
GLint imageHeight[5]; //image height info
g_texImage[FRONT] = readBitmapRGBImage("images/cm_front.bmp", &imageWidth[0], &imageHeight[0]);
g_texImage[BACK] = readBitmapRGBImage("images/cm_back.bmp", &imageWidth[0], &imageHeight[0]);
g_texImage[LEFT] = readBitmapRGBImage("images/cm_left.bmp", &imageWidth[0], &imageHeight[0]);
g_texImage[RIGHT] = readBitmapRGBImage("images/cm_right.bmp", &imageWidth[0], &imageHeight[0]);
g_texImage[TOP] = readBitmapRGBImage("images/cm_top.bmp", &imageWidth[0], &imageHeight[0]);
g_texImage[BOTTOM] = readBitmapRGBImage("images/cm_bottom.bmp", &imageWidth[0], &imageHeight[0]);
g_texImage[6] = readBitmapRGBImage("images/Fieldstone.bmp", &imageWidth[1], &imageHeight[1]);
g_texImage[7] = readBitmapRGBImage("images/FieldstoneBumpDOT3.bmp", &imageWidth[2], &imageHeight[2]);
glGenTextures(10, g_textureID);
// ...
// create and compile our GLSL program from the shader files
g_shaderProgramID[0] = loadShaders("CubeEnvMapVS.vert", "CubeEnvMapFS.frag");
g_shaderProgramID[1] = loadShaders("NormalMappingVS.vert", "NormalMappingFS.frag");
// find the location of shader variables
for (int i = 0; i < 2; i++)
{
positionIndex[i] = glGetAttribLocation(g_shaderProgramID[i], "aPosition");
normalIndex[i] = glGetAttribLocation(g_shaderProgramID[i], "aNormal");
texCoordIndex[i] = glGetAttribLocation(g_shaderProgramID[i], "aTexCoord");
g_MVP_Index[i] = glGetUniformLocation(g_shaderProgramID[i], "uModelViewProjectionMatrix");
g_M_Index[i] = glGetUniformLocation(g_shaderProgramID[i], "uModelMatrix");
g_viewPointIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uViewPoint");
g_lightPositionIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.position");
g_lightAmbientIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.ambient");
g_lightDiffuseIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.diffuse");
g_lightSpecularIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.specular");
g_lightShininessIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.shininess");
g_materialAmbientIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uMaterialProperties.ambient");
g_materialDiffuseIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uMaterialProperties.diffuse");
g_materialSpecularIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uMaterialProperties.specular");
}
g_envMapSamplerIndex = glGetUniformLocation(g_shaderProgramID[0], "uEnvironmentMap");
tangentIndex = glGetAttribLocation(g_shaderProgramID[1], "aTangent");
g_texSamplerIndex = glGetUniformLocation(g_shaderProgramID[1], "uTextureSampler");
g_normalSamplerIndex = glGetUniformLocation(g_shaderProgramID[1], "uNormalSampler");
// initialise model matrix to the identity matrix
g_mm_torus = glm::mat4(1.0f);
g_mm_wall = mat4(1.0f);
// ...
// load mesh
// load_mesh("models/sphere.obj");
load_mesh("models/torus.obj");
// ...
// generate identifier for VBOs and copy data to GPU
glGenBuffers(5, g_VBO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*g_numberOfVertices, g_pMeshVertices, GL_STATIC_DRAW);
// generate identifier for IBO and copy data to GPU
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_VBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * 3 * g_numberOfFaces, g_pMeshIndices, GL_STATIC_DRAW);
// generate identifiers for VAO
glGenVertexArrays(5, g_VAO);
// create VAO and specify VBO data
glBindVertexArray(g_VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_VBO[1]);
glVertexAttribPointer(positionIndex[0], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)));
glVertexAttribPointer(normalIndex[0], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)));
glEnableVertexAttribArray(positionIndex[0]); // enable vertex attributes
glEnableVertexAttribArray(normalIndex[0]);
// generate identifier for VBOs and copy data to GPU
glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices), g_vertices, GL_STATIC_DRAW);
// create VAO and specify VBO data
glBindVertexArray(g_VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
glVertexAttribPointer(positionIndex[1], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast<void*>(offsetof(Vertex2, position)));
glVertexAttribPointer(normalIndex[1], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast<void*>(offsetof(Vertex2, normal)));
glVertexAttribPointer(tangentIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast<void*>(offsetof(Vertex2, tangent)));
glVertexAttribPointer(texCoordIndex[0], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast<void*>(offsetof(Vertex2, texCoord)));
// enable vertex attributes
glEnableVertexAttribArray(positionIndex[1]);
glEnableVertexAttribArray(normalIndex[1]);
glEnableVertexAttribArray(tangentIndex);
glEnableVertexAttribArray(texCoordIndex[0]);
}
Render scene function:
static void render_scene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear colour buffer and depth buffer
glUseProgram(g_shaderProgramID[0]); // use the shaders associated with the shader program
glBindVertexArray(g_VAO[0]); // make VAO active
// set uniform shader variables
glm::mat4 MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_torus;
glUniformMatrix4fv(g_MVP_Index[0], 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(g_M_Index[0], 1, GL_FALSE, &g_mm_torus[0][0]);
glUniform3fv(g_viewPointIndex[0], 1, &g_camera.getPosition()[0]);
glUniform4fv(g_lightPositionIndex[0], 1, &g_lightProperties.position[0]);
glUniform4fv(g_lightAmbientIndex[0], 1, &g_lightProperties.ambient[0]);
glUniform4fv(g_lightDiffuseIndex[0], 1, &g_lightProperties.diffuse[0]);
glUniform4fv(g_lightSpecularIndex[0], 1, &g_lightProperties.specular[0]);
glUniform1fv(g_lightShininessIndex[0], 1, &g_lightProperties.shininess);
glUniform4fv(g_materialAmbientIndex[0], 1, &g_materialProperties.ambient[0]);
glUniform4fv(g_materialDiffuseIndex[0], 1, &g_materialProperties.diffuse[0]);
glUniform4fv(g_materialSpecularIndex[0], 1, &g_materialProperties.specular[0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, g_textureID[0]);
glUniform1i(g_envMapSamplerIndex, 0);
glDrawElements(GL_TRIANGLES, g_numberOfFaces * 3, GL_UNSIGNED_INT, 0); // display the vertices based on their indices and primitive type
glUseProgram(g_shaderProgramID[1]); // use the shaders associated with the shader program
glBindVertexArray(g_VAO[1]); // make VAO active
// set uniform shader variables
glClear(GL_DEPTH_BUFFER_BIT);
MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_wall;
glUniformMatrix4fv(g_MVP_Index[1], 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(g_M_Index[1], 1, GL_FALSE, &g_mm_wall[0][0]);
glUniform3fv(g_viewPointIndex[1], 1, &g_camera.getPosition()[0]);
glUniform4fv(g_lightPositionIndex[1], 1, &g_lightProperties.position[0]);
glUniform4fv(g_lightAmbientIndex[1], 1, &g_lightProperties.ambient[0]);
glUniform4fv(g_lightDiffuseIndex[1], 1, &g_lightProperties.diffuse[0]);
glUniform4fv(g_lightSpecularIndex[1], 1, &g_lightProperties.specular[0]);
glUniform1fv(g_lightShininessIndex[1], 1, &g_lightProperties.shininess);
glUniform4fv(g_materialAmbientIndex[1], 1, &g_materialProperties.ambient[0]);
glUniform4fv(g_materialDiffuseIndex[1], 1, &g_materialProperties.diffuse[0]);
glUniform4fv(g_materialSpecularIndex[1], 1, &g_materialProperties.specular[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, g_textureID[6]);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, g_textureID[7]);
glUniform1i(g_texSamplerIndex, 1);
glUniform1i(g_normalSamplerIndex, 2);
glDrawArrays(GL_TRIANGLES, 0, 36);
glFlush(); // flush the pipeline
}
Vertex shader for torus:
#version 330 core
// input data (different for all executions of this shader)
in vec3 aPosition;
in vec3 aNormal;
// uniform input data
uniform mat4 uModelViewProjectionMatrix;
uniform mat4 uModelMatrix;
// output data (will be interpolated for each fragment)
out vec3 vNormal;
out vec3 vPosition;
void main()
{
// set vertex position
gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0);
// world space
vPosition = (uModelMatrix * vec4(aPosition, 1.0)).xyz;
vNormal = (uModelMatrix * vec4(aNormal, 0.0)).xyz;
}
Fragment shader for torus:
#version 330 core
// interpolated values from the vertex shaders
in vec3 vNormal;
in vec3 vPosition;
// uniform input data
struct LightProperties
{
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
float shininess;
};
struct MaterialProperties
{
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
uniform LightProperties uLightingProperties;
uniform MaterialProperties uMaterialProperties;
uniform vec3 uViewPoint;
uniform samplerCube uEnvironmentMap;
// output data
out vec3 fColor;
void main()
{
vec3 N = normalize(vNormal);
vec3 L;
// determine whether the light is a point light source or directional light
if(uLightingProperties.position.w == 0.0f)
L = normalize((uLightingProperties.position).xyz);
else
L = normalize((uLightingProperties.position).xyz - vPosition);
vec3 V = normalize(uViewPoint - vPosition);
vec3 R = reflect(-L, N);
// calculate the ambient, diffuse and specular components
vec4 ambient = uLightingProperties.ambient * uMaterialProperties.ambient;
vec4 diffuse = uLightingProperties.diffuse * uMaterialProperties.diffuse * max(dot(L, N), 0.0);
vec4 specular = vec4(0.0f, 0.0f, 0.0f, 1.0f);
if(dot(L, N) > 0.0f)
{
specular = uLightingProperties.specular * uMaterialProperties.specular
* pow(max(dot(V, R), 0.0), uLightingProperties.shininess);
}
vec3 reflectEnvMap = reflect(-V, N);
// set output color
fColor = texture(uEnvironmentMap, reflectEnvMap).rgb;
fColor *= (diffuse + specular + ambient).rgb;
}
Vertex shader for wall:
#version 330 core
// input data (different for all executions of this shader)
in vec3 aPosition;
in vec3 aNormal;
in vec3 aTangent;
in vec2 aTexCoord;
// uniform input data
uniform mat4 uModelViewProjectionMatrix;
uniform mat4 uModelMatrix;
// output data (will be interpolated for each fragment)
out vec3 vPosition;
out vec3 vNormal;
out vec3 vTangent;
out vec2 vTexCoord;
void main()
{
// set vertex position
gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0);
// world space
vPosition = (uModelMatrix * vec4(aPosition, 1.0)).xyz;
vNormal = (uModelMatrix * vec4(aNormal, 0.0)).xyz;
vTangent = (uModelMatrix * vec4(aTangent, 0.0)).xyz;
vTexCoord = aTexCoord;
}
Fragment shader for wall:
#version 330 core
// interpolated values from the vertex shaders
in vec3 vPosition;
in vec3 vNormal;
in vec3 vTangent;
in vec2 vTexCoord;
// uniform input data
struct LightProperties
{
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
float shininess;
};
struct MaterialProperties
{
vec4 ambient;
vec4 diffuse;
vec4 specular;
};
uniform LightProperties uLightingProperties;
uniform MaterialProperties uMaterialProperties;
uniform vec3 uViewPoint;
uniform sampler2D uTextureSampler;
uniform sampler2D uNormalSampler;
// output data
out vec3 fColor;
void main()
{
// calculate normal map vectors
vec3 normal = normalize(vNormal);
vec3 tangent = normalize(vTangent);
vec3 biTangent = normalize(cross(tangent, normal));
vec3 normalMap = 2.0f * texture(uNormalSampler, vTexCoord).xyz - 1.0f;
// calculate vectors for lighting
vec3 N = normalize(mat3(tangent, biTangent, normal) * normalMap);
vec3 L;
// determine whether the light is a point light source or directional light
if(uLightingProperties.position.w == 0.0f)
L = normalize((uLightingProperties.position).xyz);
else
L = normalize((uLightingProperties.position).xyz - vPosition);
vec3 V = normalize(uViewPoint - vPosition);
vec3 R = reflect(-L, N);
// calculate Phong lighting
vec4 ambient = uLightingProperties.ambient * uMaterialProperties.ambient;
vec4 diffuse = uLightingProperties.diffuse * uMaterialProperties.diffuse * max(dot(L, N), 0.0);
vec4 specular = vec4(0.0f, 0.0f, 0.0f, 1.0f);
if(dot(L, N) > 0.0f)
{
specular = uLightingProperties.specular * uMaterialProperties.specular
* pow(max(dot(V, R), 0.0), uLightingProperties.shininess);
}
// set output color
fColor = (diffuse + specular + ambient).rgb;
fColor *= texture(uTextureSampler, vTexCoord).rgb;
}
PS: Sorry if I was a bit too irresponsible with my questions yesterday. Some of the advice I just didn't understand and thus didn't reply.
When you are drawing the 2nd part (wall), then you are binding the textures to the texture units GL_TEXTURE1 and GL_TEXTURE2:
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, g_textureID[6]);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, g_textureID[7]);
But you are setting the texture unit indices 0 and 1 to the texture sampler uniforms uTextureSampler and uNormalSampler:
glUniform1i(g_texSamplerIndex, 0);
glUniform1i(g_normalSamplerIndex, 1);`
Adapt your code like this:
glUniform1i(g_texSamplerIndex, 1); // GL_TEXTURE1
glUniform1i(g_normalSamplerIndex, 2); // GL_TEXTURE2
Further the attribute index of "aTexCoord" is stored to texCoordIndex[i] for g_shaderProgramID[i]:
for (int i = 0; i < 2; i++)
{
....
texCoordIndex[i] = glGetAttribLocation(g_shaderProgramID[i], "aTexCoord");
.....
}
You have to be aware of this when set up the vertex attribute pointer and enable the vertex attribute
Change this:
glVertexAttribPointer(texCoordIndex[0], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast<void*>(offsetof(Vertex2, texCoord)));
.....
glEnableVertexAttribArray(texCoordIndex[0]);
To this:
glVertexAttribPointer(texCoordIndex[1], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast<void*>(offsetof(Vertex2, texCoord)));
.....
glEnableVertexAttribArray(texCoordIndex[1]);
And the error is "Access violation reading location in nvoglv64.dll"
The program worked as intended on my old AMD Radeon HD 6970. A few days ago I bought a GTX 970. Great card, but I would like my program to work. I want to render a quad to the screen for deferred rendering. I try to use OpenGL 4.4
Source:
Preparing the quad:
modelMatrix = mat4(1.0);
vertices.push_back(vec3(-1.0f, -1.0f, 0.0f));
vertices.push_back(vec3(1.0f, -1.0f, 0.0f));
vertices.push_back(vec3(1.0f, 1.0f, 0.0f));
vertices.push_back(vec3(-1.0f, -1.0f, 0.0f));
vertices.push_back(vec3(1.0f, 1.0f, 0.0f));
vertices.push_back(vec3(-1.0f, 1.0f, 0.0f));
normals.push_back(vec3(0.0f, 0.0f, 1.0f));
normals.push_back(vec3(0.0f, 0.0f, 1.0f));
normals.push_back(vec3(0.0f, 0.0f, 1.0f));
normals.push_back(vec3(0.0f, 0.0f, 1.0f));
normals.push_back(vec3(0.0f, 0.0f, 1.0f));
normals.push_back(vec3(0.0f, 0.0f, 1.0f));
indices.push_back(0);
indices.push_back(1);
indices.push_back(2);
indices.push_back(0);
indices.push_back(2);
indices.push_back(3);
uvs.push_back(vec2(0.0f, 0.0f));
uvs.push_back(vec2(1.0f, 0.0f));
uvs.push_back(vec2(1.0f, 1.0f));
uvs.push_back(vec2(0.0f, 0.0f));
uvs.push_back(vec2(1.0f, 1.0f));
uvs.push_back(vec2(0.0f, 1.0f));
indexCount = static_cast<int>(indices.size());
is2D = true;
unsigned int handle[2];
glGenBuffers(2, handle);
glBindBuffer(GL_ARRAY_BUFFER, handle[0]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, handle[1]);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec3), &uvs[0], GL_STATIC_DRAW);
glGenVertexArrays(1, &array2D);
glBindVertexArray(array2D);
glBindBuffer(GL_ARRAY_BUFFER, handle[0]);
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, ((GLubyte *)NULL + (0)));
glEnableVertexAttribArray(0); // Vertex position
glBindBuffer(GL_ARRAY_BUFFER, handle[1]);
glVertexAttribPointer((GLuint)2, 2, GL_FLOAT, GL_FALSE, 0, ((GLubyte *)NULL + (0)));
glEnableVertexAttribArray(1); // Texture coordinates
glBindVertexArray(0);
Rendering the quad:
// The following three lines are called in the render loop (as 2nd pass).
// I skip rendering meshes in the first pass to better understand this error.
//sp->useSubRoutine(srp2); // SP is the shader program
//sp->resetMatrices(); // Set matrices to mat4(1.0);
//dq->render(); // DQ is the display quad
glBindFramebuffer(GL_FRAMEBUFFER, fbo); // fbo is 0 for quad
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
if (shader != nullptr)
{
shader->use();
shader->setModelMatrix(modelMatrix);
}
if (is2D)
{
glBindVertexArray(array2D);
glDrawArrays(GL_TRIANGLES, 0, indexCount); // ERROR HERE
return;
}
Vertex Shader:
#version 440
layout(location = 0) in vec3 vertexPosition;
layout(location = 1) in vec2 vertexUV;
layout(location = 2) in vec3 vertexNormal;
centroid out vec2 UV;
out vec4 position;
out vec3 normal;
uniform mat4 uniMatModel;
uniform mat4 uniMatView;
uniform mat4 uniMatProjection;
uniform mat4 uniMatModelView;
uniform mat4 uniMatModelViewProjection;
uniform mat3 uniMatNormal;
void main()
{
UV = vertexUV;
position = uniMatModelView * vec4(vertexPosition, 1.0);
normal = normalize(uniMatNormal * vertexNormal);
gl_Position = uniMatModelViewProjection * vec4(vertexPosition, 1.0);
}
Fragment Shader:
#version 440
struct lightInfo {
vec4 position;
vec3 intensity;
bool isActive;
};
// IN
centroid in vec2 UV;
in vec4 position;
in vec3 normal;
// OUT
layout (location = 0) out vec4 fragColor;
layout (location = 1) out vec3 positionData;
layout (location = 2) out vec3 normalData;
layout (location = 3) out vec3 colorData;
// SUBROUTINES
subroutine void renderPassType();
subroutine uniform renderPassType renderPass;
// UNIFORMS
uniform sampler2D uniSamTexture;
uniform sampler2D uniSamAlpha;
uniform sampler2D uniSamAmbient;
uniform sampler2D uniSamSpecular;
uniform sampler2D uniSamShininess;
uniform lightInfo uniPointLights[32];
uniform vec3 uniVec3AmbientEmissiveness;
layout(binding=0) uniform sampler2D positionTex;
layout(binding=1) uniform sampler2D normalTex;
layout(binding=2) uniform sampler2D colorTex;
subroutine (renderPassType)
void renderWorld()
{
if (texture2D(uniSamAlpha, UV).rgb[0] == 1.0) // Alphamaps have to be inverted
{
discard;
}
else
{
colorData = texture2D(uniSamTexture, UV).rgb;
}
positionData = vec3(position.x, position.y, position.z);
normalData = normal;
fragColor = vec4(colorData, 1.0);
}
subroutine (renderPassType)
void renderLight()
{
fragColor = vec4(1.0,0.0,0.0,1.0); // For testing purposes set to red
}
void main()
{
renderPass();
}
Such problems can occure on NVIDIA cards when you try to read from a vertex buffer that does not have enough elements in it. For example rendering 9 vertices from a buffer that only contains 6. AMD interestingly does not complain about that.
In your case you bind a vertex buffer to attribute location 2, but you activate location 1. This:
glVertexAttribPointer((GLuint)2, 2, GL_FLOAT, GL_FALSE, 0, ((GLubyte *)NULL + (0)));
glEnableVertexAttribArray(1); // Texture coordinates
should actually be
||
\/
glVertexAttribPointer((GLuint)1, 2, GL_FLOAT, GL_FALSE, 0, ((GLubyte *)NULL + (0)));
glEnableVertexAttribArray(1); // Texture coordinates
Edit:
I just saw another thing
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec3), &uvs[0], GL_STATIC_DRAW);
uvs.size() equals 6 in your application, so OpenGL will try to read 6 * 3 = 18 float. Your uvs-array only contains 12 floats (since you are using vec2 here).
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.