概要
vistaでandroid studio 1.1.0やってみた。
jniやってみた。
練習問題やってみた。
練習問題
jniでopenglで箱を回転、表示せよ。
写真
サンプルコード
#include <jni.h>
#include <android/log.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include "Matrix.hpp"
#define LOG_TAG "libNative"
#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 const char glVertexShader[] =
"attribute vec4 vertexPosition;\n"
"attribute vec3 vertexColour;\n"
"varying vec3 fragColour;\n"
"uniform mat4 projection;\n"
"uniform mat4 modelView;\n"
"void main()\n"
"{\n"
" gl_Position = projection * modelView * vertexPosition;\n"
" fragColour = vertexColour;\n"
"}\n";
static const char glFragmentShader[] =
"precision mediump float;\n"
"varying vec3 fragColour;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(fragColour, 1.0);\n"
"}\n";
GLuint loadShader(GLenum shaderType, const char* shaderSource) {
GLuint shader = glCreateShader(shaderType);
if (shader != 0)
{
glShaderSource(shader, 1, &shaderSource, NULL);
glCompileShader(shader);
GLint compiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (compiled != GL_TRUE)
{
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 0)
{
char * logBuffer = (char*) malloc(infoLen);
if (logBuffer != NULL)
{
glGetShaderInfoLog(shader, infoLen, NULL, logBuffer);
LOGE("Could not Compile Shader %d:\n%s\n", shaderType, logBuffer);
free(logBuffer);
logBuffer = NULL;
}
glDeleteShader(shader);
shader = 0;
}
}
}
return shader;
}
GLuint createProgram(const char* vertexSource, const char * fragmentSource) {
GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource);
if (vertexShader == 0)
{
return 0;
}
GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource);
if (fragmentShader == 0)
{
return 0;
}
GLuint program = glCreateProgram();
if (program != 0)
{
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
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 > 0)
{
char* logBuffer = (char*) malloc(bufLength);
if (logBuffer != NULL)
{
glGetProgramInfoLog(program, bufLength, NULL, logBuffer);
LOGE("Could not link program:\n%s\n", logBuffer);
free(logBuffer);
logBuffer = NULL;
}
}
glDeleteProgram(program);
program = 0;
}
}
return program;
}
GLuint simpleCubeProgram;
GLuint vertexLocation;
GLuint vertexColourLocation;
GLuint projectionLocation;
GLuint modelViewLocation;
float projectionMatrix[16];
float modelViewMatrix[16];
float angle = 0;
bool setupGraphics(int width, int height) {
simpleCubeProgram = createProgram(glVertexShader, glFragmentShader);
if (simpleCubeProgram == 0)
{
LOGE ("Could not create program");
return false;
}
vertexLocation = glGetAttribLocation(simpleCubeProgram, "vertexPosition");
vertexColourLocation = glGetAttribLocation(simpleCubeProgram, "vertexColour");
projectionLocation = glGetUniformLocation(simpleCubeProgram, "projection");
modelViewLocation = glGetUniformLocation(simpleCubeProgram, "modelView");
matrixPerspective(projectionMatrix, 45, (float)width / (float)height, 0.1f, 100);
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, width, height);
return true;
}
GLfloat cubeVertices[] = {-1.0f, 1.0f, -1.0f, /* Back. */
1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, 1.0f, /* Front. */
1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f, /* Left. */
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f, /* Right. */
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, -1.0f, /* Top. */
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f, /* Bottom. */
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f
};
GLfloat colour[] = {1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f
};
GLushort indices[] = {
0, 2, 3, 0, 1, 3, 4, 6, 7, 4, 5, 7, 8, 9, 10, 11, 8, 10, 12, 13, 14, 15, 12, 14, 16, 17, 18, 16, 19, 18, 20, 21, 22, 20, 23, 22
};
void renderFrame() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
matrixIdentityFunction(modelViewMatrix);
matrixRotateX(modelViewMatrix, angle);
matrixRotateY(modelViewMatrix, angle);
matrixTranslate(modelViewMatrix, 0.0f, 0.0f, -10.0f);
glUseProgram(simpleCubeProgram);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cubeVertices);
glEnableVertexAttribArray(vertexLocation);
glVertexAttribPointer(vertexColourLocation, 3, GL_FLOAT, GL_FALSE, 0, colour);
glEnableVertexAttribArray(vertexColourLocation);
glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, projectionMatrix);
glUniformMatrix4fv(modelViewLocation, 1, GL_FALSE, modelViewMatrix);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, indices);
angle += 1;
if (angle > 360)
{
angle -= 360;
}
}
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 := hello1
LOCAL_SRC_FILES := hello.cpp Matrix.cpp
LOCAL_LDLIBS := -llog -lGLESv2
include $(BUILD_SHARED_LIBRARY)
以上。