OpenGL imports texture as single color [closed]

1 week ago 9
ARTICLE AD BOX

I have a simple OpenGL program that draws a cube in the center of the screen. I also added some functions to give the cube a texture:

Shaders.h

#ifndef SHADER_H #define SHADER_H #include <glad/glad.h> #include <string> #include <fstream> #include <sstream> #include <iostream> class Shader { public: unsigned int ID; // constructor generates the shader on the fly // ------------------------------------------------------------------------ Shader(const char* vertexPath, const char* fragmentPath) { printf("%s", vertexPath); // 1. retrieve the vertex/fragment source code from filePath std::string vertexCode; std::string fragmentCode; std::ifstream vShaderFile; std::ifstream fShaderFile; // ensure ifstream objects can throw exceptions: vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { // open files vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath); std::stringstream vShaderStream, fShaderStream; // read file's buffer contents into streams vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); // close file handlers vShaderFile.close(); fShaderFile.close(); // convert stream into string vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch (std::ifstream::failure& e) { std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl; } const char* vShaderCode = vertexCode.c_str(); const char* fShaderCode = fragmentCode.c_str(); // 2. compile shaders unsigned int vertex, fragment; // vertex shader vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vShaderCode, NULL); glCompileShader(vertex); checkCompileErrors(vertex, "VERTEX"); // fragment Shader fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fShaderCode, NULL); glCompileShader(fragment); checkCompileErrors(fragment, "FRAGMENT"); // shader Program ID = glCreateProgram(); glAttachShader(ID, vertex); glAttachShader(ID, fragment); glLinkProgram(ID); checkCompileErrors(ID, "PROGRAM"); // delete the shaders as they're linked into our program now and no longer necessary glDeleteShader(vertex); glDeleteShader(fragment); } // activate the shader // ------------------------------------------------------------------------ void use() { glUseProgram(ID); } // utility uniform functions // ------------------------------------------------------------------------ void setBool(const std::string& name, bool value) const { glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value); } // ------------------------------------------------------------------------ void setInt(const std::string& name, int value) const { glUniform1i(glGetUniformLocation(ID, name.c_str()), value); } // ------------------------------------------------------------------------ void setFloat(const std::string& name, float value) const { glUniform1f(glGetUniformLocation(ID, name.c_str()), value); } private: // utility function for checking shader compilation/linking errors. // ------------------------------------------------------------------------ void checkCompileErrors(unsigned int shader, std::string type) { int success; char infoLog[1024]; if (type != "PROGRAM") { glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(shader, 1024, NULL, infoLog); std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; } } else { glGetProgramiv(shader, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shader, 1024, NULL, infoLog); std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; } } } }; #endif

macros.h

#pragma once #include <glad/glad.h> #include <GLFW/glfw3.h> #define STB_IMAGE_IMPLEMENTATION #include <stb_image_h/stb_image.h> #include <stdio.h> #include <stdlib.h> #include <string> #include <iostream> #include <windows.h> #include <cstdlib> #include "shaders.h" #define SCR_WIDTH 1920 #define SCR_HEIGHT 1080 #define p(x) printf("%s\n", x) #define error -1 #define true 0 #define false 1 int texAmount = 0;

functions.h

#pragma once #include "macros.h" void framebuffer_size_callback(GLFWwindow* window, int width, int height); void processInput(GLFWwindow* window); int generateTexture(char* location); int random(int max); //Controls window resizes with GLFW void framebuffer_size_callback(GLFWwindow* window, int width, int height){ glViewport(0, 0, width, height); } //Gets all inputs void processInput(GLFWwindow* window){ if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) p("hi"); } int generateTexture(const char* location){ unsigned int texture; glGenTextures(1, &texture); glActiveTexture(GL_TEXTURE0 + texAmount); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); int width, height, nrChannels, r; unsigned char *data = stbi_load(location, &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); r=texture; } else{ std::cout << "Failed to load" << location << " texture" << std::endl; r=error; } stbi_image_free(data); texAmount++; return r; } //Gives random number int random(int max) { return rand() % max + 1; }

main.cpp

#include "functions.h" int main(){ p("Starting app..."); //Initialize Window p("Initializing Window..."); glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); #ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); #endif //Create window p("Creating Window..."); GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Show Must Go On", glfwGetPrimaryMonitor(), NULL); //If window creation fails if (window == NULL){ std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } //Make the context in Window the main context in the thread glfwMakeContextCurrent(window); //Sets callbacks to functions (like when window looses/gains focus, the window_focus_callback will run thanks to this) p("Setting callbacks..."); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); //Initialize GLAD p("Initializing GLAD..."); if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){ std::cout << "Failed to initialize GLAD" << std::endl; return -1; } p("Initializing VertexShader and FragmentShader..."); Shader ourShader("shader.vs", "shader.fs"); float vertices[] = { 0.25f, 0.45f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, // top right 0.25f, -0.45f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, // bottom right -0.25f, -0.45f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left -0.25f, 0.45f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f // top left }; unsigned int indices[] = { 0, 1, 3, // first triangle 1, 2, 3 // second triangle }; p("Setting up VBO and VAO and EBO..."); unsigned int VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // color attribute glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); // texture coord attribute glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); glEnableVertexAttribArray(2); //set image defaults int tex1 = generateTexture("asset/dirt.png"); //Render Loop p("Starting Render loop..."); //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //wireframe mode while (!glfwWindowShouldClose(window)){ //Process Input of the Window processInput(window); //Render glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); //Bind texture glBindTexture(GL_TEXTURE_2D, tex1); ourShader.use(); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // Key and Mouse events glfwSwapBuffers(window); glfwPollEvents(); } glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glfwTerminate(); //Finish Window Proccess return 0; }

Shader.vs

#version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec2 aTexCoord; out vec2 TexCoord; void main() { gl_Position = vec4(aPos, 1.0); TexCoord = aTexCoord; }

Shader.fs

#version 330 core in vec2 TexCoord; out vec4 FragColor; uniform sampler2D tex1; void main() { FragColor = texture(tex1, TexCoord); }

dirt.png:

enter image description here

However, it only takes one color from the texture.

Importing of the texture works, i have tried this with a blank white texture and got... well, a blank white square.

Read Entire Article