how to use textures in android ndk with opengl es 2.0?

3,240 views
Skip to first unread message

Bill Hsu

unread,
Aug 13, 2010, 8:41:05 AM8/13/10
to android-ndk
how to use textures in android ndk with opengl es 2.0?

I tried many ways, but textures didn't show, just filled with black.
who can show me an example of how to use textures in android ndk with
opengl es 2.0? Thanks!




here is the code:

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

#include <android/log.h>

#include <stdlib.h>
#include <time.h>

typedef unsigned char byte;

static int view_width, view_height;
static byte* framebuffer;
static int framebuffer_size;
static GLuint texture_id[6];
static const char* vertexSrc =
"precision highp float;\n"
"precision highp int;\n"
"attribute vec4 vertexCoords;\n"
"attribute vec2 textureCoords;\n"
"varying vec2 f_textureCoords;\n"
"void main() {\n"
" f_textureCoords = textureCoords;\n"
" gl_Position = vertexCoords;\n"
"}\n";
static const char* fragmentSrc =
"precision highp float;\n"
"precision highp int;\n"
"uniform sampler2D texture;\n"
"varying vec2 f_textureCoords;\n"
"void main() {\n"
" gl_FragColor = texture2D(texture, f_textureCoords);\n"
"}\n";
static GLuint shaderProgram;
static GLint attrib_vertexCoords;
static GLint attrib_textureCoords;
static GLint uniform_texture;
static const GLfloat vertexCoords[] = {-1.0, 1.0, -1.0, -1.0, 1.0,
1.0, 1.0, -1.0};
static const GLfloat textureCoords[] = {0.0, 0.0, 0.0, 1.0, 1.0, 0.0,
1.0, 1.0};
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) {
view_width = width;
view_height = height;

framebuffer_size = 4*view_width*view_height;
framebuffer = (byte*)calloc(framebuffer_size, sizeof(byte));
for (int i = 0; i < framebuffer_size; i++) framebuffer[i] = 0;

glViewport(0, 0, view_width, view_height);

glGenTextures(6, &texture_id[0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_id[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture_id[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texture_id[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, texture_id[3]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, texture_id[4]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_2D, texture_id[5]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);

shaderProgram = glCreateProgram();
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSrc, NULL);
glCompileShader(vertexShader);
glAttachShader(shaderProgram, vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSrc, NULL);
glCompileShader(fragmentShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);

uniform_texture = glGetUniformLocation(shaderProgram, "texture");
glUniform1i(uniform_texture, 0);

attrib_vertexCoords = glGetAttribLocation(shaderProgram,
"vertexCoords");
glEnableVertexAttribArray(attrib_vertexCoords);
glVertexAttribPointer(attrib_vertexCoords, 2, GL_FLOAT, GL_FALSE, 0,
vertexCoords);

attrib_textureCoords = glGetAttribLocation(shaderProgram,
"textureCoords");
glEnableVertexAttribArray(attrib_textureCoords);
glVertexAttribPointer(attrib_textureCoords, 2, GL_FLOAT, GL_FALSE, 0,
textureCoords);
}

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv *
env, jobject obj) {
static int frame_count = 0;
static clock_t last_time = clock();
static int last_frame_count = 0;

frame_count++;
if (clock()-last_time > 1e7) {
__android_log_print(ANDROID_LOG_INFO, "libgl2jni", "fps: %f",
((float)frame_count-last_frame_count)/(clock()-last_time)*1e6);
last_time = clock();
last_frame_count = frame_count;
}

static byte val = 0;
val++;
if (val == 256) val = 0;
for (int i = 0; i < framebuffer_size; i++) framebuffer[i] = val;

int tst = frame_count%6;
if (tst == 0) {
glActiveTexture(GL_TEXTURE0);
} else if (tst == 1) {
glActiveTexture(GL_TEXTURE1);
} else if (tst == 2) {
glActiveTexture(GL_TEXTURE2);
} else if (tst == 3) {
glActiveTexture(GL_TEXTURE3);
} else if (tst == 4) {
glActiveTexture(GL_TEXTURE4);
} else if (tst == 5) {
glActiveTexture(GL_TEXTURE5);
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

.rommel

unread,
Aug 14, 2010, 11:12:24 AM8/14/10
to andro...@googlegroups.com
Even I am trying to find a way of doing that.

By the Bill you seems to have pretty good knowledge.


--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.


alan

unread,
Aug 16, 2010, 8:59:19 AM8/16/10
to android-ndk
have you called glEnable(GL_TEXTURE_2D) somewhere?

On Aug 14, 4:12 pm, ".rommel" <rommelbharg...@gmail.com> wrote:
> Even I am trying to find a way of doing that.
>
> By the Bill you seems to have pretty good knowledge.
>
> > android-ndk...@googlegroups.com<android-ndk%2Bunsu...@googlegroups.com>
> > .

Bill Hsu

unread,
Aug 16, 2010, 8:39:02 PM8/16/10
to andro...@googlegroups.com
I found a code in googlecode.it works well.
#include <jni.h>

#include "testclass.h"
#include <android/log.h>


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

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include <time.h>


#define LOG_TAG "jnitest"
#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 textureID;

GLuint gProgram;
GLuint gvPositionHandle;

GLuint gvTexCoordHandle;
GLuint gvSamplerHandle;
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);
}
}

static const char gVertexShader[] = "attribute vec4 a_position; \n"
"attribute vec2 a_texCoord; \n"
"varying vec2 v_texCoord; \n"
"void main() \n"
"{ \n"
" gl_Position = a_position; \n"
" v_texCoord = a_texCoord; \n"
"} \n";

static const char gFragmentShader[] =
"precision mediump float; \n"
"varying vec2 v_texCoord; \n"
"uniform sampler2D s_texture; \n"
"void main() \n"
"{ \n"
" gl_FragColor = texture2D( s_texture, v_texCoord );\n"
"}
\n";

const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f };
GLubyte testpixels[4 * 3] = { 255, 0, 0, // Red
0, 255, 0, // Green
0, 0, 255, // Blue
255, 255, 0 // Yellow
};

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

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

}

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 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");
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);
textureID = createSimpleTexture2D(textureID, testpixels, 2, 2, 3);

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

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

