我有一个纹理,我想存储在内存中。然后我想将这个纹理的一部分渲染到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,还是有其他方法可以实现这一目标?
答案 0 :(得分:2)
如果您只想渲染已加载纹理的部分,只需相应调整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
};
您的数据加载vertices
作为属性1的VAO和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
}
Fragment Shader:
in vec2 interpolatedCoords;
out vec4 out_color;
uniform sampler2D texture;
void main(void) {
out_color = texture(texture, interpolatedCoords);
}
这将是将纹理的某些部分映射到简单的2D四边形上的最简单的例子。