文章是照着教程点击打开链接  写的第二部分纹理,实现两个纹理的混合,纹理单元的使用。加载图片时候使用的FreeImage 这是个开源的加载照片的

源代码点击打开链接  选择里面shader2文件夹,按照要求选择shader.h头文件和 texture1.cpp

头文件shader.h

#ifndef SHADER_H
#define SHADER_H
#include<string>
#include<fstream>
#include<sstream>
#include<iostream>
#include<GL/glew.h>
using namespace std;
class Shader
{
public://程序的IDGLuint Program;//读取渲染程序并创建ShaderShader(const GLchar * vertexSourcePath,const GLchar *fragmentSource);{//1.从文件路径获得vertex/fragment源码string vertexCode;string fragmentCode;try{//打开文件Open filesifstream vShaderFile(vertexPath);ifstream fShaderFile(fragmentPath);stringstream vShaderStream,fShaderStream;//读取文件缓冲到流、vShaderStream<<vShaderFile.rdbuf();fShaderStream<<fShaderFile.rdbuf();//关闭文件句柄vShaderFile.close();fShaderFile.close();//将流转为GLchar数组vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); }catch(std::exception e) { std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;  }const GLchar* vShaderCode = vertexCode.c_str();const GLchar * fShaderCode = fragmentCode.c_str();// 2.编译着色器GLuint vertex, fragment;GLint success;GLchar infoLog[512];// 顶点着色器vertex = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertex, 1, &vShaderCode, NULL);glCompileShader(vertex);// 打印着色器是否错误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);// 打印是否有错误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;}// 删除着色器程序glDeleteShader(vertex);glDeleteShader(fragment);}//使用Programvoid Use();{
glUseProgram(this->Program);}
}
#endif

texture1.cpp

