2017-02-10 4 views
0

Ich versuche, eine einfache App auf Android Studio mit dem NDK, JNI C++ - Code aufrufen, laden und ein Bild anzuzeigen. Ich habe es geschafft, die Oberfläche zu erstellen und ein einfaches Dreieck zu zeichnen.Laden und Anzeigen eines Bildes in OpenGL ES 3.0 mit C++

Jetzt suche ich nach einer Möglichkeit, ein Bild in OpenGL ES 3.0 mit C++ zu laden und anzuzeigen. Ich habe die Suche gemacht, aber alle sind entweder zu komplex für mich oder veraltet oder in Java geschrieben. Es wäre toll, wenn mich jemand mit einem einfachen Beispiel führen könnte.

Antwort

0

Nach der Arbeit habe ich es endlich geschafft. Unten ist mein C++ - Quellcode. Ich verwende stb_image Bibliothek, um das Bild zu laden.

/* 
* Copyright (C) 2009 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

// OpenGL ES 3.0 code 

#include <jni.h> 
#include <android/log.h> 

#include <GLES3/gl3.h> 
#include <GLES3/gl3ext.h> 
#include <GLES3/gl3ext.h> 

#include <string> 
#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include "stb_image.h" 

#define LOG_TAG "libgl2jni" 
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) 
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 

GLuint mTexture, VAO;// Create reference Id for the texture 
GLuint gProgram; 
GLuint gvPositionHandle; 

static void printGLString(const char *name, GLenum s) { 
    const char *v = (const char *) glGetString(s); 
    LOGI("GL %s = %s\n", name, v); 
} 

static void checkGlError(const char* op) { 
    for (GLint error = glGetError(); error; error 
      = glGetError()) { 
     LOGI("after %s() glError (0x%x)\n", op, error); 
    } 
} 

auto gVertexShader = 
"#version 300 es\n" 
"layout (location=0) in vec3 position;\n" 
"layout (location=1) in vec3 color;\n" 
"layout (location=2) in vec2 texCoord;\n" 

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

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

auto gFragmentShader = 

"#version 300 es\n" 
"in vec3 ourColor;\n" 
"in vec2 TexCoord;\n" 

"out vec4 color;\n" 

"uniform sampler2D ourTexture;\n" 


"void main()\n" 
"{\n" 
    "color = texture(ourTexture , TexCoord);\n" 
"}\n"; 

GLuint loadShader(GLenum shaderType, const char* pSource) { 
    GLuint shader = glCreateShader(shaderType); 
    if (shader) { 
     glShaderSource(shader, 1, &pSource, NULL); 
     glCompileShader(shader); 
     GLint compiled = 0; 
     glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 
     if (!compiled) { 
      GLint infoLen = 0; 
      glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 
      if (infoLen) { 
       char* buf = (char*) malloc(infoLen); 
       if (buf) { 
        glGetShaderInfoLog(shader, infoLen, NULL, buf); 
        LOGE("Could not compile shader %d:\n%s\n", 
          shaderType, buf); 
        free(buf); 
       } 
       glDeleteShader(shader); 
       shader = 0; 
      } 
     } 
    } 
    return shader; 
} 

GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { // Load and Bind Fragments to Progam and link program then return result 
    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); 
    if (!vertexShader) { 
     return 0; 
    } 

    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); 
    if (!pixelShader) { 
     return 0; 
    } 

    GLuint program = glCreateProgram(); 
    if (program) { 
     glAttachShader(program, vertexShader); 
     checkGlError("glAttachShader"); 
     glAttachShader(program, pixelShader); 
     checkGlError("glAttachShader"); 
     glLinkProgram(program); 
     GLint linkStatus = GL_FALSE; 
     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 
     if (linkStatus != GL_TRUE) { 
      GLint bufLength = 0; 
      glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 
      if (bufLength) { 
       char* buf = (char*) malloc(bufLength); 
       if (buf) { 
        glGetProgramInfoLog(program, bufLength, NULL, buf); 
        LOGE("Could not link program:\n%s\n", buf); 
        free(buf); 
       } 
      } 
      glDeleteProgram(program); 
      program = 0; 
     } 
    } 
    return program; 
} 



bool setupGraphics(int w, int h) { 
    printGLString("Version", GL_VERSION); 
    printGLString("Vendor", GL_VENDOR); 
    printGLString("Renderer", GL_RENDERER); 
    printGLString("Extensions", GL_EXTENSIONS); 

    LOGI("setupGraphics(%d, %d)", w, h); 
    gProgram = createProgram(gVertexShader, gFragmentShader); 
    if (!gProgram) { 
     LOGE("Could not create program."); 
     return false; 
    } 
    gvPositionHandle = glGetAttribLocation(gProgram, "position"); 
    checkGlError("glGetAttribLocation"); 
    LOGI("glGetAttribLocation(\"position\") = %d\n", 
      gvPositionHandle); 

    glViewport(0, 0, w, h); 
    checkGlError("glViewport"); 
    return true; 
} 

GLfloat recVertices[] = { 
     // 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() 
{ 

    GLuint VBOs[2], EBO; // Initialize an buffer to store all the verticles and transfer them to the GPU 
    glGenVertexArrays (1,&VAO); // Generate VAO 
    glGenBuffers(1, VBOs); // Generate VBO 
    glGenBuffers(1, &EBO); // Generate EBO 
    glBindVertexArray (VAO);// Bind the Vertex Array 

    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, EBO);//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 
    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); 
    //Texture Coordinate Attribute 
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); 
    glEnableVertexAttribArray(2); 

    glBindVertexArray(0);//3. Unbind VAO 

} 

void generateTexture() 
{ 

    glGenTextures(1 , &mTexture); 
    glBindTexture(GL_TEXTURE_2D, mTexture);// Bind our 2D texture so that following set up will be applied 

    //Set texture wrapping parameter 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT); 

    //Set texture Filtering parameter 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); 

    //Load the image 
    int picWidth,picHeight,n; 
    unsigned char* image = stbi_load("/storage/emulated/sdcard/Lighthouse.jpg", &picWidth, &picHeight, &n,0); 
    if (image == NULL) { 
     LOGI("Failed to load image: %s", stbi_failure_reason()); 
    } 
    //Generate the image 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB , picWidth , picHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image); 
    glGenerateMipmap(GL_TEXTURE_2D); 

    stbi_image_free(image);// Free the reference to the image 
    glBindTexture(GL_TEXTURE_2D,0); //Unbind 2D textures 

} 
void renderFrame() { 
    static float grey; 
    grey += 0.01f; 
    if (grey > 1.0f) { 
     grey = 0.0f; 
    } 

    generateTexture(); 
    glClearColor(grey+0.05f, grey-0.03f, grey+0.02f, grey-0.04f); 
    checkGlError("glClearColor"); 
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 
    checkGlError("glClear"); 

    glUseProgram(gProgram); 
    checkGlError("glUseProgram"); 

    /*glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, recVertices); 
    checkGlError("glVertexAttribPointer"); 
    glEnableVertexAttribArray(gvPositionHandle); 
    checkGlError("glEnableVertexAttribArray"); 
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
    checkGlError("glDrawArrays");*/ 
    glActiveTexture(GL_TEXTURE0); 
    checkGlError("glActiveTexture"); 
    glBindTexture(GL_TEXTURE_2D,mTexture); 
    checkGlError("glBindTexture"); 
    GLint mlocation = glGetUniformLocation(gProgram,"ourTexture"); 
    checkGlError("glGetUniformLocation"); 
    glUniform1i(mlocation,0); 
    checkGlError("glUniform1i"); 
    initBuffers(); 
    glBindVertexArray(VAO); 
    checkGlError("glBindVertexArray"); 
    glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0); 

} 

extern "C" { 
    JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_init(JNIEnv * env, jobject obj, jint width, jint height); 
    JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_step(JNIEnv * env, jobject obj); 
}; 

JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_init(JNIEnv * env, jobject obj, jint width, jint height) 
{ 
    setupGraphics(width, height); 
} 

JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_step(JNIEnv * env, jobject obj) 
{ 

    renderFrame(); 
} 
Verwandte Themen