2017-08-09 63 views
0

我有一个纹理,我想要在内存中存储。然后我想将这个纹理的一部分渲染到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,还是有其他方法来实现这一点?

回答

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到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); 

} 

这将是一个纹理的某些部分映射到一个简单的二维四边形的最梗概例子。

+0

非常感谢!这是我需要的答案:] –