2017-02-14 1 views
1

J'essaie de créer une application qui dessine une image dans Android Studio avec NDK et JNI pour appeler du code C++ en utilisant OpenGL ES. Je suis allé à travers le tutoriel comment faire cela dans OpenGL à: https://learnopengl.com/#!Getting-started/Textures, qui utilisent GLSL 330 core. Toutefois, OpenGL ES 3.0 n'est pas pris en charge sur l'émulateur Android (note dans ce lien: https://developer.android.com/ndk/guides/stable_apis.html). Par conséquent, je dois utiliser le GLSL ES #version 100, qui ne supporte pas "layout", "in" et "out" dans les shaders ci-dessous. Comment les éditer afin qu'ils puissent fonctionner dans #version 100 et y a-t-il des changements dans le code source si je les édite? Merci pour votre attention et votre aide. Après la recherche, j'ai découvert que je pouvais utiliser glGetAttributeLocation pour obtenir l'emplacement de la variable dans le vertex shader au lieu d'utiliser layout (location = 0). Cependant, il n'y a pas de VAO dans GLSL ES #version 100, donc je ne pouvais toujours pas comprendre comment cela fonctionne sans VAO.Comment faire pour convertir GLSL #version 330 core à GLSL ES #version 100?

shaders Mon Vertex:

#version 330 core 
layout (location = 0) in vec3 position; 
layout (location = 1) in vec3 color; 
layout (location = 2) in vec2 texCoord; 

out vec3 ourColor; 
out vec2 TexCoord; 

void main() 
{ 
    gl_Position = vec4(position, 1.0f); 
    ourColor = color; 
    // We swap the y-axis by substracing our coordinates from 1. This is done because most images have the top y-axis inversed with OpenGL's top y-axis. 
    // TexCoord = texCoord; 
    TexCoord = vec2(texCoord.x, 1.0 - texCoord.y); 
} 

fragment Shader:

#version 330 core 
in vec3 ourColor; 
in vec2 TexCoord; 

out vec4 color; 

// Texture samplers 
uniform sampler2D ourTexture1; 
uniform sampler2D ourTexture2; 

void main() 
{ 
    // Linearly interpolate between both textures (second texture is only slightly combined) 
    color = mix(texture(ourTexture1, TexCoord), texture(ourTexture2, TexCoord), 0.2); 
} 

Initialiser VAO, VBO ,:

// Set up vertex data (and buffer(s)) and attribute pointers 
    GLfloat vertices[] = { 
     // Positions   // Colors   // Texture Coords 
     0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Top Right 
     0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Bottom Right 
     -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Left 
     -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // Top Left 
    }; 
    GLuint indices[] = { // Note that we start from 0! 
     0, 1, 3, // First Triangle 
     1, 2, 3 // Second Triangle 
    }; 
    GLuint VBO, VAO, ; 
    glGenVertexArrays(1, &VAO); 
    glGenBuffers(1, &VBO); 
    glGenBuffers(1, &); 

    glBindVertexArray(VAO); 

    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 

    // Position attribute 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); 
    glEnableVertexAttribArray(0); 
    // Color attribute 
    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 

dessiner une image:

 // Clear the colorbuffer 
     glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 
     glClear(GL_COLOR_BUFFER_BIT); 

     // Activate shader 
     ourShader.Use();  

     // Bind Textures using texture units 
     glActiveTexture(GL_TEXTURE0); 
     glBindTexture(GL_TEXTURE_2D, texture1); 
     glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0); 
     glActiveTexture(GL_TEXTURE1); 
     glBindTexture(GL_TEXTURE_2D, texture2); 
     glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture2"), 1); 

     // Draw container 
     glBindVertexArray(VAO); 
     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 
     glBindVertexArray(0); 
+1

Créer des shaders séparés pour les versions diffirent et passer à celui requis en code C++. Vous pouvez également utiliser un autre émulateur, comme les bluestacks. – Reaper

+0

Merci pour vos conseils, je décide de l'exécuter sur mon téléphone et cela fonctionne maintenant. :) –

Répondre

1

Enfin, je parviens à le résoudre. Dans GLSL ES 100, il n'y a pas inout et layout(location=0) comme je l'ai mentionné ci-dessus. Par conséquent, je dois les remplacer:

