2017-02-14 519 views
1

我试图制作一个应用程序,在Android Studio中用NDK和JNI绘制图像,以使用OpenGL ES调用C++代码。我已经通过教程了解如何在OpenGL中执行此操作:https://learnopengl.com/#!Getting-started/Textures,它使用GLSL 330内核。但是,Android模拟器不支持OpenGL ES 3.0(请注意,在此链接中:https://developer.android.com/ndk/guides/stable_apis.html)。如何将GLSL #version 330内核转换为GLSL ES #version 100?

因此,我必须使用GLSL ES#版本100,它不支持下面着色器中的“布局”,“入”和“出”。我应该如何编辑它们以便它们可以在#version 100中运行,并且如果我编辑它们,源代码中是否有任何更改?感谢您的关注和您的帮助。

更新:经过搜索后,我发现我可以使用glGetAttributeLocation获取顶点着色器中变量的位置,而不是使用布局(位置= 0)。但是,GLSL ES#版本100中没有VAO,所以我仍然无法确定它在没有VAO的情况下如何工作。

我的顶点着色器:

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

片段着色器:

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

初始化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 

绘制图像:

 // 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

为diffirent版本创建单独的着色器,并切换到C++代码中需要的着色器。或者,使用其他模拟器,如bluestacks。 – Reaper

+0

感谢您的建议,我决定在我的手机上运行它,现在它工作。 :) –

回答

1

最后,我设法解决它。在GLSL ES 100中,没有我上面提到的inoutlayout(location=0)。因此,我不得不更换它们:

in =>attribute

out =>varying

,彻底去除layout(location=0),因为没有这样的事情确实在GLSL ES 100一样的东西,据我知道。

由于去除layout(location=0)的,我们要告诉我们的节目顶点数据,这是位置颜色textCoord在这种情况下的位置。随着layout(location=0),我们可以简单的把位0在

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

没有它,我们首先需要获得顶点属性与定位:

GLint mPosition= glGetAttributeLocation(ourProgram,"position") 

然后更换常数0,1或2我的预定义mPosition

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

同样在colortextCoord。下面

是我的编辑顶点着色器,片段着色器以及如何初始化VBO,并通过我们的数据:

编辑vertex shader为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"; 

为GLSL ES 100编辑fragment shader

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

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


} 

然后我们替换VAO我们绘制函数与initBuffer()函数的调用

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

希望这将有助于谁和我有同样的问题结合。请随时问我,如果你有任何问题:)。