//纹理单元的使用
#include<iostream>
//GLEW
#define GLEW_STATIC
#include <GL/glew.h>// GLFW
#include <GLFW/glfw3.h>
#pragma comment(lib,"FreeImage.lib")
// Other Libs
#include<FreeImage.h>
#include<Shader.h>
using namespace std;// 函数原型
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);// Window 尺寸
const GLuint WIDTH = 800, HEIGHT = 600;// The MAIN function, from here we start the application and run the game loop
int main()
{// 初始化GLFWglfwInit();
FreeImage_Initialise(TRUE);//初始化FreeImage// Set all the required options for GLFW  设置全部要求的GLFW选项glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);// Create a GLFWwindow object that we can use for GLFW's functions 创建窗口GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);glfwMakeContextCurrent(window);// Set the required callback functions 设置回调函数glfwSetKeyCallback(window, key_callback);// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions 恢复函数指针和扩展glewExperimental = GL_TRUE;// Initialize GLEW to setup the OpenGL Function pointers  初始化GLEWglewInit();// Define the viewport dimensions 定义视图的尺寸glViewport(0, 0, WIDTH, HEIGHT);// Build and compile our shader program  建立和编译我们的渲染程序Shader ourShader("D:/C语言/openglflew/shader2/shader.vs", "D:/C语言/openglflew/shader2/shader.frag");// Set up vertex data (and buffer(s)) and attribute pointers 设置顶点数据和属性指针GLfloat vertices[] = {// Positions  位置        // Colors   颜色        // Texture Coords 纹理坐标0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // Top Right 上右0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // Bottom Right底右-0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // Bottom Left底左-0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // Top Left 左上};GLuint indices[] = {  // Note that we start from 0! 备注:我们从0开始0, 1, 3, // First Triangle 第一个三角形1, 2, 3  // Second Triangle   第二个三角形};//创建VAO VBO EBO,GLuint VBO, VAO, EBO;glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO);glGenBuffers(1, &EBO);//绑定glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);// Position attribute  顶点属性glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(0);// Color attribute  颜色属性glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));glEnableVertexAttribArray(1);// TexCoord attribute  纹理坐标属性glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));glEnableVertexAttribArray(2);glBindVertexArray(0); // Unbind VAO 解绑VAO// Load, create texture and generate mipmaps 加载,创建纹理并且形成译码//image formatFREE_IMAGE_FORMAT fif = FIF_UNKNOWN;FREE_IMAGE_FORMAT fifmt;int width, height;FIBITMAP *dib(0);//1 获取图片格式fifmt = FreeImage_GetFileType("D:/C语言/openglflew/wall.png", 0);//2 加载图片if(FreeImage_FIFSupportsReading(fifmt))dib = FreeImage_Load(fifmt, "D:/C语言/openglflew/wall.png",0);printf("bit: %d\n", FreeImage_GetBPP(dib));//灰度printf("type: %d\n",FreeImage_GetImageType(dib));//返回类型printf("bit: %d\n",FreeImage_GetColorsUsed(dib));//调色板的大小printf("bit: %d\n",FreeImage_GetDIBSize(dib));//大小//if the image failed to load, return failureif(!dib)cout<<55<<endl;
//3 转化为rgb 24色
dib = FreeImage_ConvertTo24Bits(dib);//4 获取数据指针
BYTE *pixels = (BYTE*)FreeImage_GetBits(dib);width = FreeImage_GetWidth(dib);height = FreeImage_GetHeight(dib);cout<<"width:"<<width<<endl;cout<<"height:"<<height<<endl;///----------------------------------------加载第二个纹理图片----FREE_IMAGE_FORMAT fif1 = FIF_UNKNOWN;FREE_IMAGE_FORMAT fifmt1;int width1, height1;FIBITMAP *dib1(0);//1 获取图片格式fifmt1 = FreeImage_GetFileType("D:/C语言/openglflew/face.png", 0);//2 加载图片if(FreeImage_FIFSupportsReading(fifmt1))dib1 = FreeImage_Load(fifmt1, "D:/C语言/openglflew/face.png",0);printf("bit: %d\n", FreeImage_GetBPP(dib1));//灰度printf("type: %d\n",FreeImage_GetImageType(dib1));//返回类型printf("bit: %d\n",FreeImage_GetColorsUsed(dib1));//调色板的大小printf("bit: %d\n",FreeImage_GetDIBSize(dib1));//大小//if the image failed to load, return failureif(!dib1)cout<<55<<endl;
//3 转化为rgb 24色
dib1= FreeImage_ConvertTo24Bits(dib1);//4 获取数据指针
BYTE *pixels1 = (BYTE*)FreeImage_GetBits(dib1);width1 = FreeImage_GetWidth(dib1);height1 = FreeImage_GetHeight(dib1);cout<<"width1:"<<width1<<endl;cout<<"height1:"<<height1<<endl;// Load and create a texture  加载和创建纹理GLuint texture1;GLuint texture2;// ====================// Texture 1 纹理1// ====================glGenTextures(1, &texture1);// All upcoming GL_TEXTURE_2D operations now have effect on our texture object   全不即将到来的GL_TEXTURE_2D操作的将会影响的我们的纹理对象glBindTexture(GL_TEXTURE_2D, texture1);  // Set our texture parameters 设置我们的纹理程序glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);  // Set texture wrapping to GL_REPEAT 设置纹理 包装GL_REPEAT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);// Set texture filtering 设置纹理过滤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_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);FreeImage_Unload(dib);FreeImage_DeInitialise();glGenerateMipmap(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture. 解绑纹理,,这样做将不会让我们纹理陷入困境// ===================// Texture 2 纹理2// ===================glGenTextures(1, &texture2);glBindTexture(GL_TEXTURE_2D, texture2);// Set our texture parameters 设置我们的纹理程序glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);// Set texture filtering 设置纹理的过滤glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// Load, create texture and generate mipmaps 加载,创建纹理和形成译码glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width1, height1, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels1);FreeImage_Unload(dib1);FreeImage_DeInitialise();glGenerateMipmap(GL_TEXTURE_2D);glBindTexture(GL_TEXTURE_2D, 0);// Game loopwhile (!glfwWindowShouldClose(window)){// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions 检查是否有事件glfwPollEvents();// Render 渲染// Clear the colorbuffer 清除颜色缓存glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);// Activate shader 设置活动的着色器ourShader.Use();     // Bind Textures using texture units 绑定纹理使用纹理单元glActiveTexture(GL_TEXTURE0);//激活纹理单元glBindTexture(GL_TEXTURE_2D, texture1);//绑定当前纹理单元到激活的纹理单元//我们使用glUniform1i设置unform采样器的位置和日纹理单元。通过glUniform1i的设置,我们保证glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, texture2);glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture2"), 1);  // Draw container  画画容器glBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);glBindVertexArray(0);// Swap the screen buffersglfwSwapBuffers(window);}// Properly de-allocate all resources once they've outlived their purpose 删除占用的资源glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);// Terminate GLFW, clearing any resources allocated by GLFW. 清除任何关于GLFW的资源glfwTerminate();return 0;
}// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)glfwSetWindowShouldClose(window, GL_TRUE);
}

像素着色器

#version 330 core
in vec3 ourColor;
in vec2 TexCoord;out vec4 color;// Texture samplers
uniform sampler2D ourTexture1;
uniform sampler2D ourTexture2;void main()
{
// Linearly interpolate between both textures (second texture is only slightly combined) 在第一个和第二个纹理在中线性插入color = mix(texture(ourTexture1, TexCoord), texture(ourTexture2, TexCoord), 0.2);
//mix是GLSL带的函数,根据第三个参数决定前两个的输入值,现在是前面的占0.8,后面的0.2。假如第三个是0那么第一个值输入
}

顶点着色器

#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoord;out vec3 ourColor;
out vec2 TexCoord;void main()
{gl_Position = vec4(position, 1.0f);ourColor = color;// We swap the y-axis by substracing our coordinates from 1.我们替换y轴通过1减去我们的坐标//This is done because most images have the top y-axis inversed with OpenGL's top y-axis.这样做是因为大部分图像y轴坐标和opengl的坐标时颠倒的// TexCoord = texCoord;TexCoord = vec2(texCoord.x, 1.0 - texCoord.y);
}

