我有一个我想存储在内存中的纹理。然后我想将这个纹理的一部分渲染到 OpenGL 上下文中。我想知道如何做到这一点。
到目前为止,我已经设置了我的顶点数据。
GLfloat texture[] =
{
-0.5f, 0.5f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f, 1.0f, // top rght
0.5f, 0.5f, 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f, // bottom right
0.5f, -0.5f, 0.0, 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, // bottom left
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, // top left
};
然后我完成创建 VBO 和使用 OpenGL 函数的常规步骤
GLuint indices[] =
{
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, VB);
glBufferData(GL_ARRAY_BUFFER, sizeof(texture), texture, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//position attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
//colour attributes
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
加载并创建纹理:
GLuint texture0;
int width, height;
unsigned char* image[1];
glGenTextures(1, &texture0);
glBindTexture(GL_TEXTURE_2D, texture0);
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
image[0] = SOIL_load_image("Textures/texture.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image[0]);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image[0]);
glBindTexture(GL_TEXTURE_2D, texture0);
然后我使用 while 循环来激活着色器,然后绘制纹理。但是我现在想要做的是将这个纹理存储在内存中并只渲染它的一小部分。我是使用 Renderbuffer 对象还是 PBO,还是有其他实现方法?
最佳答案
如果您只想渲染加载纹理的一部分,只需相应地调整 VBO 中的纹理坐标即可。
传递给着色器程序中的 texture(...)
函数的纹理坐标将左下角映射为 (0,0)
,将右上角映射为(1,1)
。因此,如果我们只想将纹理的右上角映射到平面四边形,我们的纹理坐标将包含 (0.5,0.5)
、(0.5,1.0)
、(1.0,1.0)
和 (1.0,0.5)
。
这里是顶点和纹理坐标 VBO 数据:
float[] vertices = {
0.5, 0.5, 0.0, // upper left triangle
-0.5, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, 0.5, 0.0, // lower right triangle
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
};
float[] textureCoords = {
1.0, 1.0,
0.5, 1.0,
0.5, 0.5,
1.0, 1.0,
0.5, 0.5,
1.0, 0.5
};
一旦你将数据加载到 VAO 作为属性 1 和 textureCoords
作为属性 2。那么你的着色器应该看起来像这样:
顶点着色器:
in vec3 vertex;
in vec2 textureCoords;
out vec2 interpolatedCoords;
void main(void) {
interpolatedCoords = textureCoords;
gl_Position = vertex; // You transform these coordinates or whatever you'd like here
}
片段着色器:
in vec2 interpolatedCoords;
out vec4 out_color;
uniform sampler2D texture;
void main(void) {
out_color = texture(texture, interpolatedCoords);
}
这将是将纹理的某些部分映射到简单的 2D 四边形上的最简单的示例。
关于c - 如何将纹理存储在内存中并渲染其中的一小部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45594676/