I have been going through the learnopengl tutorials recently and was on the texture tutorial. I was going through it and everything was working up until the mix() function was called in the fragment shader. For some reason, I can display both textures separately using texture() and just changing the sampler I use for it (so I know they both work), but can't get them to mix (I get a black screen).
Also, I wanted to rename the ourTexture sampler to something better, but whenever I rename it I get a black screen. I rename it both in the fragment shader and when I call the glGetUniformLocation() function, but for some reason nothing is working. No matter what I do, the texture only shows up if is call the sampler "ourTexture"
Here is the code:
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define SCREEN_WIDTH 1080
#define SCREEN_HEIGHT 1080
const char* vertexShaderSource = "#version 330 core\n"
"layout(location = 0) in vec4 positions;\n"
"layout(location = 1) in vec3 a_Colors;\n"
"layout(location = 2) in vec2 tex_Coords;\n"
"out vec4 colors;\n"
"out vec2 texCoords;\n"
"void main()\n"
"{\n"
" gl_Position = positions;\n"
" colors = vec4(a_Colors, 1.0);\n"
" texCoords = tex_Coords;\n"
"}\n";
const char* fragmentShaderSource = "#version 330 core\n"
"in vec4 colors;\n"
"in vec2 texCoords;\n"
"out vec4 Frag_Color;\n"
"uniform sampler2D ourTexture;\n"
"uniform sampler2D smileyTexture;\n"
"void main()\n"
"{\n"
" Frag_Color = texture(ourTexture, texCoords);\n" //Mix doesn't work for some reason
"}\n";
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
GLFWwindow* window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Multi-Color Square", NULL, NULL);
if(window == NULL)
{
std::cout << "Failed to create window!" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
int version = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
if(version == 0)
{
std::cout << "Failed to load glad!" << std::endl;
glfwTerminate();
return -1;
}
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
unsigned int program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glUseProgram(program);
//Texture loading
int width, height, nrChannels;
unsigned char* data = stbi_load("container.jpeg", &width, &height, &nrChannels, 0);
unsigned int texture;
glGenTextures(1, &texture); //Generates the texture id
glBindTexture(GL_TEXTURE_2D, texture); //Binds the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); //Sets the texture data
glGenerateMipmap(GL_TEXTURE_2D); //Generate a mipmap for the currently bound 2d texture
stbi_image_free(data);
stbi_set_flip_vertically_on_load(true);
data = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);
unsigned int smileyTexture;
glGenTextures(1, &smileyTexture);
glBindTexture(GL_TEXTURE_2D, smileyTexture);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(data);
glBindTexture(GL_TEXTURE_2D, 0);
float verticies[] = {
//Coords //Colors //Textures
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f
};
unsigned int indicies[] = {
0, 1, 2,
0, 2, 3
};
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW);
unsigned int vertexPointer;
glGenVertexArrays(1, &vertexPointer);
glBindVertexArray(vertexPointer);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)0); //Positions
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(2 * sizeof(float))); //Colors
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(5 * sizeof(float)));
glEnableVertexAttribArray(2);
unsigned int indexBuffer;
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies), indicies, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glUniform1i(glGetUniformLocation(program, "ourTexture"), 0);
glUniform1i(glGetUniformLocation(program, "smileyTexture"), 1);
while(!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, smileyTexture);
glBindVertexArray(vertexPointer);
glUseProgram(program);
glDrawElements(GL_TRIANGLES, sizeof(indicies) / sizeof(unsigned int), GL_UNSIGNED_INT, NULL);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteBuffers(1, &buffer);
glDeleteBuffers(1, &indexBuffer);
glDeleteVertexArrays(1, &vertexPointer);
glfwTerminate();
return 0;
}
Edit: I call mix like mix(texture(ourTexture, texCoords), texture(smileyTexture, texCoords), 0.2);
However I've also tried mix(texture(ourTexture, texCoords), texture(smileyTexture, texCoords), texture(smileyTexture, texCoords).a * 0.2);
as was suggested in the comments on learnopengl but it still doesn't work
CodePudding user response:
ourTexture
has 3 color channels (RGB). smileyTexture
has 4 color channels (RGBA). You have to mix the RGB channels of the textures depending on the alpha channel of smileyTexture
:
vec4 color = texture(ourTexture, texCoords);
vec4 smileyColor = texture(smileyTexture, texCoords);
Frag_Color = vec4(mix(color.rgb, smileyColor.rgb, smileyColor.a), 1.0);