概要
vistaでandroid studio 1.1.0やってみた。
jniやってみた。
練習問題やってみた。
練習問題
jniでopenglを表示せよ。
写真
方針
- ndk r10 にopengl無いので、r12bにする。
サンプルコード
#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 "ohi"
#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);
}
}
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";
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(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;
}
const GLfloat gTriangleVertices[] = {
0.0f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f
};
void renderFrame() {
static float grey;
grey += 0.01f;
if (grey > 1.0f)
{
grey = 0.0f;
}
glClearColor(grey, grey, grey, 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");
}
extern "C" {
JNIEXPORT void JNICALL Java_com_ohisamallc_ohiapp154_ohiapp154_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_com_ohisamallc_ohiapp154_ohiapp154_GL2JNILib_step(JNIEnv * env, jobject obj);
};
JNIEXPORT void JNICALL Java_com_ohisamallc_ohiapp154_ohiapp154_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height)
{
setupGraphics(width, height);
}
JNIEXPORT void JNICALL Java_com_ohisamallc_ohiapp154_ohiapp154_GL2JNILib_step(JNIEnv * env, jobject obj)
{
renderFrame();
}
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.cpp
LOCAL_LDLIBS := -llog -lGLESv2
include $(BUILD_SHARED_LIBRARY)
soビルド手順
>set PATH=C:\Users\ore\Downloads\android-ndk-r12b-windows-x86\android-ndk-r12b;%PATH%
>cd src/main/jni
>ndk-build
以上。