纹理是一个2D图片(也有1D和3D),它用来添加物体的细节;这就像有一张绘有砖块的图片贴到你的3D的房子上,你的房子看起来就有了一个砖墙。因为我们可以在一张图片上插入足够多的细节,这样物体就会拥有很多细节而不会增加额外的顶点。

为了能够把纹理映射到三角形上,我们需要说明三角形的每个顶点各自对应纹理的哪个部分。这样每个顶点就会有一个纹理坐标(texture coordinate),它指明从纹理图像的哪个地方采样。之后在所有的其他的像素上进行像素插值。

纹理坐标与顶点坐标不同。纹理坐标的范围为(0,0)-(1,1) 分别代指左下角和右上角。

过程

1. 初始化OpenGL环境

2. 设置顶点&纹理坐标数组

GLfloat vertices[] = {
// Positions // Texture Coords
0.5f, 0.5f, 0.0f, 1.0f, -1.0f, // Top Right
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // Bottom Right
-0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // Bottom Left
-0.5f, 0.5f, 0.0f, 0.0f, -1.0f // Top Left

3. 创建并载入着色器

顶点着色器:

#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord; out vec2 TexCoord; void main()
{
gl_Position = vec4(position, 1.0f);
TexCoord = texCoord;
}

像素着色器:

#version 330 core
in vec3 ourColor;
in vec2 TexCoord; out vec4 color; uniform sampler2D ourTexture; void main()
{
color = texture(ourTexture, TexCoord);
}

4. 设置VAO、VBO、EBO

GLuint indices[] = {  // Note that we start from 0!
0, 1, 3, // First Triangle
1, 2, 3 // Second Triangle
};
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, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0); // TexCoord attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1); glBindVertexArray(0); // Unbind VAO

5. 创建并载入纹理 (这里载入图片使用SOIL库,推荐使用FreeImage)

// Load and create a texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture); // All upcoming GL_TEXTURE_2D operations now have effect on this texture object
// Set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT (usually basic 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);
// Load image, create texture and generate mipmaps
int width, height;
unsigned char* image = SOIL_load_image("image.jpg", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture.

6. 绘制及善后工作

	while (!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); // Bind Texture
glBindTexture(GL_TEXTURE_2D, texture); // Activate shader
ourShader.Use(); // Draw container
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0); // Swap the screen buffers
glfwSwapBuffers(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.
glfwTerminate();

效果

参考:http://bullteacher.com/7-textures.html

【OpenGL】纹理(Texture)的更多相关文章

  1. Unity 用户手册用户指南二维纹理 (Texture 2D)

    http://www.58player.com/blog-2327-953.html 二维纹理 (Texture 2D) 纹理 (Textures) 使您的 网格 (Meshes).粒子 (Parti ...

  2. OpenGL 纹理贴图

    前一节实例代码中有个贴图操作. 今天就简单说明一下纹理贴图... 为了使用纹理贴图.我们首先需要启用纹理贴图功能. 我们可以在Renderer实现的onSurfaceCreated中定义启用: // ...

  3. openGL 纹理05

    纹理(Texture) 为了能够把纹理映射(Map)到三角形上,我们需要指定三角形的每个顶点各自对应纹理的哪个部分. 这样每个顶点就会关联着一个纹理坐标(Texture Coordinate) 用来标 ...

  4. OpenGL: 纹理采样 texture sample

    Sampler (GLSL) Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的.一个sampler和 ...

  5. OpenGL纹理

    如果不用头文件,把所有东西堆在同一个cpp文件中,会出现“超出GPU内存的错误!” 1 //我们自己的着色器类 #ifndef SHADER_H #define SHADER_H #include & ...

  6. [OpenGL]纹理贴图实现 总结

    实现步骤 第一步:设置所需要的OpenGL环境 设置上下文环境 删除已经存在的渲染的缓存 设置颜色缓存 设置帧缓存 清除缓存 设置窗口大小 开启功能 编译shander 使用program 获取sha ...

  7. 二维纹理 Texture 2D

    Textures bring your Meshes, Particles, and interfaces to life! They are image or movie files that yo ...

  8. Qt5.6.0+OpenGL 纹理贴图首战告捷

    重要的话写在前面~~通过今晚的实验,知道了EBO是不能随便release的~~~一直不要release就可以了,否则vao会失效 Display.h #ifndef DISPLAYWIDGET_H # ...

  9. three.js学习:纹理Texture之平面纹理

    index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

随机推荐

  1. 代码:jquery自定义插件 demo

    jquery自定义插件 demo 2016-1-13 只是一个简易的示例 <script type="text/javascript" src="http://cd ...

  2. es 测试代码

    测试代码 PUT test/doc/1 { "num": 1.0 } PUT test/doc/2 { "num": 2.0 } POST _scripts/j ...

  3. Mybatis八( mybatis工作原理分析)

    MyBatis的主要成员 Configuration        MyBatis所有的配置信息都保存在Configuration对象之中,配置文件中的大部分配置都会存储到该类中 SqlSession ...

  4. Flex学习笔记--多层菜单按钮

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...

  5. javascript创建节点的事件绑定

    javascript创建节点的事件绑定 timeupdate事件是<video>中用来返回视频播放进度的事件,绑定在<video>标签返回视频播放位置(每秒计). 现video ...

  6. AspxGridView服务器事件列表

    2.AutoFilterCellEditorCreate (1)语法:publicdelegate void ASPxGridViewEditorCreateEventHandler(object s ...

  7. [转]使用Ubuntu Live CD修复Grub引导教程

    这个教程的方法我用过了,能够解决了我的问题. 这篇文章主要介绍了使用Ubuntu Live CD修复Grub引导教程,本文以 Ubuntu Live CD 修复 Grub 引导为例,需要的朋友可以参考 ...

  8. FB4.6项目迁移到4.7时 embed报错问题

    问题: 从FB4.6或更早版本移植到4.7的项目Embed标签,比如 [Embed(source="assets/BtnPlay.png")]   ,会报错 解决 方案: 4.7E ...

  9. centos7安装Lnmp(Linux+Nginx+MySql+Php+phpMyAdmin+Apache)

    centos7安装Lnmp(Linux+Nginx+MySql+Php)及Apache   Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx是一个高性能的HTTP和反向代理服务器,Ng ...

  10. dshow采集过程

    捕捉静态图片常用的filter是Sample Graber filter,它的用法参考手册.然后将捕捉filter的静态PIN连接到Sample Grabber,再将Sample Grabber连接到 ...