I am following an OpenGL tutorial in C++. My problem is about texturing my cubes. The program seems to correctly load textures but it doesn't show the expected result, my cubes looks grey.
I have already tried to change my shaders (like the mix value) but it does not change anything.
Here is my code:
#pragma once
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <thread>
#include <chrono>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "shader.hpp"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "head.h"
/*TODO -- refresh shader every sec*/
class Shader {
public:
Shader(std::string const& nameFragment, std::string const& nameVertex)
: nameFragment_(nameFragment), nameVertex_(nameVertex) {
update();
}
void update(){
if (nameFragment_.empty() || nameVertex_.empty() || (nameFragment_.empty() && nameVertex_.empty())) {
return;
}
bool recreate = false;
std::ifstream stream(nameFragment_);
std::string tmp = std::string(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
stream.close();
if (tmp != fragment_) {
setFragment(tmp);
recreate = true;
}
stream.open(nameVertex_);
tmp = std::string(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
stream.close();
if (tmp != vertex_) {
setVertex(tmp);
recreate = true;
}
if (recreate) {
createFragmentObject();
createVertexObject();
createProgramObject();
deleteUselessShaders();
std::cout << nameFragment_ << " & " << nameVertex_ << " Shaders loaded.\n";
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
void use() {
glUseProgram(programObject_);
}
void setFragmentName(std::string const& name) {
nameFragment_ = name;
}
void setVertexName(std::string const& name) {
nameVertex_ = name;
}
std::string getFragmentName() {
return nameFragment_;
}
std::string getVertexName() {
return nameVertex_;
}
void setFragment(std::string const& fragment) {
fragment_ = fragment;
fs_ptr_ = fragment_.c_str();
}
const GLchar*& getFragment() {
return fs_ptr_;
}
void setVertex(std::string const& vertex) {
vertex_ = vertex;
vs_ptr_ = vertex_.c_str();
}
const GLchar*& getVertex() {
return vs_ptr_;
}
void createVertexObject() {
/*Creating a VS object*/
vertexObject_ = glCreateShader(GL_VERTEX_SHADER);
/*Link the VS code to the VS object*/
glShaderSource(vertexObject_, 1, &vs_ptr_, NULL);
glCompileShader(vertexObject_);
/*Testing the VS compilation*/
int success;
char infoLog[512];
glGetShaderiv(vertexObject_, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexObject_, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
const unsigned int & getVertexObject() {
return vertexObject_;
}
void createFragmentObject() {
/*As the VS, same for FS*/
fragmentObject_ = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentObject_, 1, &fs_ptr_, NULL);
glCompileShader(fragmentObject_);
int success;
char infoLog[512];
glGetShaderiv(fragmentObject_, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentObject_, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
const unsigned int& getFragmentObject() {
return fragmentObject_;
}
void createProgramObject() {
/*Creating the program Shader*/
programObject_ = glCreateProgram();
glAttachShader(programObject_, vertexObject_);
glAttachShader(programObject_, fragmentObject_);
glLinkProgram(programObject_);
int success;
char infoLog[512];
/*Testing PS compilation*/
glGetProgramiv(programObject_, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(programObject_, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
const unsigned int& getProgramObject() {
return programObject_;
}
void deleteUselessShaders() {
/*Deleting shaders already used*/
glDeleteShader(vertexObject_);
glDeleteShader(fragmentObject_);
}
void setBool(const std::string& name, bool value) const
{
glUniform1i(glGetUniformLocation(programObject_, name.c_str()), (int)value);
}
// ------------------------------------------------------------------------
void setInt(const std::string& name, int value) const
{
glUniform1i(glGetUniformLocation(programObject_, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setFloat(const std::string& name, float value) const
{
glUniform1f(glGetUniformLocation(programObject_, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setVec2(const std::string& name, const glm::vec2& value) const
{
glUniform2fv(glGetUniformLocation(programObject_, name.c_str()), 1, &value[0]);
}
void setVec2(const std::string& name, float x, float y) const
{
glUniform2f(glGetUniformLocation(programObject_, name.c_str()), x, y);
}
// ------------------------------------------------------------------------
void setVec3(const std::string& name, const glm::vec3& value) const
{
glUniform3fv(glGetUniformLocation(programObject_, name.c_str()), 1, &value[0]);
}
void setVec3(const std::string& name, float x, float y, float z) const
{
glUniform3f(glGetUniformLocation(programObject_, name.c_str()), x, y, z);
}
// ------------------------------------------------------------------------
void setVec4(const std::string& name, const glm::vec4& value) const
{
glUniform4fv(glGetUniformLocation(programObject_, name.c_str()), 1, &value[0]);
}
void setVec4(const std::string& name, float x, float y, float z, float w) const
{
glUniform4f(glGetUniformLocation(programObject_, name.c_str()), x, y, z, w);
}
// ------------------------------------------------------------------------
void setMat2(const std::string& name, const glm::mat2& mat) const
{
glUniformMatrix2fv(glGetUniformLocation(programObject_, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat3(const std::string& name, const glm::mat3& mat) const
{
glUniformMatrix3fv(glGetUniformLocation(programObject_, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat4(const std::string& name, const glm::mat4& mat) const
{
glUniformMatrix4fv(glGetUniformLocation(programObject_, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
private:
std::string nameFragment_;
std::string nameVertex_;
std::string vertex_;
std::string fragment_;
const GLchar *vs_ptr_;
const GLchar *fs_ptr_;
unsigned int vertexObject_;
unsigned int fragmentObject_;
unsigned int programObject_;
};
/*mises à l’échelle, puis les rotations et enfin les translations*/
/*glm::mat4; mat = glm::mat4(1.0f);*/
#include "head.h"
#define FPS 62
#define WIDTH 800
#define HEIGHT 600
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
int main(){
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //For MacOS
#endif
/*Window initialization*/
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Hello Window!", NULL, NULL);
if (window == NULL){
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
/*GLAD initialization*/
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
// configure global opengl state
// -----------------------------
glEnable(GL_DEPTH_TEST);
/*Initialize shaders*/
Shader myShaders("./Shaders/Hello.fs", "./Shaders/Hello.vs");
/*Vertices*/
float vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
glm::vec3 cubePositions[] = {
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(2.0f, 5.0f, -15.0f),
glm::vec3(-1.5f, -2.2f, -2.5f),
glm::vec3(-3.8f, -2.0f, -12.3f),
glm::vec3(2.4f, -0.4f, -3.5f),
glm::vec3(-1.7f, 3.0f, -7.5f),
glm::vec3(1.3f, -2.0f, -2.5f),
glm::vec3(1.5f, 2.0f, -2.5f),
glm::vec3(1.5f, 0.2f, -1.5f),
glm::vec3(-1.3f, 1.0f, -1.5f)
};
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// texture coord attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// load and create a texture
// -------------------------
unsigned int texture1, texture2;
// texture 1
// ---------
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
// set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// load image, create texture and generate mipmaps
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
// The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path.
unsigned char* data = stbi_load(("./Textures/container.jpg"), &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);
// texture 2
// ---------
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
// set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// load image, create texture and generate mipmaps
data = stbi_load("./Textures/awesomeface.png", &width, &height, &nrChannels, 0);
if (data)
{
// note that the awesomeface.png has transparency and thus an alpha channel, so make sure to tell OpenGL the data type is of GL_RGBA
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
myShaders.use();
myShaders.setInt("texture1", 0);
myShaders.setInt("texture2", 1);
/*To get a wireframe style*/
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
/*Render Loop*/
double lasttime = glfwGetTime();
while (!glfwWindowShouldClose(window)){
glfwSwapBuffers(window);
while (glfwGetTime() < lasttime + 1.0 / FPS) {
processInput(window);
glClearColor(0.2f, 0.7f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // also clear the depth buffer now!
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
/*Activating our shader*/
myShaders.use();
// create transformations
glm::mat4 view = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
glm::mat4 projection = glm::mat4(1.0f);
projection = glm::perspective(glm::radians(45.0f), (float)WIDTH / (float)HEIGHT, 0.1f, 100.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
// pass transformation matrices to the shader
myShaders.setMat4("projection", projection); // note: currently we set the projection matrix each frame, but since the projection matrix rarely changes it's often best practice to set it outside the main loop only once.
myShaders.setMat4("view", view);
// render boxes
glBindVertexArray(VAO);
for (unsigned int i = 0; i < 10; i++)
{
// calculate the model matrix for each object and pass it to shader before drawing
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, cubePositions[i]);
float angle = 20.0f * i;
model = glm::rotate(model, glm::radians((float)angle), glm::vec3(1.0f, 0.3f, 0.5f));
myShaders.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
glfwPollEvents();
}
lasttime += 1.0 / FPS;
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
/*Resize*/
void framebuffer_size_callback(GLFWwindow* window, int width, int height){
glViewport(0, 0, width, height);
}
/*Handle inputs*/
void processInput(GLFWwindow* window){
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
#version 330 core
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D texture1;
uniform sampler2D texture2;
void main()
{
FragColor = mix(texture(texture1,TexCoord),texture(texture2,TexCoord),0.2f);
}
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor; // la variable aColor a l'attribut de position 1
layout (location = 2) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
TexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y);
}
Look at:
// texture coord attribute glVertexAttribPointer(1, [...] );
vs. your shader:
layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aColor; // la variable aColor a l'attribut de position 1 layout (location = 2) in vec2 aTexCoord;
So, you actually tell the GL to use your texture coordinates as the aColor
attribute. And since you do not enable an array for attribute location 2 ( aTexCoord
) at all, all vertices will see the same texture coordinate value, hence the texture sampling will return the same color from the texture everywhere...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.