环绕方式
|
描述
|
GL_REPEAT
|
对纹理的默认行为。重复纹理图像。
|
GL_MIRRORED_REPEAT
|
和 GL_REPEAT 一样,但每次重复图片是镜像放置的。
|
GL_CLAMP_TO_EDGE
|
纹理坐标会被约束在0到1之间,超出的部分会重复纹理坐标的边缘,产生一种边缘被拉伸的效果。
|
GL_CLAMP_TO_BORDER
|
超出的坐标为用户指定的边缘颜色。
|
过滤方式
|
描述
|
GL_NEAREST_MIPMAP_NEAREST
|
使用最邻近的多级渐远纹理来匹配像素大小,并使用邻近插值进行纹理采样
|
GL_LINEAR_MIPMAP_NEAREST
|
使用最邻近的多级渐远纹理级别,并使用线性插值进行采样
|
GL_NEAREST_MIPMAP_LINEAR
|
在两个最匹配像素大小的多级渐远纹理之间进行线性插值,使用邻近插值进行采样
|
GL_LINEAR_MIPMAP_LINEAR
|
在两个邻近的多级渐远纹理之间使用线性插值,并使用线性插值进行采样
|
/纹理/
//如果窗口大小改变 回调函数
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void loadImage(unsigned int VAO);
void processInput(GLFWwindow* window, Shader ourShader);
float mixnum = 0.2f;
int main()
{
glfwInit();//初始化 glfw
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//确定使用的版本号 major minor
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//确定使用的核心模式 core-profile
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT); MAC平台使用的版本号
stbi_set_flip_vertically_on_load(true);//颠倒Y 轴
GLFWwindow* window = glfwCreateWindow(800, 600, "learnOpenGL", NULL, NULL);//生成一个窗口对象
if (window == NULL)
{
std::cout << "Failed to create GLFW windows" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);//设置当前主窗口对象
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))//初始化 GLAD
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
//glViewport(1,1,10,10);//告诉opengl 窗口的位置和大小 前俩参数是左下角 位置 后俩就是窗口宽高
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//注册窗口大小改变回调事件
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 // 左上
-0.5f,-0.5f,0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // 左下
-0.5f,0.5f,0.0f, 0.0f, 1.0f, 0.0f, 0.0f,1.0f, // 顶部
0.5f,-0.5f,0.0f, 0.0f, 0.0f, 1.0f, 1.0f,0.0f, // 右下
0.5f,-0.5f,0.0f, 1.0f, 0.0f, 0.0f, 1.0f,0.0f, // 左下
-0.5f,0.5f,0.0f,0.0f, 1.0f, 0.0f, 0.0f,1.0f, // 顶部
0.5f,0.5f,0.0f, 0.0f, 0.0f, 1.0f, 1.0f,1.0f // 右下
};
float texCoords[] = {
0.0f,0.0f,//左下角
1.0f,0.0f,//右下角
0.5f,1.0f//上中
};
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);//申请一个顶点缓冲区
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);//把顶点缓冲区绑定到 array_buffer 缓冲区上
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//把顶点数据复制到内存上
int nrAttributes;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);
std::cout << "Maximum nr of vertex attirbutes supported : " << nrAttributes << std::endl;
Shader ourShader("C:/Users/Hoolai/source/repos/OpenGl_1/OpenGl_1/shaders/vs.glsl", "C:/Users/Hoolai/source/repos/OpenGl_1/OpenGl_1/shaders/fs.glsl");
//告诉opengl 该如何解析顶点数据
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//告诉opengl 该如何解析顶点数据
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);
//loadImage(VAO);
unsigned int texture1, texture2;
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int width, height, nrChannels;
unsigned char *data = stbi_load("C:/Users/Hoolai/source/repos/OpenGl_1/OpenGl_1/images/container.jpg", &width, &height, &nrChannels, 0);
if (data)
{
/*参数1 渲染的目标鸟类型
参数2 mipmap等级 0就是基础等级
参数3 纹理的存储格式 RGB
参数4 5 就是纹理的高度和宽度
参数6 0 不要问为什么 就是这么任性
参数7 原图的格式和数据类型, 储存到 char byte数组内 传入对应值
参数8 图像数据传入*/
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
//使用完数据 释放下数据
stbi_image_free(data);
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
// 为当前绑定的纹理对象设置环绕、过滤方式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_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);
data = stbi_load("C:/Users/Hoolai/source/repos/OpenGl_1/OpenGl_1/images/awesomeface.png", &width, &height, &nrChannels, 0);
if (data)
{
/*参数1 渲染的目标鸟类型
参数2 mipmap等级 0就是基础等级
参数3 纹理的存储格式 RGB
参数4 5 就是纹理的高度和宽度
参数6 0 不要问为什么 就是这么任性
参数7 原图的格式和数据类型, 储存到 char byte数组内 传入对应值
参数8 图像数据传入*/
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
//使用完数据 释放下数据
stbi_image_free(data);
// render container
ourShader.use();
ourShader.setInt("texture1", 0);
//glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0);
// or set it via the texture class
ourShader.setInt("texture2", 1);
ourShader.setInt("mixnum", mixnum);
//做一个渲染循环,保证程序不直接退出 Renderer Loop
while (!glfwWindowShouldClose(window))//每次循环检查下 GLFW是否需求要推出 返回True就会跳出循环 程序结束
{
processInput(window, ourShader);//每次循环检查下输入
glClear(GL_COLOR_BUFFER_BIT);
//ourShader.use();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
//ourShader.use();
glBindVertexArray(VAO);
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
//glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0,6);//使用顶点数组渲染 第一个是渲染图形,第二 三个参数是 数组索引 开始和结束值
glfwSwapBuffers(window);//GLFW的渲染函数 储存窗口的每个像素 输出到屏幕上
glfwPollEvents();//检查函数有没有触发什么事件 键盘输入 鼠标点击等
}
glfwTerminate();//如果退出程序 清理下glfw的资源
return 0;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);//感觉没有生效
}
bool up = false;
bool down = false;
void processInput(GLFWwindow *window, Shader ourShader)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)//是否按下 ESC建
{
glfwSetWindowShouldClose(window, true);//执行关闭窗口
}
if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS)
{
ourShader.setFloat("offset", 0.5f);
}
if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS)
{
ourShader.setFloat("offset", 0.0f);
/* glClearColor(0.4f, 0.6f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);*/
}
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
{
up = true;
}
if (up&&glfwGetKey(window, GLFW_KEY_UP) == GLFW_RELEASE)
{
up = false;
mixnum = mixnum + 0.1f;
if (mixnum > 1.0f)
{
mixnum = 1.0f;
}
ourShader.setFloat("mixnum", mixnum);
std::cout << "aaaaa " << mixnum << std::endl;
}
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
{
down = true;
}
if (down&&glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_RELEASE)
{
down = false;
mixnum = mixnum - 0.1f;
if (mixnum < 0.0f)
{
mixnum = 0.0f;
}
ourShader.setFloat("mixnum", mixnum);
std::cout << "bbbbb " << mixnum << std::endl;
/* glClearColor(0.4f, 0.6f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);*/
}