This is not a duplicate. Old posts that i have found DO NOT work on helping.
Here, 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. 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.
Here is the texture i am talking about.
Here are all the codes:
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);
}
Shaders.h
#ifndef SHADER_H
#define SHADER_H
#include
#include
#include
#include
#include
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
#include
#define STB_IMAGE_IMPLEMENTATION
#include
#include
#include
#include
#include
#include
#include
#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;
}
What have i tried: Nothing. I don't really care anymore. You know how much i wasted to get some opengl working on my computer? More than a whole year, 3 different computers, tear, blood and sweat. Only to be able to draw an useless square on a window. I miss JavaScript. Way easier to setup and less the hustle.