おまけ:RICOH THETAのJPG画像を平面-球変換してOpenGLで表示する(その6)
RICOH THETA for openFrameworksのテクスチャマッピング版
簡単になりすぎて、勉強にならないから困ります、、、。こちらはGPUの無いレッツノートでも動きます。
githubに上げました。
https://github.com/dotchang/ricohThetaExample
testApp.cpp
#include "testApp.h"
#define _USE_MATH_DEFINES
#include <math.h>
#include <fstream>
testApp::testApp(int argc, char* argv[])
: ofBaseApp()
{
if(argc == 2) filename = argv[1];
else filename = "E:\\Pictures\\RICOH THETA\\R0010001.JPG";
}
int testApp::get_angles(const char* filename)
{
std::ifstream fin;
const int size = 10*1000;
unsigned char head[size];
fin.open(filename, std::ios::in | std::ios::binary);
if(fin.fail()){
std::cerr << filename << " open failed." << std::endl;
return -1;
}
fin.read( (char*)head,size);
union {
int i;
unsigned int ui;
unsigned char b[4];
} bytes;
for(int i=0; i<size; i++){
unsigned char *buf = head + i;
if(buf[0] == 0x00 && buf[1] == 0x04 && buf[2] == 0x00 && buf[3] == 0x05 &&
buf[4] == 0x00 && buf[5] == 0x00 && buf[6] == 0x00 && buf[7] == 0x01) {
// big endian to little endian
bytes.b[0] = buf[3+8];
bytes.b[1] = buf[2+8];
bytes.b[2] = buf[1+8];
bytes.b[3] = buf[0+8];
unsigned int offset = bytes.ui + 12;
bytes.b[0] = head[offset+3];
bytes.b[1] = head[offset+2];
bytes.b[2] = head[offset+1];
bytes.b[3] = head[offset+0];
unsigned int a = bytes.ui;
bytes.b[0] = head[offset+7];
bytes.b[1] = head[offset+6];
bytes.b[2] = head[offset+5];
bytes.b[3] = head[offset+4];
unsigned int b = bytes.ui;
compass = (float)a / (float)b;
std::cout << "compass = " << compass << std::endl;
break;
}
}
for(int i=0; i<size; i++){
unsigned char *buf = head + i;
if(buf[0] == 0x00 && buf[1] == 0x03 && buf[2] == 0x00 && buf[3] == 0x0a &&
buf[4] == 0x00 && buf[5] == 0x00 && buf[6] == 0x00 && buf[7] == 0x02) {
// big endian to little endian
bytes.b[0] = buf[3+8];
bytes.b[1] = buf[2+8];
bytes.b[2] = buf[1+8];
bytes.b[3] = buf[0+8];
unsigned int offset = bytes.ui + 12;
bytes.b[0] = head[offset+3];
bytes.b[1] = head[offset+2];
bytes.b[2] = head[offset+1];
bytes.b[3] = head[offset+0];
int a = bytes.i;
bytes.b[0] = head[offset+7];
bytes.b[1] = head[offset+6];
bytes.b[2] = head[offset+5];
bytes.b[3] = head[offset+4];
int b = bytes.i;
zenith_x = (float)a / (float)b;
std::cout << "zenith_x = " << zenith_x << std::endl;
bytes.b[0] = head[offset+3+8];
bytes.b[1] = head[offset+2+8];
bytes.b[2] = head[offset+1+8];
bytes.b[3] = head[offset+0+8];
a = bytes.i;
bytes.b[0] = head[offset+7+8];
bytes.b[1] = head[offset+6+8];
bytes.b[2] = head[offset+5+8];
bytes.b[3] = head[offset+4+8];
b = bytes.i;
zenith_y = (float)a / (float)b;
std::cout << "zenith_y = " << zenith_y << std::endl;
break;
}
}
fin.close();
return 0;
}
//--------------------------------------------------------------
void testApp::setup() {
get_angles(filename.data());
ofSetVerticalSync(true);
// load an image from disk
img.loadImage(filename);
// loop through the image in the x and y axes
float r = 10.0f; // radius
ofEnableDepthTest();
ofEnableNormalizedTexCoords();
glEnable(GL_POINT_SMOOTH); // use circular points instead of square points
glPointSize(3); // make the points bigger
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
cam.setAutoDistance(false);
cam.setPosition(0,0,0);
cam.lookAt(ofVec3f(-r,0,0),ofVec3f(0,0,1));
cam.setDistance(1.0);
}
//--------------------------------------------------------------
void testApp::update() {
}
//--------------------------------------------------------------
void testApp::draw() {
ofBackgroundGradient(ofColor::gray, ofColor::black, OF_GRADIENT_CIRCULAR);
// keep horizontal
ofVec3f updir = cam.getUpDir();
ofVec3f lookdir = cam.getLookAtDir();
ofVec3f hordir = updir.getCrossed(lookdir);
ofQuaternion quat;
quat.makeRotate(ofVec3f(hordir.x,hordir.y,0).normalized(),hordir.normalized( ) );
ofMatrix4x4 upmat(quat);
ofVec3f new_updir = upmat*updir;
cam.lookAt(lookdir, new_updir);
// keep zenith
ofQuaternion qzx, qzy, qzz;
qzx.set(sin(zenith_x/2*M_PI/180.0),0,0,cos(zenith_x/2*M_PI/180.0));
qzy.set(0,sin(-zenith_y/2*M_PI/180.0),0,cos(-zenith_y/2*M_PI/180.0));
qzz.set(0,0,sin(compass/2*M_PI/180.0),cos(compass/2*M_PI/180.0));
ofMatrix4x4 m44(qzx*qzy);
ofMatrix4x4 m_yaw(qzz);
// even points can overlap with each other, let's avoid that
cam.begin();
ofPushMatrix();
//ofMultMatrix(m_yaw); // adjust north
ofMultMatrix(m44.getInverse());
ofMatrix4x4 rot(0,-1,0,0,
0,0,-1,0,
1,0,0,0,
0,0,0,1);
ofMultMatrix(rot);
img.bind();
ofSphere(10);
img.unbind();
ofPopMatrix();
cam.end();
}
//--------------------------------------------------------------
void testApp::keyPressed(int key){
}
//--------------------------------------------------------------
void testApp::keyReleased(int key){
}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y){
}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h){
}
//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg){
}
//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo){
if( dragInfo.files.size() > 0 ){
img.loadImage(dragInfo.files[0]);
}
}
こっそり、ドラッグアンドドロップに対応しました。