NDK OpenGL ES Cube


/*
 * 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 2.0 code

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

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <stdio.h>
#include <stdlib.h>
#include <math.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__)

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);
    }
}
int texPixel_w,texPixel_h;
bool bAlpha;
GLubyte* texPixels;
GLuint gvNormalHandle;
GLuint gvTexCoordHandle;
GLuint gvSamplerHandle;
GLuint textureID;




static void load_file(){

//	FILE* file = fopen("/sdcard/tex.txt","r");
	FILE* file = fopen("/storage/sdcard0/DCIM/a1.rgb","r");
	int w=480;
	int h=360;
	char *s;
	if (file != NULL)
	{
	  //  fscanf(file,"%d %d",&w,&h);
	    LOGI("w=%d h=%d\n", w, h);
	    texPixel_w=w;
	    texPixel_h=h;
	  //  fscanf(file,"%s",s);
	  //  if(s=="RGB")
	  //  {
	        bAlpha=false;
	        texPixels=new GLubyte[w*h*3];
	        for(int i=0;i<w*h*3;++i)
	        {
	            int a;
	            fscanf(file,"%d",&a);
	            texPixels[i]=(GLubyte)a;
	        }
	        /*
	    }
	    else
	    {
	        bAlpha=true;
	        texPixels=new GLubyte[w*h*4];
	        for(int i=0;i<w*h*4;++i)
	        {
	            int a;
	            fscanf(file,"%d",&a);
	            texPixels[i]=(GLubyte)a;
	        }
	    }*/

	}
}
/*
static const char gVertexShader[] = 
    "attribute vec4 vPosition;\n"
    "void main() {\n"
    "  gl_Position = vPosition;\n"
    "}\n";

static const char gFragmentShader[] = 
    "precision mediump float;\n"
    "void main() {\n"
    "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
    "}\n";
    */
static const char gVertexShader[] = "attribute vec4 a_position;   \n"
                "attribute vec3 a_normal;     \n"
        "attribute vec2 a_texCoord;   \n"
        "varying vec2 v_texCoord;     \n"
        "varying vec3 v_normal; \n"
        "void main()                  \n"
        "{                            \n"
        "   gl_Position = a_position; \n"
        " v_normal = a_normal; \n"
        "   v_texCoord = a_texCoord;  \n"
        "}                            \n";

static const char gFragmentShader[] =
                "precision mediump float;                            \n"
                        "varying vec2 v_texCoord;                            \n"
                        "varying vec3 v_normal; \n"
                        "uniform sampler2D s_texture;                        \n"
                        "void main()                                         \n"
                        "{                                                   \n"
                        "  gl_FragColor = texture2D( s_texture, v_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) {
    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;
}

GLuint gProgram;
GLuint gvPositionHandle;

bool setupGraphics_3(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, "vPosition");
    checkGlError("glGetAttribLocation");
    LOGI("glGetAttribLocation(\"vPosition\") = %d\n",
            gvPositionHandle);

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


/////////////////////////////////////////////////////////////
GLuint createSimpleTexture2D(GLuint _textureid, GLubyte* pixels,
                int width, int height, int channels) {

	load_file();


        // Bind the texture
        glActiveTexture(GL_TEXTURE0);
        checkGlError("glActiveTexture");
        // Bind the texture object
        glBindTexture(GL_TEXTURE_2D, _textureid);
        checkGlError("glBindTexture");

        GLenum format;
        switch (channels) {
        case 3:
                format = GL_RGB;
                break;
        case 1:
                format = GL_LUMINANCE;
                break;
        case 4:
                format = GL_RGBA;
                break;
        }
        // Load the texture
        glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format,
                        GL_UNSIGNED_BYTE, pixels);

        checkGlError("glTexImage2D");
        // Set the filtering mode
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

        return _textureid;

}



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, "a_position");
        gvNormalHandle=glGetAttribLocation(gProgram,"a_normal");
        gvTexCoordHandle = glGetAttribLocation(gProgram, "a_texCoord");

        gvSamplerHandle = glGetAttribLocation(gProgram, "s_texture");

        // Use tightly packed data
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

        // Generate a texture object
        glGenTextures(1, &textureID);
        if(!bAlpha)
            textureID = createSimpleTexture2D(textureID, texPixels,texPixel_w, texPixel_h, 3);
        else
            textureID = createSimpleTexture2D(textureID, texPixels,texPixel_w, texPixel_h, 3);

        checkGlError("glGetAttribLocation");
        LOGI("glGetAttribLocation(\"vPosition\") = %d\n",
                        gvPositionHandle);

        glViewport(0, 0, w, h);
        checkGlError("glViewport");
        return true;
}
const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
        0.5f, -0.5f };