void renderFrame() {

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

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

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

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

// Load the vertex position
glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, stride,
vVertices);
// Load the texture coordinate
glVertexAttribPointer(gvTexCoordHandle, 2, GL_FLOAT, GL_FALSE, stride,
&vVertices[3]);

glEnableVertexAttribArray(gvPositionHandle);
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);

//checkGlError("glVertexAttribPointer");
//glEnableVertexAttribArray(gvPositionHandle);
//checkGlError("glEnableVertexAttribArray");
//glDrawArrays(GL_TRIANGLES, 0, 3);
//checkGlError("glDrawArrays");
}


static long
_getTime(void)
{
struct timeval now;

gettimeofday(&now, NULL);
return (long)(now.tv_sec*1000 + now.tv_usec/1000);
}
#ifdef __cplusplus
extern "C"
{
#endif
JNIEXPORT jint JNICALL Java_com_billhsu_jnitest_Jni_getString(JNIEnv*
env, jobject thiz);
JNIEXPORT void JNICALL Java_com_billhsu_jnitest_Jni_Resize(JNIEnv *


env, jobject obj, jint width, jint height);

JNIEXPORT void JNICALL Java_com_billhsu_jnitest_Jni_Render(JNIEnv
* env, jobject obj);
JNIEXPORT void JNICALL Java_com_billhsu_jnitest_Jni_init(JNIEnv *
env, jobject obj);
JNIEXPORT void JNICALL Java_com_billhsu_jnitest_Jni_Pause(JNIEnv *
env, jobject obj);
JNIEXPORT void JNICALL Java_com_billhsu_jnitest_Jni_Resume(JNIEnv *
env, jobject obj);
#ifdef __cplusplus
}
#endif
JNIEXPORT jint JNICALL Java_com_billhsu_jnitest_Jni_getString(JNIEnv
*env,jobject thiz)
{
testclass _testclass;
env->NewStringUTF(_testclass.getString());
}

JNIEXPORT void JNICALL Java_com_billhsu_jnitest_Jni_Resize(JNIEnv *


env, jobject obj, jint width, jint height)

{
setupGraphics(width, height);
}
JNIEXPORT void JNICALL Java_com_billhsu_jnitest_Jni_Render(JNIEnv *
env, jobject obj)
{
//long sTime=_getTime();

/* NOTE: if sDemoStopped is TRUE, then we re-render the same frame
* on each iteration.

if (!sDemoStopped) {
long delta=_getTime()-sTimeOld;
renderFrame(delta);
sTimeOld=_getTime();*/
renderFrame();

}
JNIEXPORT void JNICALL Java_com_billhsu_jnitest_Jni_init(JNIEnv * env,
jobject obj)
{/*
sTimeOld=_getTime();
gAppAlive = 1;
sDemoStopped = 0;
sTimeOffsetInit = 0;*/
}

JNIEXPORT void JNICALL Java_com_billhsu_jnitest_Jni_Pause(JNIEnv *
env, jobject obj)
{
//sDemoStopped = !sDemoStopped;
}

JNIEXPORT void JNICALL Java_com_billhsu_jnitest_Jni_Resume(JNIEnv *
env, jobject obj)
{
//sDemoStopped = !sDemoStopped;
//sTimeOld=_getTime();

>> >  glTexParameteri(GL_TEXTURE> > android-ndk...@googlegroups.com<android-ndk%2Bunsu...@googlegroups.com>


>> > .
>> > For more options, visit this group at
>> >http://groups.google.com/group/android-ndk?hl=en.
>>
>>
>
> --
> You received this message because you are subscribed to the Google Groups "android-ndk" group.
> To post to this group, send email to andro...@googlegroups.com.

> To unsubscribe from this group, send email to android-ndk...@googlegroups.com.

Reply all
Reply to author
Forward
0 new messages