I am currently experiencing an issue with rendering multiple textures at once with OpenGL 3.3 Core. I load 2 separate images through SOIL ( an image loading library ) but only one of the images appears in the final program. This is my current code:
#include <iostream>
#include <GL\glew.h>
#include <GL\GL.h>
#include <GLFW\glfw3.h>
#include <SOIL.h>
#include "Shader.h"
#include "texture2D.h"
using namespace std;
void processInput(GLFWwindow *window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
if (window == NULL) {
cout << "GLFW WINDOW CREATION FAILED! " << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
cout << "Made By Rial Seebran " << endl;
cout << glfwGetVersionString() << endl;
glewInit();
if (glewInit() != GLEW_OK) {
cout << "GLEW INITIALIZATION FAILED! " << endl;
glfwTerminate();
return -1;
}
float positions[] = {
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f
};
unsigned int indices[] = {
0, 1, 2,
3, 2, 1
};
unsigned int VAO;
unsigned int VBO;
unsigned int EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, ((GLvoid*)(0)));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, ((GLvoid*)(sizeof(float) * 3)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Shader shader("shader.vs", "shader.fs");
Texture2D texture1;
texture1.LoadTexture("container.jpg");
Texture2D texture2;
texture2.LoadTexture("awesomeface.png");
shader.Use();
while (!glfwWindowShouldClose(window)) {
glClearColor(0.1f, 0.15f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
texture1.BindTexture(0);
texture2.BindTexture(1);
shader.Uniform1I("myTexture1", 0);
shader.Uniform1I("myTexture2", 1);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
processInput(window);
glfwPollEvents();
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glfwTerminate();
return 0;
}
And this is the texture class (all in a .h file):
#ifndef TEXTURE2D
#define TEXTURE2D
#include <GL\glew.h>
#include <GL\GL.h>
#include <SOIL.h>
#include <iostream>
using namespace std;
class Texture2D {
public:
Texture2D();
~Texture2D();
void LoadTexture(const char* texPath);
void BindTexture(unsigned int texUnit);
unsigned int texture_M;
};
Texture2D::Texture2D() {
}
Texture2D::~Texture2D() {
glDeleteTextures(1, &texture_M);
}
void Texture2D::LoadTexture(const char* texPath) {
int width;
int height;
unsigned char *image = SOIL_load_image(texPath, &width, &height, 0, SOIL_LOAD_RGBA);
if (image == NULL) {
cout << "Failed to load Image! " << endl;
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, texture_M);
if (image != NULL) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
}
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0);
}
void Texture2D::BindTexture(unsigned int texUnit) {
glActiveTexture(GL_TEXTURE0 + texUnit);
glBindTexture(GL_TEXTURE_2D, texture_M);
}
#endif
In the fragment shader, I use the mix()
function which linearly interpolates the 2 textures, yet the "awesomeface.png" image is the only texture which shows up in the final program. What should be fixed, for the program to display both textures?
I did not call glGenTextures()
in the texture2D class. Thanks to stackOverflow user @Rabbid76 for pointing that out