My Problem is similar to the problems mentioned here.
My Github commit:
When i try to draw a cube in opengl 3.3 on windows with c++, glfw and glad i have the problem, that it only displays a solid color(colour?) based on the original texture. It seems to be a problem with the texture cordinates which are not applied. Shader and cpp code and also RenderDoc further down the post. Ask for more if u need.
Vertex Shader:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
layout (location = 2) in vec3 aNormal;
out vec3 FragPos;
out vec2 TexCoord;
out vec3 Normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(){
gl_Position = projection * view * model * vec4(aPos, 1.0f);
FragPos = vec3(model * vec4(aPos, 1.0));
TexCoord = aTexCoord;
Normal = aNormal;
};
Fragment Shader
- ony uniforms and main functions are important
- commenting in the vec4 only changes the lighting and makes it look 3d
#version 330 core
in vec3 FragPos;
in vec2 TexCoord;
in vec3 Normal;
struct DirLight {
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform DirLight dirLight;
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
struct PointLight {
vec3 position;
float constant;
float linear;
float quadratic;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
#define NR_POINT_LIGHTS 1
uniform PointLight pointLights[NR_POINT_LIGHTS];
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
struct Material {
vec3 specular;
float shininess;
};
uniform Material material;
uniform sampler2D tex_sampler;
uniform vec3 viewPos;
out vec4 FragColor;
void main()
{
// properties
vec3 norm = normalize(Normal);
vec3 viewDir = normalize(viewPos - FragPos);
// phase 1: Directional lighting
vec3 result = CalcDirLight(dirLight, norm, viewDir);
// phase 2: Point lights
for(int i = 0; i < NR_POINT_LIGHTS; i++)
result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);
FragColor = texture(tex_sampler, TexCoord);// * vec4(result, 1.0);
}
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
vec3 lightDir = normalize(-light.direction);
// diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// specular shading
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// combine results
vec3 ambient = light.ambient * vec3(texture(tex_sampler, TexCoord));
vec3 diffuse = light.diffuse * diff * vec3(texture(tex_sampler, TexCoord));
vec3 specular = light.specular * spec * vec3(1.0f, 0.0f, 0.0f);
//return (ambient + diffuse + specular);
return (ambient + diffuse);
}
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
vec3 lightDir = normalize(light.position - fragPos);
// diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// specular shading
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// attenuation
float distance = length(light.position - fragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance +
light.quadratic * (distance * distance));
// combine results
vec3 ambient = light.ambient * vec3(texture(tex_sampler, TexCoord));
vec3 diffuse = light.diffuse * diff * vec3(texture(tex_sampler, TexCoord));
vec3 specular = light.specular * spec * vec3(1.0f, 1.0f, 1.0f);
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return (ambient + diffuse + specular);
}
I load my texture and draw the cube:
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
unsigned int texture = makeTexture(textureDir + "diamond_ore.png");
[...]
defaultShader.use();
// CAMERA
// model matrix set further down, dynamically for each object
//view matrix, transform world space to camera space
glm::mat4 view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
defaultShader.setMatrix4fv("view", view);
//projection matrix, view space to device cordinates
glm::mat4 projection = glm::perspective(glm::radians(fov), 800.0f / 600.0f, 0.1f, 100.0f);
defaultShader.setMatrix4fv("projection", projection);
// DRAWING
//clear color and depth buffer
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
////vertex data, shaders
defaultShader.setVec3("viewPos", cameraPos.x, cameraPos.y, cameraPos.z);
defaultShader.setInt("tex_sampler", 0);
defaultShader.setVec3("material.specular", 1.0f, 0.0f, 0.0f);
defaultShader.setFloat("material.shininess", 32.0f);
defaultShader.setVec3("dirLight.direction", 0.0f, -1.0f, 0.0f);
defaultShader.setVec3("dirLight.ambient", 1.0f, 1.0f, 1.0f);
defaultShader.setVec3("dirLight.diffuse", 0.8f, 0.8f, 0.8f); // darken diffuse light a bit
defaultShader.setVec3("dirLight.specular", 1.0f, 1.0f, 1.0f);
defaultShader.setVec3("pointLights[0].position", -1.0f, -1.0f, -1.0f);
defaultShader.setVec3("pointLights[0].ambient", 0.2f, 0.2f, 0.2f);
defaultShader.setVec3("pointLights[0].diffuse", 0.8f, 0.8f, 0.8f); // darken diffuse light a bit
defaultShader.setVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f);
defaultShader.setFloat("pointLights[0].constant", 1.0f);
defaultShader.setFloat("pointLights[0].linear", 0.045f);
defaultShader.setFloat("pointLights[0].quadratic", 0.0075f);
model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(-1.0, -1.0, -1.0));
defaultShader.setMatrix4fv("model", model);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glDrawArrays(GL_TRIANGLES, 0, 36);
float cube_vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
};
buffers.cpp:
//VAO
VAO::VAO() {
glGenVertexArrays(1, &this->vaoID);
}
void VAO::bind(){
glBindVertexArray(this->vaoID);
}
void VAO::fillFirst() {
this->bind();
this->vbos[0].fillBuffer();
this->setAttribPointer(0, 3, GL_FLOAT, false, 8, 0);
this->setAttribPointer(1, 2, GL_FLOAT, false, 8, 3);
this->setAttribPointer(2, 3, GL_FLOAT, false, 8, 5);
if (this->ebos.size() > 0) {
this->ebos[0].fillBuffer();
}
}
void VAO::setAttribPointer(int attribID, int length, int type, bool normalized, int stride, int offset) {
this->bind();
glVertexAttribPointer(
attribID,
length,
type,
normalized,
stride * sizeof(float),
(void*)(offset * sizeof(float))
);
glEnableVertexAttribArray(attribID);
}
//VBO
VBO::VBO(std::vector<Vertex> vertices) {
glGenBuffers(1, &this->vboID);
this->vertices = vertices;
}
void VBO::fillBuffer() {
glBindBuffer(GL_ARRAY_BUFFER, this->vboID);
std::cout << sizeof(this->vertices[0]) << ":" << sizeof(&this->vertices[0]) << std::endl;
glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(this->vertices[0]), &this->vertices[0], GL_STATIC_DRAW);
}
RenderDoc:
Edit 1:
I replaced FragColor = texture(tex_sampler, TexCoord);// * vec4(result, 1.0);
in the fragment shader with FragColor = vec4(TexCoord.x * TexCoord.x, TexCoord.y * TexCoord.y, 1.0, 1.0);
which leads to a regular change in color and implies, that the texture cordinates are passed to the fragment shader. There seem to be wrong or missing parts somewhere which are required for using opengl textures.