I’m trying to put a texture on my object (which is a 3D cube) but I’m not sure how to do it because I don’t get the correct result.
This is where I initialize everything:
void OpenGLWindow::initGL()
{
.
.
.
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
shader = loadShaderProgram("simple.vert", "simple.frag");
glUseProgram(shader);
// ambient
glUniform3f(glGetUniformLocation(shader, "objectColor"), 1.0f, 0.5f, 0.31f);
glUniform3f(glGetUniformLocation(shader, "lightColor"), 1.0f, 1.0f, 1.0f);
glUniform3fv(glGetUniformLocation(shader, "lightPos"), 1, &lightPos[0]);
glUniform3f(glGetUniformLocation(shader, "viewPos"), 0.0f, 0.0f, 3.0f);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
int width, height, nrChannels;
unsigned char *data = stbi_load("container.png", &width, &height, &nrChannels, 0);
if (data) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else {
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
// Set our viewing and projection matrices, since these do not change over time
glm::mat4 projectionMat = glm::perspective(glm::radians(90.0f), 4.0f/3.0f, 0.1f, 10.0f);
int projectionMatrixLoc = glGetUniformLocation(shader, "projectionMatrix");
glUniformMatrix4fv(projectionMatrixLoc, 1, false, &projectionMat[0][0]);
glm::vec3 eyeLoc(0.0f, 0.0f, 2.0f);
glm::vec3 targetLoc(0.0f, 0.0f, 0.0f);
glm::vec3 upDir(0.0f, 1.0f, 0.0f);
glm::mat4 viewingMat = glm::lookAt(eyeLoc, targetLoc, upDir);
int viewingMatrixLoc = glGetUniformLocation(shader, "viewingMatrix");
glUniformMatrix4fv(viewingMatrixLoc, 1, false, &viewingMat[0][0]);
// Load the model that we want to use and buffer the vertex attributes
//geometry.loadFromOBJFile("sphere.obj");
geometry.loadFromOBJFile("cube.obj");
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, 3*geometry.vertexCount()*sizeof(float), geometry.vertexData(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
GLuint texturebuffer;
glGenBuffers(1, &texturebuffer);
glBindBuffer(GL_ARRAY_BUFFER, texturebuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(geometry.textureCoordData()) * sizeof(glm::vec3), geometry.textureCoordData(), GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, texturebuffer);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
GLuint normalbuffer;
glGenBuffers(1, &normalbuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(geometry.normalData()) * sizeof(glm::vec3), geometry.normalData(), GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glPrintError("Setup complete", true);
}
I’m reading an .obj file which has the coordinates of the vertices, normals and textures already using a class which stores each coordinates in an appropriate vector;
for e.g. std::vector vertices; std::vector textureCoords; std::vector normals;
How can I send the values inside the texture’s vector to the shader?
This is my vertex shader:
#version 330 core
in vec3 position;
out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoord;
uniform mat4 projectionMatrix;
uniform mat4 viewingMatrix;
uniform mat4 modelMatrix;
void main()
{
vec4 transformedPosition = projectionMatrix * viewingMatrix * modelMatrix * vec4(position, 1.0f);
gl_Position = transformedPosition;
FragPos = vec3(modelMatrix * vec4(position, 1.0));
Normal = mat3(transpose(inverse(modelMatrix))) * position;
}
Fragment shader:
out vec4 outColor;
in vec3 Normal;
in vec3 FragPos;
uniform vec3 lightPos;
uniform vec3 objectColor;
uniform vec3 lightColor;
uniform vec3 viewPos;
void main()
{
float ambientStrength = 0.06;
vec3 ambient = ambientStrength * lightColor;
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
float specularStrength = 0.1;
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * lightColor;
vec3 result = (ambient + diffuse + specular) * objectColor;
outColor = vec4(result, 1.0);
}
Also, I’m using SDL for this.