int main(int argc, char** argv) { unsigned char dx = 0; unsigned char dy = 0; const char* arg_format = NULL; const char* arg_src = NULL; const char* arg_dst = NULL; if(argc == 6) { dx = (unsigned char) strtoul(argv[2], (char**) NULL, 10); dy = (unsigned char) strtoul(argv[3], (char**) NULL, 10); arg_format = argv[1]; arg_src = argv[4]; arg_dst = argv[5]; } else if(argc == 4) { arg_format = argv[1]; arg_src = argv[2]; arg_dst = argv[3]; if(check_ext(arg_src, "mgm")) { usage(argv[0]); return EXIT_FAILURE; } } else { usage(argv[0]); return EXIT_FAILURE; } // parse format int type; int format; if(strcmp(arg_format, "RGBA-8888") == 0) { type = TEXGZ_UNSIGNED_BYTE; format = TEXGZ_RGBA; } else if(strcmp(arg_format, "BGRA-8888") == 0) { type = TEXGZ_UNSIGNED_BYTE; format = TEXGZ_BGRA; } else if(strcmp(arg_format, "RGB-565") == 0) { type = TEXGZ_UNSIGNED_SHORT_5_6_5; format = TEXGZ_RGB; } else if(strcmp(arg_format, "RGBA-4444") == 0) { type = TEXGZ_UNSIGNED_SHORT_4_4_4_4; format = TEXGZ_RGBA; } else if(strcmp(arg_format, "RGB-888") == 0) { type = TEXGZ_UNSIGNED_BYTE; format = TEXGZ_RGB; } else if(strcmp(arg_format, "RGBA-5551") == 0) { type = TEXGZ_UNSIGNED_SHORT_5_5_5_1; format = TEXGZ_RGBA; } else if(strcmp(arg_format, "LUMINANCE") == 0) { type = TEXGZ_UNSIGNED_BYTE; format = TEXGZ_LUMINANCE; } else if(strcmp(arg_format, "LUMINANCE-F") == 0) { type = TEXGZ_FLOAT; format = TEXGZ_LUMINANCE; } else { LOGE("invalid format=%s", arg_format); return EXIT_FAILURE; } // import src texgz_tex_t* tex = NULL; if(check_ext(arg_src, "texgz")) { tex = texgz_tex_import(arg_src); } else if(check_ext(arg_src, "jpg")) { tex = texgz_jpeg_import(arg_src); } else if(check_ext(arg_src, "png")) { tex = texgz_png_import(arg_src); } else if(check_ext(arg_src, "mgm")) { tex = texgz_mgm_import(arg_src, dx, dy); } else { LOGE("invalid src=%s", arg_src); return EXIT_FAILURE; } if(tex == NULL) { return EXIT_FAILURE; } // convert to format if(texgz_tex_convert(tex, type, format) == 0) { goto fail_convert; } // export dst int ret = 0; if(check_ext(arg_dst, "texgz")) { ret = texgz_tex_export(tex, arg_dst); } else if(check_ext(arg_dst, "jpg")) { ret = texgz_jpeg_export(tex, arg_dst); } else if(check_ext(arg_dst, "png")) { ret = texgz_png_export(tex, arg_dst); } else { LOGE("invalid dst=%s", arg_dst); goto fail_dst; } if(ret == 0) { goto fail_export; } texgz_tex_delete(&tex); // success return EXIT_SUCCESS; // failure fail_export: fail_dst: fail_convert: texgz_tex_delete(&tex); return EXIT_FAILURE; }
void lzs_renderer_draw(lzs_renderer_t* self) { assert(self); LOGD("debug"); double t0 = a3d_utime(); // stretch screen to 800x480 glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrthof(0.0f, SCREEN_W, SCREEN_H, 0.0f, 0.0f, 2.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // draw camera glEnable(GL_TEXTURE_EXTERNAL_OES); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindTexture(GL_TEXTURE_EXTERNAL_OES, self->texid); glVertexPointer(3, GL_FLOAT, 0, VERTEX); glTexCoordPointer(2, GL_FLOAT, 0, COORDS); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_EXTERNAL_OES); utime_update("setup", &t0); // capture buffers GLint format = TEXGZ_BGRA; GLint type = GL_UNSIGNED_BYTE; glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &format); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &type); if((format == TEXGZ_BGRA) && (type == GL_UNSIGNED_BYTE)) { LOGD("readpixels format=0x%X, type=0x%X", format, type); // TODO - check for texgz errors // process buffers texgz_tex_t* bc = self->buffer_color; texgz_tex_t* bg = self->buffer_gray; texgz_tex_t* bsx = self->buffer_sx; texgz_tex_t* bsy = self->buffer_sy; glReadPixels(self->sphero_x - RADIUS_BALL, (SCREEN_H - self->sphero_y - 1) - RADIUS_BALL, bc->width, bc->height, bc->format, bc->type, (void*) bc->pixels); #ifdef DEBUG_BUFFERS texgz_tex_export(bc, "/sdcard/laser-shark/color.texgz"); #endif utime_update("readpixels", &t0); texgz_tex_computegray(bc, bg); utime_update("computegray", &t0); texgz_tex_computeedges3x3(bg, bsx, bsy); utime_update("computeedges", &t0); // compute peak { int x; int y; int peak_x = 0; int peak_y = 0; float peak = 0.0f; float* gpixels = (float*) bg->pixels; float* xpixels = (float*) bsx->pixels; float* ypixels = (float*) bsy->pixels; for(x = 0; x < bg->width; ++x) { for(y = 0; y < bg->height; ++y) { int idx = bg->width*y + x; // compute magnitude squared float magsq = xpixels[idx]*xpixels[idx] + ypixels[idx]*ypixels[idx]; gpixels[idx] = magsq; if(magsq > peak) { peak_x = x; peak_y = y; peak = magsq; } } } LOGD("peak=%f, peak_x=%i, peak_y=%i", peak, peak_x, peak_y); utime_update("computepeak", &t0); #ifdef DEBUG_BUFFERS texgz_tex_export(bg, "/sdcard/laser-shark/peak.texgz"); #endif // move sphero center to match peak self->sphero_x += (float) peak_x - (float) bg->width / 2.0f; self->sphero_y -= (float) peak_y - (float) bg->height / 2.0f; } } else { LOGE("unsupported format=0x%X, type=0x%X", format, type); } // compute phone X, Y center compute_position(self, SCREEN_CX, SCREEN_CY, &self->phone_X, &self->phone_Y); // compute sphero X, Y compute_position(self, self->sphero_x, self->sphero_y, &self->sphero_X, &self->sphero_Y); utime_update("computeposition", &t0); // compute goal float dx = self->phone_X - self->sphero_X; float dy = self->phone_Y - self->sphero_Y; float a = fix_angle(atan2f(dx, dy) * 180.0f / M_PI); self->sphero_goal = a - self->sphero_heading_offset; // compute speed float dotp = cosf((a - self->sphero_heading) * M_PI / 180.0f); if(dotp > 0.0f) { // linearly interpolate speed based on the turning angle self->sphero_speed = SPEED_MAX*dotp + SPEED_MIN*(1.0f - dotp); } else { // go slow to turn around self->sphero_speed = SPEED_MIN; } // draw camera cross-hair { float x = SCREEN_CX; float y = SCREEN_CY; float r = RADIUS_CROSS; limit_position(r, &x, &y); lzs_renderer_crosshair(y - r, x - r, y + r, x + r, 1.0f, 0.0f, 0.0f); } // draw sphero search box { float r = RADIUS_BALL; limit_position(r, &self->sphero_x, &self->sphero_y); float x = self->sphero_x; float y = self->sphero_y; lzs_renderer_drawbox(y - r, x - r, y + r, x + r, 0.0f, 1.0f, 0.0f, 0); } lzs_renderer_step(self); // draw string a3d_texstring_printf(self->string_sphero, "sphero: head=%i, x=%0.1f, y=%0.1f, spd=%0.2f, goal=%i", (int) fix_angle(self->sphero_heading + self->sphero_heading_offset), self->sphero_X, self->sphero_Y, self->sphero_speed, (int) fix_angle(self->sphero_goal)); a3d_texstring_printf(self->string_phone, "phone: heading=%i, slope=%i, x=%0.1f, y=%0.1f", (int) fix_angle(self->phone_heading), (int) fix_angle(self->phone_slope), self->phone_X, self->phone_Y); a3d_texstring_draw(self->string_sphero, 400.0f, 16.0f, 800, 480); a3d_texstring_draw(self->string_phone, 400.0f, 16.0f + self->string_sphero->size, 800, 480); a3d_texstring_draw(self->string_fps, (float) SCREEN_W - 16.0f, (float) SCREEN_H - 16.0f, SCREEN_W, SCREEN_H); utime_update("draw", &t0); //texgz_tex_t* screen = texgz_tex_new(SCREEN_W, SCREEN_H, SCREEN_W, SCREEN_H, TEXGZ_UNSIGNED_BYTE, TEXGZ_BGRA, NULL); //glReadPixels(0, 0, screen->width, screen->height, screen->format, screen->type, (void*) screen->pixels); //texgz_tex_export(screen, "/sdcard/laser-shark/screen.texgz"); //texgz_tex_delete(&screen); A3D_GL_GETERROR(); }