2017-08-09 2 views
0

J'ai une texture que je voudrais stocker en mémoire. Ensuite, je voudrais rendre une partie de cette texture dans un contexte OpenGL. Je voudrais savoir comment faire ça.Comment stocker une texture en mémoire et en restituer une petite partie

Jusqu'ici, j'ai configuré mes données de vertex.

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 
}; 

je puis passer par les étapes habituelles de la création d'un VBO, et en utilisant les fonctions 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 

charge et crée une texture:

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

J'utilise ensuite une boucle while activer le shader puis dessiner la texture. Cependant, je veux maintenant faire est de stocker cette texture en mémoire et de ne rendre qu'une petite partie de celle-ci. Dois-je utiliser un objet Renderbuffer ou un PBO, ou existe-t-il un autre moyen d'y parvenir?

Répondre

2

Si vous vouliez seulement rendre la partie de la texture chargée, ajustez simplement vos coordonnées de texture dans un VBO en conséquence.

Les coordonnées de texture transmises à la fonction texture(...) dans un programme de nuanceur correspondent au coin inférieur gauche (0,0) et l'angle supérieur droit est (1,1). Ainsi, si nous souhaitons mapper uniquement le coin supérieur droit d'une texture à un quadrant plat, nos coordonnées de texture seront composées de (0.5,0.5), (0.5,1.0), (1.0,1.0) et (1.0,0.5).


serait ici le sommet et la texture de coordonnées données 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 
}; 

Une fois que vous avez votre charge de données vertices à un VAO comme attribut 1 et textureCoords comme attribut 2. Ensuite, votre shaders devrait ressembler à quelque chose comme ceci:

Vertex Shader:

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

} 

Ce serait l'os le plus strict exemple de cartographier une partie d'une texture sur simple quad 2D.

+0

Merci beaucoup! C'est la réponse dont j'avais besoin:] –