目录
Texture Wrapping:UV超过了[0,1]怎么办?
Texture Filter:UV经过计算得到的是浮点数怎么办?
Texture Unit——OpenGL提供了多个Texture锚定点,显示多个纹理图
OpenGL提供了几种方式,如图
Texture Filter的结果以及相关情况下的设置
也就是说在纹理变小的时候,采用Nearest进行采样;纹理变大的时候,采用Linear方式采样。
①在C++当中创建Texture,并且绑定到系统中进行渲染和数据传递
②在shader中进行处理
新建ffImage.h及ffImage.cpp
- //ffImage.h
- #pragma once
- #include "Base.h"
-
- class ffImage
- {
- private:
- int m_width;
- int m_height;
- int m_picType;
- ffRGBA* m_data;
- public:
- int getWidth()const { return m_width; }
- int getHeight()const { return m_height; }
- int getPicType()const { return m_picType; }
- ffRGBA* getData()const { return m_data; }
-
- ffRGBA getColor(int x, int y)const {
- if (x<0 || x>m_width - 1 || y<0 || y>m_height - 1) {
- return ffRGBA(0, 0, 0, 0);
- }
- return m_data[y * m_width + x];
- }
-
- ffImage(int _width = 0, int _height = 0, int _picType = 0, ffRGBA* _data = nullptr) {
- m_width = _width;
- m_height = _height;
- m_picType = _picType;
-
- int _sumSize = m_width * m_height;
- if (_data && _sumSize) {
- m_data = new ffRGBA[_sumSize];
- memcpy(m_data, _data, sizeof(ffRGBA) * _sumSize);
- }
- else {
- m_data = nullptr;
- }
- }
- ~ffImage() {
- if (m_data) {
- delete[]m_data;
- }
- }
-
- public:
- static ffImage* readFromFile(const char* _fileName);
-
- };
-
- //ffImage.cpp
- #include "ffImage.h"
- #define STB_IMAGE_IMPLEMENTATION
- #include "stb_image.h"
-
- ffImage* ffImage::readFromFile(const char* _fileName)
- {
- int _picType = 0;
- int _width = 0;
- int _height = 0;
-
- //stbimage读入图片是反过来的
- stbi_set_flip_vertically_on_load(true);
-
- unsigned char* bits = stbi_load(_fileName, &_width, &_height, &_picType, STBI_rgb_alpha);
- ffImage* _image = new ffImage(_width, _height, _picType, (ffRGBA*)bits);
-
- stbi_image_free(bits);
- return _image;
- }
同样的,建立一个句柄:
unsigned int _texture = 0;
纹理的相关处理:
- void initTexture() {
- _pImage = ffImage::readFromFile("res/wall.jpg");
- //纹理绑定
- glGenTextures(1, &_texture);
- glBindTexture(GL_TEXTURE_2D, _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_LINEAR);
- //读入图片数据
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _pImage->getWidth(), _pImage->getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE,_pImage->getData());
- }
同样的,需要在顶点数组中添加UV信息:
- 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, 0.0f,1.0f,0.0f, 0.0f,1.0f
- };
同样的,新建一个锚点(layout):
- //对哪个锚点进行操作:layout=0的锚点,读3个顶点,类型为float,不需要归一化,每次步长为3个float大小,从0处开始读
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(sizeof(float)*3));
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(sizeof(float)*6));
同样的,激活这个锚点2
- //打开锚点:激活
- glEnableVertexAttribArray(0);
- glEnableVertexAttribArray(1);
- glEnableVertexAttribArray(2);
同样的,更新一下shader
- //vertexShader.glsl
- #version 330 core
- layout (location = 0) in vec3 aPos;
- layout (location = 1) in vec3 aColor;
- layout (location = 2) in vec2 aUV;
-
- out vec4 outColor;
- out vec2 outUV;
-
- void main()
- {
- gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
- outColor = vec4(aColor, 1.0f);
- outUV = aUV;
- };
- //fragmentShader.glsl
- #version 330 core
- out vec4 FragColor;
-
- in vec4 outColor;
- in vec2 outUV;
-
- uniform sampler2D outTexture;
-
- void main()
- {
- FragColor = texture(outTexture, outUV);
- };
这里值得注意一点,在fragmentShader中的sampler2D,这里并没有通过C++的代码传入数据,因为我们只用了一张纹理贴图,默认texture unit为0,而这个sampler2D也是默认取为0的texture unit
渲染结果:
混合结果:
- //fragmentShader.glsl
- #version 330 core
- out vec4 FragColor;
-
- in vec4 outColor;
- in vec2 outUV;
-
- uniform sampler2D outTexture;
-
- void main()
- {
- FragColor = texture(outTexture, outUV) * outColor;
- };