#include <iostream>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "Shader.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <functional>
float vertices[] = {
// ---- 位置 ---- ---- 颜色 ---- - 纹理坐标 -
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // 右上
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 右下
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // 左下
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // 左上
};
unsigned int indices[] = {
// 注意索引从0开始!
// 此例的索引(0,1,2,3)就是顶点数组vertices的下标,
// 这样可以由下标代表顶点组合成矩形
0, 1, 2, // 第一个三角形
0, 2, 3 // 第二个三角形
};
float texCoords[] = {
0.0f, 0.0f, // 左下角
1.0f, 0.0f, // 右下角
0.5f, 1.0f // 上中
};
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
//键盘事件处理器
void processInput(GLFWwindow* window);
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
}
int main(int argc, char* argv[])
{
glfwInit();///初始化glfw
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);///配置glfw,指定主版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);///配置glfw,指定次版本号
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);///指定glfw使用核心模式
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);///参数列表:窗口宽、窗口高、窗口名称、...
if (window == nullptr)
{
std::cout << "failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);///通知GLFW将我们窗口的上下文设置为当前线程的主上下文
glewExperimental = GL_TRUE;///使用glew前一定要调用初始化
if (glewInit() != GLEW_OK)
{
std::cout << "init glew failed.\n";
return -1;
}
glViewport(0, 0, 800, 600);///设置opengl渲染窗口开始位置(相对于程序窗口)和大小
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);///窗口大小变化时触发回调,更新渲染窗口的大小
unsigned int VAO;
glGenVertexArrays(1, &VAO);
unsigned int VBO;
glGenBuffers(1, &VBO);///生成缓冲对象VBO
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);///绑定为顶点缓冲对象
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);///把定义的顶点数据读取到内存中(参数:1.绑定为顶点缓冲,2.数据大小,3.实际数据,4.使用类型)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);///启用顶点属性;顶点属性默认是禁用的
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);///启用顶点属性;顶点属性默认是禁用的
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);///启用顶点属性;顶点属性默认是禁用的
unsigned int EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
int c_width, c_height, c_nrChannels;
stbi_set_flip_vertically_on_load(true);
unsigned char* c_data = stbi_load("container.jpg", &c_width, &c_height, &c_nrChannels, 0);// 获取图片信息
unsigned int c_texture;
glGenTextures(1, &c_texture);// 生成纹理对象
glBindTexture(GL_TEXTURE_2D, c_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_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (c_data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, c_width, c_height, 0, GL_RGB, GL_UNSIGNED_BYTE, c_data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "failed to load texture" << std::endl;
}
stbi_image_free(c_data);// 释放图片资源
int t_width, t_height, t_nrChannels;
unsigned char* t_data = stbi_load("texture.png", &t_width, &t_height, &t_nrChannels, 0);// 获取图片信息
unsigned int t_texture;
glGenTextures(1, &t_texture);
glBindTexture(GL_TEXTURE_2D, t_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_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (t_data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, t_width, t_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, t_data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "failed to load texture" << std::endl;
}
stbi_image_free(t_data);// 释放图片资源
Shader our_shader((char*)("v_shader.txt"), (char*)("f_shader.txt"));
our_shader.use(); // 不要忘记在设置uniform变量之前激活着色器程序!
glUniform1i(glGetUniformLocation(our_shader.ID, "texture1"), 0); // 手动设置
our_shader.set_value("texture2", (int)1); // 或者使用着色器类设置
float mix_value = 0.0f;
while (!glfwWindowShouldClose(window))///只要opengl渲染窗口不主动关闭程序会一直进行
{
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);///设置清空屏幕所用的颜色,状态设置函数
glClear(GL_COLOR_BUFFER_BIT);///清空屏幕的颜色缓冲,状态使用函数
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);///设置渲染模式,前后都渲染、线模式
glActiveTexture(GL_TEXTURE0);// 在绑定纹理之前先激活纹理单元
glBindTexture(GL_TEXTURE_2D, c_texture);
glActiveTexture(GL_TEXTURE1);// 在绑定纹理之前先激活纹理单元
glBindTexture(GL_TEXTURE_2D, t_texture);
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
{
mix_value += 0.01f;
if (mix_value > 1.0f)
{
mix_value = 1.0f;
}
}
else if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
{
mix_value -= 0.01f;
if (mix_value < 0.0f)
{
mix_value = 0.0f;
}
}
our_shader.use();
our_shader.set_value("transparency", mix_value);
our_shader.use();
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);///交换颜色缓冲
glfwPollEvents();///检查有没有事件触发,相应对应的事件
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glDeleteTextures(1, &c_texture);
glDeleteTextures(1, &t_texture);
glfwTerminate();///释放分配的渲染资源
return 0;
}
opengl渐变纹理
最新推荐文章于 2024-05-04 17:13:11 发布