纹理图片

运行效果图

用glew,glfw实现opengl学习笔记5课纹理(2)相关推荐

  1. OpenGL 学习笔记 II:初始化 API,第一个黑窗,游戏循环和帧率,OpenGL 默认垂直同步,glfw 帧率

    前情提要: 上一篇: OpenGL 学习笔记 I:OpenGL glew glad glfw glut 的关系,OpenGL 状态机,现代操作系统的窗口管理器,OpenGL 窗口和上下文 OpenGL ...

  2. 【OpenGL学习笔记⑧】——键盘控制正方体+光源【冯氏光照模型 光照原理 环境光照+漫反射光照+镜面光照】

    ✅ 重点参考了 LearnOpenGL CN 的内容,但大部分知识内容,小编已作改写,以方便读者理解. 文章目录 零. 成果预览图 一. 光照原理与投光物的配置 1.1 光照原理 1.2 投光物 二. ...

  3. 【OpenGL学习笔记⑥】——3D变换【旋转的正方体 实现地月系统 旋转+平移+缩放】

    ✈️ 文章目录 零. 成果预览图 一.3D立方体的顶点数组 二.纹理旋转 三.纹理缩放 四.画n个3D图形 五.轨道的数学公式 六.深度缓冲(Z 缓冲) 七.完整代码 八.参考附录: 神器的正方体 ☁ ...

  4. 【OpenGL学习笔记】地月系

    OpenGL学习笔记2-地月系 文章目录 OpenGL学习笔记2-地月系 前言 运行结果 纹理图片 一.TexturePool 1.**TexturePool.h** 2.**TexturePool. ...

  5. OpenGL学习笔记(八):进一步理解VAO、VBO和SHADER,并使用VAO、VBO和SHADER绘制一个三角形

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7888 ...

  6. OpenGL学习笔记:矩阵变换

    文章目录 缩放 glm矩阵表示 glm缩放矩阵实现 位移 齐次坐标 glm位移矩阵实现 旋转 沿x轴旋转 沿y轴旋转 沿z轴旋转 沿任意轴旋转 glm旋转矩阵实现 矩阵的组合 glm矩阵组合使用 接上 ...

  7. OpenGL学习笔记(一)绘制点线面及多面体

    OpenGL学习笔记(一)绘制点线面及多面体 绘制点线面 #include <iostream> #include <GL/GLUT.h> #define PI 3.14159 ...

  8. OpenGL学习笔记(一):环境搭建、三维空间坐标系理解以及OpenGL的基本使用

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7866 ...

  9. OPENGL学习笔记之八

    OPENGL学习笔记之八 2017/11/15 阅读材料来自learnopengl.com以及learnopengl-cn.github.io 我们通常会自己设定一个坐标的范围,之后再在顶点着色器中将 ...

  10. OpenGL学习笔记(十三):将纹理贴图应用到四边形上,对VAO/VBO/EBO/纹理/着色器的使用方式进行总结

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7919 ...

最新文章

  1. Java oracle 超出打开游标的最大数
  2. 用nrm一键切换npm源
  3. 链内容百度新算法怎样判断高质量外链和原创内容
  4. ORACLE经常使用系统查询
  5. iif能用到mysql中吗_数据库基础知识:SQL中的IIF语句详解
  6. LINUX系统配置相关
  7. SpringSecurity安全框架的笔记
  8. idea添加注释模板
  9. 离线数仓03-数仓分层业务逻辑
  10. 青青子美人之QQ美女找茬辅助工具c#源码
  11. MATLAB图像处理_YUV格式详解
  12. 从隐式转换案例,来挖掘开发人员的技能提升
  13. 学习要有但行好事,莫问前程的心态
  14. vim方向键、退格键失效,insert模式异常修复方法
  15. 一无所知学编程:Jargon File(1)
  16. 共享扫码娃娃机无现金化扫码支付
  17. 学习笔记:【案例】中医证型关联规则挖掘
  18. 顶级程序员的心得 –– Coders at Work
  19. Java真的不难(二十五)Stream流
  20. 跟着彭亮一起学人工智能之深度学习--零基础学人工智能

热门文章

  1. HDU 6096 树套树
  2. FPGA设计中遇到的奇葩问题之“芯片也要看出身”(二)
  3. php excel数据导出
  4. XAML实例教程系列 - 标记扩展(Markup Extensions)
  5. Oracle 备份与恢复学习笔记(8)
  6. CenturyLink设定NG-PON2部署阶段 业务、无线回程为初始服务目标
  7. 在EF4.1的DBContext中实现事务处理(BeginTransaction)和直接执行SQL语句的示例
  8. Gephi可视化(二)——Gephi Toolkit叫板Prefuse
  9. 添加地图图例 Arcengine+C#
  10. getchar()细节