void renderFrame_square() {

        GLfloat vVertices[] = { -0.75f, 1.0f, 0.0f, // Position 0
                                  0.0f, 1.0f, 0.0f,
                                        0.0f, 0.0f, // TexCoord 0
                        -.75f, -1.0f, 0.0f, // Position 1
                         0.0f,  1.0f, 0.0f,
                         0.0f,  1.0f, // TexCoord 1

                        0.75f, -1.0f, 0.0f, // Position 2
                         0.0f,  1.0f, 0.0f,
                         1.0f,  1.0f, // TexCoord 2

                        0.75f,  1.0f, 0.0f, // Position 3
                        0.0f,   1.0f, 0.0f,
                        1.0f,   0.0f // TexCoord 3
                        };


        GLfloat vVertices_Position[] = { -0.75f, 1.0f, 0.0f, // Position 0
                              -.75f, -1.0f, 0.0f, // Position 1
                              0.75f, -1.0f, 0.0f, // Position 2
                              0.75f,  1.0f, 0.0f, // Position 3
                              };
        GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
        GLsizei stride = 8 * sizeof(GLfloat); // 3 for position, 3 for normal, 2 for texture


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


        // glClearColor(0.0f, 	0.0f, 1.0f, 1.0f);
        checkGlError("glClearColor");

        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
        checkGlError("glClear");

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

        // Load the vertex position
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride,
                        vVertices);
                        checkGlError("gvPositionHandle");
        glVertexAttribPointer(1,3, GL_FLOAT, GL_FALSE, stride,
                    vVertices+3);
        checkGlError("gvNormalHandle");
        // Load the texture coordinate
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, stride,
                        vVertices+6);
        checkGlError("gvTexCoordHandle");

        glEnableVertexAttribArray(gvPositionHandle);
        glEnableVertexAttribArray(gvNormalHandle);
     //   glEnableVertexAttribArray(gvTexCoordHandle);


        // Bind the texture
     //   glActiveTexture(GL_TEXTURE0);
    //    glBindTexture(GL_TEXTURE_2D, textureID);

        // Set the sampler texture unit to 0
        glUniform1i(gvSamplerHandle, 0);

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);




   //     glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
   //     checkGlError("glVertexAttribPointer");
   //     glEnableVertexAttribArray(gvPositionHandle);
   //     checkGlError("glEnableVertexAttribArray");
   //     glDrawArrays(GL_TRIANGLES, 0, 3);
   //     checkGlError("glDrawArrays");


}

void renderFrame_square2a(){


}

