两张图片渐变交替
想要实现两张图片的渐变交替,需要用到以时间为参数的sin函数来实现,此处的实现方式为sin(timeValue),可以让image1和image2渐变交替。
main.cpp
#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "Shader.h"
#include "SOIL2/SOIL2.h"
#include "SOIL2/stb_image.h"
const GLint WIDTH = 800, HEIGHT = 600;
GLFWwindow* window;
int init()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
if (nullptr == window)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if (GLEW_OK != glewInit())
{
std::cout << "Failed to initialise GLEW" << std::endl;
return -1;
}
glViewport(0, 0, screenWidth, screenHeight);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC0_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
int main()
{
init();
Shader shader = Shader("res/shaders/core1.vs", "res/shaders/core1.frag");
float vertices[] = {
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f
};
unsigned int indices[] =
{
0,1,3,
1,2,3
};
GLuint VAO, VBO;
GLuint EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(2);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
GLuint texture1;
int width, height;
unsigned char* image1 = SOIL_load_image("res/images/image1.jpg", &width, &height, 0, SOIL_LOAD_RGBA);
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image1);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image1);
glBindTexture(GL_TEXTURE_2D, 0);
unsigned char* image2 = SOIL_load_image("res/images/image2.jpg", &width, &height, 0, SOIL_LOAD_RGBA);
GLuint texture2;
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image2);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image2);
glBindTexture(GL_TEXTURE_2D, 0);
shader.Use();
glUniform1i(glGetUniformLocation(shader.Program, "ourTexture0"), 0);
glUniform1i(glGetUniformLocation(shader.Program, "ourTexture1"), 1);
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
shader.Use();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
float timeValue = glfwGetTime();
float TimeValue = sin(timeValue) + 1.0f;
int vertexCorlorLocation = glGetUniformLocation(shader.Program, "mixt");
glUniform1f(vertexCorlorLocation, TimeValue);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glDeleteTextures(1, &texture1);
glDeleteTextures(1, &texture2);
glfwTerminate();
return 0;
}
Shader.h
#pragma once
#include<string>
#include<fstream>
#include<sstream>
#include<iostream>
#include<GL/glew.h>
class Shader {
GLuint vertex, fragment;
public:
GLuint Program;
Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
{
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
vShaderFile.exceptions(std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::badbit);
try {
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
vShaderFile.close();
fShaderFile.close();
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
}
catch (std::ifstream::failure a) {
std::cout <<
"ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ"
<< std::endl;
}
const GLchar* vShaderCode = vertexCode.c_str();
const GLchar* fShaderCode = fragmentCode.c_str();
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
GLint success;
GLchar infoLog[512];
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
std::cout <<
"ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
<< infoLog << std::endl;
}
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
std::cout <<
"ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"
<< infoLog << std::endl;
}
this->Program = glCreateProgram();
glAttachShader(this->Program, vertex);
glAttachShader(this->Program, fragment);
glLinkProgram(this->Program);
glValidateProgram(this->Program);
glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
std::cout <<
"ERROR::SHADER::PROGRAM::LINKING_FAILED\n" <<
infoLog << std::endl;
}
}
~Shader() {
glDetachShader(this->Program, vertex);
glDetachShader(this->Program, fragment);
glDeleteShader(vertex);
glDeleteShader(fragment);
glDeleteProgram(this->Program);
}
void Use() {
glUseProgram(this->Program);
}
};
core1.vs
#version 330 core
layout(location = 0) in vec3 position;
layout(location = 2) in vec2 texCoords;
layout(location = 1) in vec3 color;
out vec2 TexCoords;
out vec3 ourColor;
void main(){
gl_Position = vec4(position, 1.0f);
TexCoords = vec2(texCoords.x, 1.0f-texCoords.y);
ourColor = color;
}
core1.frag
#version 330 core
in vec2 TexCoords;
in vec3 ourColor;
out vec4 color;
uniform sampler2D ourTexture0;
uniform sampler2D ourTexture1;
uniform float mixt;
void main(){
color= mix(texture(ourTexture0, TexCoords), texture(ourTexture1, TexCoords),mixt);
//color = texture(ourTexture0, TexCoords) * vec4(ourColor, 1.0);
}