NativeActivityでのlibpngを使った画像表示なのですが、
Android NDKのNativeActivityに
http://d.hatena.ne.jp/hecomi/20130226/1361886948
を参考に組み込んでいたのですが
エラーが出て進めません。C++の標準ライブラリ?が読めてない感じなのですがどうすればいいでしょうか?
環境はeclipse adt-bundle-windows-x86-20130522、NDK android-ndk-r8e
プロジェクトをコピーしたのを圧縮したのを添付します。
よろしくお願いします。
エラー
説明 リソース パス ロケーション 型
Symbol 'height_' could not be resolved image.cpp /NativeActivity/jni 行 12 Semantic Error
Symbol 'width_' could not be resolved image.cpp /NativeActivity/jni 行 12 Semantic Error
Symbol 'color_type_' could not be resolved image.cpp /NativeActivity/jni 行 13 Semantic Error
Symbol 'bit_depth_' could not be resolved image.cpp /NativeActivity/jni 行 13 Semantic Error
Type 'std::string' could not be resolved image.cpp /NativeActivity/jni 行 10 Semantic Error
Member declaration not found image.cpp /NativeActivity/jni 行 10 Semantic Error
Symbol 'data_' could not be resolved image.cpp /NativeActivity/jni 行 11 Semantic Error
Symbol 'file_name_' could not be resolved image.cpp /NativeActivity/jni 行 11 Semantic Error
Symbol 'std' could not be resolved main.cpp /NativeActivity/jni 行 18 Semantic Error
Method 'c_str' could not be resolved image.cpp /NativeActivity/jni 行 18 Semantic Error
Method 'c_str' could not be resolved image.cpp /NativeActivity/jni 行 16 Semantic Error
Invalid arguments '
Candidates are:
void glGetShaderInfoLog(unsigned int, int, int *, char *)
' main.cpp /NativeActivity/jni 行 75 Semantic Error
Type 'std::string' could not be resolved main.cpp /NativeActivity/jni 行 74 Semantic Error
Type 'std::string' could not be resolved main.cpp /NativeActivity/jni 行 102 Semantic Error
Type 'std::string' could not be resolved image.h /NativeActivity/jni 行 15 Semantic Error
Symbol 'compression_type_' could not be resolved image.cpp /NativeActivity/jni 行 14 Semantic Error
Type 'std::string' could not be resolved image.h /NativeActivity/jni 行 7 Semantic Error
Symbol 'interlace_type_' could not be resolved image.cpp /NativeActivity/jni 行 13 Semantic Error
Method 'c_str' could not be resolved main.cpp /NativeActivity/jni 行 76 Semantic Error
Method 'c_str' could not be resolved main.cpp /NativeActivity/jni 行 104 Semantic Error
Symbol 'filter_method_' could not be resolved image.cpp /NativeActivity/jni 行 14 Semantic Error
Invalid arguments '
Candidates are:
void glGetProgramInfoLog(unsigned int, int, int *, char *)
' main.cpp /NativeActivity/jni 行 103 Semantic Error
Invalid arguments '
Candidates are:
__sFILE * fopen(const char *, const char *)
' image.cpp /NativeActivity/jni 行 16 Semantic Error
#include <string>
#include <EGL/egl.h>
#include <GLES/gl.h>
#include <GLES2/gl2.h>
#include <android/log.h>
#include <android_native_app_glue.h>
#include <image.h>
#define LOG_TAG ("gles2ndtest")
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
using namespace std;
struct engine
{
android_app* app;
EGLDisplay display;
EGLSurface surface;
EGLContext context;
};
const char* vertex_shader =
"attribute vec4 position;\n"
"attribute vec2 texcoord;\n"
"varying vec2 texcoordVarying;\n"
"void main() {\n"
"gl_Position = position;\n"
"texcoordVarying = texcoord;\n"
"}\n";
const char* fragment_shader =
"precision mediump float;\n"
"varying vec2 texcoordVarying;\n"
"uniform sampler2D texture;\n"
"void main() {\n"
"gl_FragColor = texture2D(texture, texcoordVarying);\n"
"}\n";
const float vertices[] = {
-1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f
};
const float texcoords[] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f
};
GLuint program, position, texcoord;
GLuint textures[1];
GLuint load_shader(GLenum shader_type, const char* source)
{
GLuint shader = glCreateShader(shader_type);
if (shader) {
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
GLint compiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLint length = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
if (length) {
std::string log(static_cast<size_t>(length), ' ');
glGetShaderInfoLog(shader, length, 0, &log[0]);
LOGE("Could not compile shader %d:\n%s\n", shader_type, log.c_str());
glDeleteShader(shader);
shader = 0;
}
}
}
return shader;
}
GLuint create_program(const char* vertex_source, const char* fragment_source)
{
GLuint vertex_shader = load_shader(GL_VERTEX_SHADER, vertex_source);
if (vertex_shader == 0) return 0;
GLuint pixel_shader = load_shader(GL_FRAGMENT_SHADER, fragment_source);
if (pixel_shader == 0) return 0;
GLuint program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, pixel_shader);
glLinkProgram(program);
GLint link_status = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &link_status);
if (link_status != GL_TRUE) {
GLint length = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
if (length) {
std::string log(static_cast<size_t>(length), ' ');
glGetProgramInfoLog(program, length, 0, &log[0]);
LOGE("Could not link program:\n%s\n", log.c_str());
}
glDeleteProgram(program);
program = 0;
}
return program;
}
void load_png()
{
program = create_program(vertex_shader, fragment_shader);
if (program == 0) return;
glUseProgram(program);
position = glGetAttribLocation(program, "position");
glEnableVertexAttribArray(position);
texcoord = glGetAttribLocation(program, "texcoord");
glEnableVertexAttribArray(texcoord);
textures[0] = glGetUniformLocation(program, "texture");
glGenTextures(1, textures);
glBindTexture(GL_TEXTURE_2D, textures[0]);
PNG png("/sdcard/tmp/hoge.png");
LOGD("Image: alpha:%d width:%dpx height%dpx",
png.has_alpha(), png.get_width(), png.get_height());
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, png.has_alpha() ? GL_RGBA : GL_RGB,
png.get_width(), png.get_height(),
0, png.has_alpha() ? GL_RGBA : GL_RGB,
GL_UNSIGNED_BYTE, png.get_data());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
int init(engine* e)
{
const EGLint attribs[] = {
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, 0, 0);
EGLConfig config;
EGLint num_configs;
eglChooseConfig(display, attribs, &config, 1, &num_configs);
EGLint format;
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry(e->app->window, 0, 0, format);
EGLSurface surface = eglCreateWindowSurface(display, config, e->app->window, 0);
EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribs);
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
return -1;
}
EGLint w, h;
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
e->display = display;
e->surface = surface;
e->context = context;
glViewport(0, 0, w, h);
}
void draw(engine* e)
{
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
LOGD("glBindTexture");
glBindTexture(GL_TEXTURE_2D, textures[0]);
LOGD("glVertexAttribPointer");
glVertexAttribPointer(texcoord, 2, GL_FLOAT, GL_FALSE, 0, texcoords);
LOGD("glVertexAttribPointer");
glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 0, vertices);
LOGD("glDrawArra");
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
eglSwapBuffers(e->display, e->surface);
}
void android_main(android_app* state)
{
app_dummy();
engine e;
state->userData = &e;
state->onAppCmd = [](android_app* app, int32_t cmd) {
auto e = static_cast<engine*>(app->userData);
switch (cmd) {
case APP_CMD_INIT_WINDOW:
init(e);
load_png();
draw(e);
break;
}
};
e.app = state;
while (1) {
int ident, events;
android_poll_source* source;
while ((ident=ALooper_pollAll(0, 0, &events, (void**)&source)) >= 0) {
if (source != 0) {
source->process(state, source);
}
if (state->destroyRequested != 0) {
if (e.display != EGL_NO_DISPLAY) {
eglMakeCurrent(e.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (e.context != EGL_NO_CONTEXT) {
eglDestroyContext(e.display, e.context);
}
if (e.surface != EGL_NO_SURFACE) {
eglDestroySurface(e.display, e.surface);
}
eglTerminate(e.display);
}
e.display = EGL_NO_DISPLAY;
e.context = EGL_NO_CONTEXT;
e.surface = EGL_NO_SURFACE;
return;
}
}
}
}
#include <string>
#include <png.h>
class PNG
{
public:
PNG(const std::string& file_name);
~PNG();
unsigned int get_width(); // 画像の横幅を取得
unsigned int get_height(); // 画像の縦幅を取得
bool has_alpha(); // RGBA/RGB --> true/false
unsigned char* get_data(); // 画像データ
private:
const std::string file_name_;
unsigned char* data_;
png_uint_32 width_, height_;
int bit_depth_, color_type_, interlace_type_;
int compression_type_, filter_method_;
};
#include <image.h>
#include <android/log.h>
#define LOG_TAG ("PNG")
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
PNG::PNG(const std::string& file_name) :
file_name_(file_name), data_(0),
width_(0), height_(0),
bit_depth_(0), color_type_(0), interlace_type_(0),
compression_type_(0), filter_method_(0)
{
FILE* fp = fopen(file_name_.c_str(), "rb");
if (fp == 0) {
LOGE("%s is not found.", file_name_.c_str());
fclose(fp);
return;
}
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (png == 0) {
LOGE("png_create_read_struct error.");
fclose(fp);
return;
}
png_infop info = png_create_info_struct(png);
if (info == 0) {
LOGE("png_create_info_struct error.");
png_destroy_read_struct(&png, 0, 0);
fclose(fp);
return;
}
if (setjmp(png_jmpbuf(png))) {
LOGE("png_jmpbuf error.");
png_destroy_read_struct(&png, &info, 0);
fclose(fp);
return;
}
png_init_io(png, fp);
unsigned int sig_bytes = 0;
png_set_sig_bytes(png, sig_bytes);
png_read_png(png, info, (PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND), 0);
png_get_IHDR(png, info, &width_, &height_, &bit_depth_, &color_type_, &interlace_type_, &compression_type_, &filter_method_);
unsigned int row_bytes = png_get_rowbytes(png, info);
if (data_ != 0) {
delete[] data_;
}
data_ = new unsigned char[row_bytes * height_];
png_bytepp rows = png_get_rows(png, info);
for (int i = 0; i < height_; ++i) {
memcpy(data_ + (row_bytes * i), rows[i], row_bytes);
}
png_destroy_read_struct(&png, &info, 0);
}
PNG::~PNG()
{
if (data_) delete[] data_;
}
unsigned int PNG::get_width()
{
return width_;
}
unsigned int PNG::get_height()
{
return height_;
}
unsigned char* PNG::get_data()
{
return data_;
}
bool PNG::has_alpha()
{
if (color_type_ == PNG_COLOR_TYPE_RGBA) {
return true;
}
return false;
}
TOP_LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#libpngのMakeFikeを読み込む
include $(TOP_LOCAL_PATH)/libpng/src/Android.mk
LOCAL_PATH := $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)
LOCAL_MODULE := native-activity
LOCAL_CFLAGS := -std=c++11 #コンパイルオプション
LOCAL_SRC_FILES := $(wildcard *.cpp) #ソースコードはcpp全部
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libpng/src/. #libpngのソースコード全部インクルード
LOCAL_LDLIBS := -lz -llog -landroid -lEGL -lGLESv1_CM -lGLESv2
LOCAL_STATIC_LIBRARIES := android_native_app_glue libpng
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)