【OpenGL】纹理(Texture)
纹理是一个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)的更多相关文章
- Unity 用户手册用户指南二维纹理 (Texture 2D)
http://www.58player.com/blog-2327-953.html 二维纹理 (Texture 2D) 纹理 (Textures) 使您的 网格 (Meshes).粒子 (Parti ...
- OpenGL 纹理贴图
前一节实例代码中有个贴图操作. 今天就简单说明一下纹理贴图... 为了使用纹理贴图.我们首先需要启用纹理贴图功能. 我们可以在Renderer实现的onSurfaceCreated中定义启用: // ...
- openGL 纹理05
纹理(Texture) 为了能够把纹理映射(Map)到三角形上,我们需要指定三角形的每个顶点各自对应纹理的哪个部分. 这样每个顶点就会关联着一个纹理坐标(Texture Coordinate) 用来标 ...
- OpenGL: 纹理采样 texture sample
Sampler (GLSL) Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的.一个sampler和 ...
- OpenGL纹理
如果不用头文件,把所有东西堆在同一个cpp文件中,会出现“超出GPU内存的错误!” 1 //我们自己的着色器类 #ifndef SHADER_H #define SHADER_H #include & ...
- [OpenGL]纹理贴图实现 总结
实现步骤 第一步:设置所需要的OpenGL环境 设置上下文环境 删除已经存在的渲染的缓存 设置颜色缓存 设置帧缓存 清除缓存 设置窗口大小 开启功能 编译shander 使用program 获取sha ...
- 二维纹理 Texture 2D
Textures bring your Meshes, Particles, and interfaces to life! They are image or movie files that yo ...
- Qt5.6.0+OpenGL 纹理贴图首战告捷
重要的话写在前面~~通过今晚的实验,知道了EBO是不能随便release的~~~一直不要release就可以了,否则vao会失效 Display.h #ifndef DISPLAYWIDGET_H # ...
- three.js学习:纹理Texture之平面纹理
index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
随机推荐
- idea 控制台行数限制
在本地进行测试时,会出现报错太多idea控制台被限制打印出来的日志被清楚的现象: idea改变控制台打印log限制的方法: 1. 点击 File ->Settings ->editor - ...
- java中的排序(自定义数据排序)--使用Collections的sort方法
排序:将一组数据按相应的规则 排列 顺序 1.规则: 基本数据类型:日常的大小排序. 引用类型: 内置引用类型(String,Integer..),内部已经指定规则,直接使用即可.---- ...
- python中的update
update()批量写入批量更新字典,举个例子: 1 a = { 2 "name":"dlrb", 3 "age":25, 4 " ...
- 3. group_concat与oracle中wm_concat用法一样
例子如下: select group_concat(rp.ROLE_ID) from eic_right_role_operator rp where rp.OPERATOR_ID = #id#
- POI解析大量数据
参考:https://blog.csdn.net/whandgdh/article/details/80267674
- JS 对象(对象遍历,拷贝)
定义属性 直接 obj.对象 的方法 Object.defineProperty(obj, prop, descriptor) ,这种方法可以设置 或者修改对象属性的访问权限 数据描述符和存取描述符 ...
- 用Redis实现分布式锁 与 实现任务队列
这一次总结和分享用Redis实现分布式锁 与 实现任务队列 这两大强大的功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说分享思路比分享代码更重要(貌似大概是这个意 ...
- ABAP-数据引用
*&---------------------------------------------------------------------* *& Report ZRICO_TES ...
- python之 pendulum讲解
一,下载地址:https://pypi.python.org/pypi/pendulum 二,pendulum的一大优势是内嵌式取代Python的datetime类,可以轻易地将它整合进已有代码,并且 ...
- iOS 坐标转换
例:把A view上的某个点的坐标(a)转换到B view上,两种方法 CGPoint targetPointB = [A convertPoint:a toView:B];(记忆方法:把A上的某个点 ...