void renderFrame_3angle() {

    static float grey;
    grey += 0.01f;
    if (grey > 1.0f) {
        grey = 0.0f;
    }
    glClearColor(grey, 1.0f, 1.0f, 1.0f);
    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, gTriangleVertices);
    checkGlError("glVertexAttribPointer");
    glEnableVertexAttribArray(gvPositionHandle);
    checkGlError("glEnableVertexAttribArray");
    glDrawArrays(GL_TRIANGLES, 0, 3);
    checkGlError("glDrawArrays");
}
// http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/
void renderFrame_square2(){


    glClearColor(0, 1.0f, 1.0f, 1.0f);
    checkGlError("glClearColor");
    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    checkGlError("glClear");

    glUseProgram(gProgram);


    ////////
    /*
	static const GLfloat g_vertex_buffer_data[] = {
	   -1.0f, -0.5f, 0.0f,
	   1.0f, -0.5f, 0.0f,
	   0.0f,  1.0f, 0.0f,
	};
	*/
	static const GLfloat g_vertex_buffer_data[] = {
	    -0.5f,-0.5f,-0.5f, // triangle 1 : begin
	    -0.5f,-0.5f, 0.5f,
	    -0.5f, 0.5f, 0.5f, // triangle 1 : end
	    0.5f, 0.5f,-0.5f, // triangle 2 : begin
	    -0.5f,-0.5f,-0.5f,
	    -0.5f, 0.5f,-0.5f, // triangle 2 : end
	    0.5f,-0.5f, 0.5f,
	    -0.5f,-0.5f,-0.5f,
	    0.5f,-0.5f,-0.5f,
	    0.5f, 0.5f,-0.5f,
	    0.5f,-0.5f,-0.5f,
	    -0.5f,-0.5f,-0.5f,
	    -0.5f,-0.5f,-0.5f,
	    -0.5f, 0.5f, 0.5f,
	    -0.5f, 0.5f,-0.5f,
	    0.5f,-0.5f, 0.5f,
	    -0.5f,-0.5f, 0.5f,
	    -0.5f,-0.5f,-0.5f,
	    -0.5f, 0.5f, 0.5f,
	    -0.5f,-0.5f, 0.5f,
	    0.5f,-0.5f, 0.5f,
	    0.5f, 0.5f, 0.5f,
	    0.5f,-0.5f,-0.5f,
	    0.5f, 0.5f,-0.5f,
	    0.5f,-0.5f,-0.5f,
	    0.5f, 0.5f, 0.5f,
	    0.5f,-0.5f, 0.5f,
	    0.5f, 0.5f, 0.5f,
	    0.5f, 0.5f,-0.5f,
	    -0.5f, 0.5f,-0.5f,
	    0.5f, 0.5f, 0.5f,
	    -0.5f, 0.5f,-0.5f,
	    -0.5f, 0.5f, 0.5f,
	    0.5f, 0.5f, 0.5f,
	    -0.5f, 0.5f, 0.5f,
	    0.5f,-0.5f, 0.5f
	};
	/////////////////
/*
	GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	// Use our shader
	glUseProgram(programID);
*/
	// Draw triangle...
	///////////////////////

	// This will identify our vertex buffer
	GLuint vertexbuffer;

	// Generate 1 buffer, put the resulting identifier in vertexbuffer
	glGenBuffers(1, &vertexbuffer);

	// The following commands will talk about our 'vertexbuffer' buffer
	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

	// Give our vertices to OpenGL.
	glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);


	/////////////////


	// 1rst attribute buffer : vertices
//	glEnableVertexAttribArray(0);
//	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
	/*
	glVertexAttribPointer(
	   0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
	   3,                  // size
	   GL_FLOAT,           // type
	   GL_FALSE,           // normalized?
	   0,                  // stride
	   (void*)0            // array buffer offset
	);
*/
	// Draw the triangle !
//
//	glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle

//	glDisableVertexAttribArray(0);



    glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, 0,  (void*)0 );
 //   glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
 //   checkGlError("glVertexAttribPointer");
    glEnableVertexAttribArray(gvPositionHandle);
//    checkGlError("glEnableVertexAttribArray");
 //   glDrawArrays(GL_TRIANGLES, 0, 3);
    // Draw the triangle !
    glDrawArrays(GL_TRIANGLES, 0, 12*3); // From index 0 to 12*3 -> 12 triangles -> 6 squares

//    checkGlError("glDrawArrays");


}
void renderFrame() {
//	renderFrame_3angle();
//	renderFrame_square();
//	renderFrame_2_square
	renderFrame_square2();

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

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

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj)
{
    renderFrame();
}


Leave a Reply