in =>attribute

out =>varying

Et supprimer complètement layout(location=0) parce qu'il n'y a pas une telle chose fait la même chose en GLSL ES 100 pour autant que je compte .

En raison de la suppression de layout(location=0), nous devons dire au programme l'emplacement de nos données sommet, qui sont la position, couleur et textCoord dans ce cas. Avec layout(location=0), nous pourrions simplement mettre l'emplacement 0 dans le

glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); 
glEnableVertexAttribArray(0); 

Sans elle, nous avons d'abord besoin d'obtenir l'emplacement de l'attribut sommet avec:

GLint mPosition= glGetAttributeLocation(ourProgram,"position") 

remplacez le nombre constant de 0,1 ou 2 avec mon prédéfini mPosition:

glVertexAttribPointer(mPosition,3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); 
glEnableVertexAttribArray(mPosition);; 

sur la même color et textCoord.

ci-dessous sont mon vertex shader édité, fragment shader et comment initialiser VBO et passer nos données:

Edité vertex shader pour GLSL ES 100:

auto gVertexShader = 
"attribute vec3 position;\n" 
"attribute vec3 color;\n" 
"attribute vec2 texCoord;\n" 

"varying vec3 ourColor;\n" 
"varying vec2 TexCoord;\n" 

"void main()\n" 
"{\n" 
    "gl_Position = vec4(position,1.0); // Add the xOffset to the x position of the vertex position\n" 
    "ourColor = color;\n" 
    "TexCoord= vec2(texCoord.x,1.0-texCoord.y);\n" 
"}\n"; 

Edité fragment shader pour GLSL ES 100:

static const char FRAGMENT_SHADER[] = 
    "#version 100\n" 
    "precision mediump float;\n" 
    "varying vec4 vColor;\n" 
    "void main() {\n" 
    " gl_FragColor = vColor;\n" 
    "}\n"; 

ma fonction InitBuffer:

// Set up vertex data (and buffer(s)) and attribute pointers 
    GLfloat vertices[] = { 
     // Positions   // Colors   // Texture Coords 
     0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Top Right 
     0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Bottom Right 
     -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Left 
     -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // Top Left 
    }; 
    GLuint indices[] = { // Note that we start from 0! 
     0, 1, 3, // First Triangle 
     1, 2, 3 // Second Triangle 
    }; 
void initBuffers() 
{ 
    GLint mPosition,mCorlor,mTextCoord; 
    GLuint VBOs[2]; // Initialize an buffer to store all the verticles and transfer them to the GPU 

    glGenBuffers(2, VBOs); // Generate VBO 


    glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);//Bind verticles array for OpenGL to use 
    glBufferData(GL_ARRAY_BUFFER, sizeof(recVertices), recVertices, GL_STATIC_DRAW); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBOs[1]);//Bind the indices for information about drawing sequence 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 

    // 1. set the vertex attributes pointers 
    // Position Attribute 
    mPosition=glGetAttributeLocation(Program, "position"); 
    glVertexAttribPointer(mPosition, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); 
    glEnableVertexAttribArray(mPosition); 
    // Color Attribute 

    mColor=glGetAttributeLocation(Program, "color"); 
    glVertexAttribPointer(mColor, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); 
    glEnableVertexAttribArray(mColor); 
    //Texture Coordinate Attribute 

    mTextCoord=glGetAttributeLocation(Program, "textCoord")' 
    glVertexAttribPointer(mTextCoord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); 
    glEnableVertexAttribArray(mTextCoord); 


} 

Ensuite, nous remplacer VAO obligatoire dans notre fonction de tirage au sort avec l'appel de initBuffer() fonction

// Clear the colorbuffer 
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT); 

    // Activate shader 
    ourShader.Use();  

    // Bind Textures using texture units 
    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, texture1); 
    glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0); 
    glActiveTexture(GL_TEXTURE1); 
    glBindTexture(GL_TEXTURE_2D, texture2); 
    glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture2"), 1); 

    // Draw container 
    initBuffers(); 
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 
    glBindVertexArray(0); 

Espérons que cela aidera qui a le même problème avec moi. N'hésitez pas à me demander si vous avez des questions :).