moved OpenGL wrappers to separate header
added GlBuffer, GlTexture and GpuMat support to InputArray replaced addTextOpenGl function by render + GlFont
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/core/gpumat.hpp"
|
||||
#include "opencv2/core/opengl_interop.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/calib3d/calib3d.hpp"
|
||||
@@ -13,56 +13,52 @@ using namespace std;
|
||||
using namespace cv;
|
||||
using namespace cv::gpu;
|
||||
|
||||
class PointCloudRenderer
|
||||
{
|
||||
public:
|
||||
PointCloudRenderer(const Mat& points, const Mat& img, double scale);
|
||||
|
||||
void onMouseEvent(int event, int x, int y, int flags);
|
||||
void draw();
|
||||
void update(int key, double aspect);
|
||||
|
||||
int fov_;
|
||||
|
||||
private:
|
||||
int mouse_dx_;
|
||||
int mouse_dy_;
|
||||
|
||||
double yaw_;
|
||||
double pitch_;
|
||||
Point3d pos_;
|
||||
|
||||
TickMeter tm_;
|
||||
static const int step_;
|
||||
int frame_;
|
||||
|
||||
GlCamera camera_;
|
||||
GlArrays pointCloud_;
|
||||
string fps_;
|
||||
};
|
||||
|
||||
bool stop = false;
|
||||
|
||||
void mouseCallback(int event, int x, int y, int flags, void* userdata)
|
||||
{
|
||||
int* dx = static_cast<int*>(userdata);
|
||||
int* dy = dx + 1;
|
||||
if (stop)
|
||||
return;
|
||||
|
||||
static int oldx = x;
|
||||
static int oldy = y;
|
||||
static bool moving = false;
|
||||
|
||||
if (event == EVENT_LBUTTONDOWN)
|
||||
{
|
||||
oldx = x;
|
||||
oldy = y;
|
||||
moving = true;
|
||||
}
|
||||
else if (event == EVENT_LBUTTONUP)
|
||||
{
|
||||
moving = false;
|
||||
}
|
||||
|
||||
if (moving)
|
||||
{
|
||||
*dx = oldx - x;
|
||||
*dy = oldy - y;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dx = 0;
|
||||
*dy = 0;
|
||||
}
|
||||
PointCloudRenderer* renderer = static_cast<PointCloudRenderer*>(userdata);
|
||||
renderer->onMouseEvent(event, x, y, flags);
|
||||
}
|
||||
|
||||
inline int clamp(int val, int minVal, int maxVal)
|
||||
void openGlDrawCallback(void* userdata)
|
||||
{
|
||||
return max(min(val, maxVal), minVal);
|
||||
}
|
||||
if (stop)
|
||||
return;
|
||||
|
||||
Point3d rotate(Point3d v, double yaw, double pitch)
|
||||
{
|
||||
Point3d t1;
|
||||
t1.x = v.x * cos(-yaw / 180.0 * CV_PI) - v.z * sin(-yaw / 180.0 * CV_PI);
|
||||
t1.y = v.y;
|
||||
t1.z = v.x * sin(-yaw / 180.0 * CV_PI) + v.z * cos(-yaw / 180.0 * CV_PI);
|
||||
|
||||
Point3d t2;
|
||||
t2.x = t1.x;
|
||||
t2.y = t1.y * cos(pitch / 180.0 * CV_PI) - t1.z * sin(pitch / 180.0 * CV_PI);
|
||||
t2.z = t1.y * sin(pitch / 180.0 * CV_PI) + t1.z * cos(pitch / 180.0 * CV_PI);
|
||||
|
||||
return t2;
|
||||
PointCloudRenderer* renderer = static_cast<PointCloudRenderer*>(userdata);
|
||||
renderer->draw();
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
@@ -192,96 +188,168 @@ int main(int argc, const char* argv[])
|
||||
const string windowName = "OpenGL Sample";
|
||||
|
||||
namedWindow(windowName, WINDOW_OPENGL);
|
||||
resizeWindow(windowName, 400, 400);
|
||||
|
||||
PointCloudRenderer renderer(points, imgLeftColor, scale);
|
||||
|
||||
int fov = 0;
|
||||
createTrackbar("Fov", windowName, &fov, 100);
|
||||
|
||||
int mouse[2] = {0, 0};
|
||||
setMouseCallback(windowName, mouseCallback, mouse);
|
||||
|
||||
GlArrays pointCloud;
|
||||
|
||||
pointCloud.setVertexArray(points);
|
||||
pointCloud.setColorArray(imgLeftColor, false);
|
||||
|
||||
GlCamera camera;
|
||||
camera.setScale(Point3d(scale, scale, scale));
|
||||
|
||||
double yaw = 0.0;
|
||||
double pitch = 0.0;
|
||||
|
||||
const Point3d dirVec(0.0, 0.0, -1.0);
|
||||
const Point3d upVec(0.0, 1.0, 0.0);
|
||||
const Point3d leftVec(-1.0, 0.0, 0.0);
|
||||
Point3d pos;
|
||||
|
||||
TickMeter tm;
|
||||
const int step = 20;
|
||||
int frame = 0;
|
||||
createTrackbar("Fov", windowName, &renderer.fov_, 100);
|
||||
setMouseCallback(windowName, mouseCallback, &renderer);
|
||||
setOpenGlDrawCallback(windowName, openGlDrawCallback, &renderer);
|
||||
|
||||
while (true)
|
||||
{
|
||||
tm.start();
|
||||
|
||||
int key = waitKey(1);
|
||||
|
||||
if (key >= 0)
|
||||
key = key & 0xff;
|
||||
|
||||
if (key == 27)
|
||||
{
|
||||
stop = true;
|
||||
break;
|
||||
}
|
||||
|
||||
double aspect = getWindowProperty(windowName, WND_PROP_ASPECT_RATIO);
|
||||
|
||||
const double posStep = 0.1;
|
||||
|
||||
#ifdef _WIN32
|
||||
const double mouseStep = 0.001;
|
||||
#else
|
||||
const double mouseStep = 0.000001;
|
||||
#endif
|
||||
|
||||
const int mouseClamp = 300;
|
||||
|
||||
camera.setPerspectiveProjection(30.0 + fov / 100.0 * 40.0, aspect, 0.1, 1000.0);
|
||||
|
||||
int mouse_dx = clamp(mouse[0], -mouseClamp, mouseClamp);
|
||||
int mouse_dy = clamp(mouse[1], -mouseClamp, mouseClamp);
|
||||
|
||||
yaw += mouse_dx * mouseStep;
|
||||
pitch += mouse_dy * mouseStep;
|
||||
|
||||
key = tolower(key);
|
||||
if (key == 'w')
|
||||
pos += posStep * rotate(dirVec, yaw, pitch);
|
||||
else if (key == 's')
|
||||
pos -= posStep * rotate(dirVec, yaw, pitch);
|
||||
else if (key == 'a')
|
||||
pos += posStep * rotate(leftVec, yaw, pitch);
|
||||
else if (key == 'd')
|
||||
pos -= posStep * rotate(leftVec, yaw, pitch);
|
||||
else if (key == 'q')
|
||||
pos += posStep * rotate(upVec, yaw, pitch);
|
||||
else if (key == 'e')
|
||||
pos -= posStep * rotate(upVec, yaw, pitch);
|
||||
|
||||
camera.setCameraPos(pos, yaw, pitch, 0.0);
|
||||
renderer.update(key, aspect);
|
||||
|
||||
pointCloudShow(windowName, camera, pointCloud);
|
||||
|
||||
tm.stop();
|
||||
|
||||
if (frame++ >= step)
|
||||
{
|
||||
ostringstream fps;
|
||||
fps << "FPS: " << step / tm.getTimeSec();
|
||||
|
||||
clearTextOpenGl(windowName);
|
||||
addTextOpenGl(windowName, fps.str(), Point(0, 0), Scalar::all(255), "Courier New", 16);
|
||||
|
||||
frame = 0;
|
||||
tm.reset();
|
||||
}
|
||||
updateWindow(windowName);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int PointCloudRenderer::step_ = 20;
|
||||
|
||||
PointCloudRenderer::PointCloudRenderer(const Mat& points, const Mat& img, double scale)
|
||||
{
|
||||
mouse_dx_ = 0;
|
||||
mouse_dy_ = 0;
|
||||
|
||||
fov_ = 0;
|
||||
yaw_ = 0.0;
|
||||
pitch_ = 0.0;
|
||||
|
||||
frame_ = 0;
|
||||
|
||||
camera_.setScale(Point3d(scale, scale, scale));
|
||||
|
||||
pointCloud_.setVertexArray(points);
|
||||
pointCloud_.setColorArray(img, false);
|
||||
|
||||
tm_.start();
|
||||
}
|
||||
|
||||
inline int clamp(int val, int minVal, int maxVal)
|
||||
{
|
||||
return max(min(val, maxVal), minVal);
|
||||
}
|
||||
|
||||
void PointCloudRenderer::onMouseEvent(int event, int x, int y, int flags)
|
||||
{
|
||||
static int oldx = x;
|
||||
static int oldy = y;
|
||||
static bool moving = false;
|
||||
|
||||
if (event == EVENT_LBUTTONDOWN)
|
||||
{
|
||||
oldx = x;
|
||||
oldy = y;
|
||||
moving = true;
|
||||
}
|
||||
else if (event == EVENT_LBUTTONUP)
|
||||
{
|
||||
moving = false;
|
||||
}
|
||||
|
||||
if (moving)
|
||||
{
|
||||
mouse_dx_ = oldx - x;
|
||||
mouse_dy_ = oldy - y;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_dx_ = 0;
|
||||
mouse_dy_ = 0;
|
||||
}
|
||||
|
||||
const int mouseClamp = 300;
|
||||
mouse_dx_ = clamp(mouse_dx_, -mouseClamp, mouseClamp);
|
||||
mouse_dy_ = clamp(mouse_dy_, -mouseClamp, mouseClamp);
|
||||
}
|
||||
|
||||
Point3d rotate(Point3d v, double yaw, double pitch)
|
||||
{
|
||||
Point3d t1;
|
||||
t1.x = v.x * cos(-yaw / 180.0 * CV_PI) - v.z * sin(-yaw / 180.0 * CV_PI);
|
||||
t1.y = v.y;
|
||||
t1.z = v.x * sin(-yaw / 180.0 * CV_PI) + v.z * cos(-yaw / 180.0 * CV_PI);
|
||||
|
||||
Point3d t2;
|
||||
t2.x = t1.x;
|
||||
t2.y = t1.y * cos(pitch / 180.0 * CV_PI) - t1.z * sin(pitch / 180.0 * CV_PI);
|
||||
t2.z = t1.y * sin(pitch / 180.0 * CV_PI) + t1.z * cos(pitch / 180.0 * CV_PI);
|
||||
|
||||
return t2;
|
||||
}
|
||||
|
||||
void PointCloudRenderer::update(int key, double aspect)
|
||||
{
|
||||
const Point3d dirVec(0.0, 0.0, -1.0);
|
||||
const Point3d upVec(0.0, 1.0, 0.0);
|
||||
const Point3d leftVec(-1.0, 0.0, 0.0);
|
||||
|
||||
const double posStep = 0.1;
|
||||
|
||||
#ifdef _WIN32
|
||||
const double mouseStep = 0.001;
|
||||
#else
|
||||
const double mouseStep = 0.000001;
|
||||
#endif
|
||||
|
||||
camera_.setPerspectiveProjection(30.0 + fov_ / 100.0 * 40.0, aspect, 0.1, 1000.0);
|
||||
|
||||
yaw_ += mouse_dx_ * mouseStep;
|
||||
pitch_ += mouse_dy_ * mouseStep;
|
||||
|
||||
if (key == 'w')
|
||||
pos_ += posStep * rotate(dirVec, yaw_, pitch_);
|
||||
else if (key == 's')
|
||||
pos_ -= posStep * rotate(dirVec, yaw_, pitch_);
|
||||
else if (key == 'a')
|
||||
pos_ += posStep * rotate(leftVec, yaw_, pitch_);
|
||||
else if (key == 'd')
|
||||
pos_ -= posStep * rotate(leftVec, yaw_, pitch_);
|
||||
else if (key == 'q')
|
||||
pos_ += posStep * rotate(upVec, yaw_, pitch_);
|
||||
else if (key == 'e')
|
||||
pos_ -= posStep * rotate(upVec, yaw_, pitch_);
|
||||
|
||||
camera_.setCameraPos(pos_, yaw_, pitch_, 0.0);
|
||||
|
||||
tm_.stop();
|
||||
|
||||
if (frame_++ >= step_)
|
||||
{
|
||||
ostringstream ostr;
|
||||
ostr << "FPS: " << step_ / tm_.getTimeSec();
|
||||
fps_ = ostr.str();
|
||||
|
||||
frame_ = 0;
|
||||
tm_.reset();
|
||||
}
|
||||
|
||||
tm_.start();
|
||||
}
|
||||
|
||||
void PointCloudRenderer::draw()
|
||||
{
|
||||
camera_.setupProjectionMatrix();
|
||||
camera_.setupModelViewMatrix();
|
||||
|
||||
render(pointCloud_);
|
||||
|
||||
render(fps_, GlFont::get("Courier New", 16), Scalar::all(255), Point2d(3.0, 0.0));
|
||||
}
|
||||
|
Reference in New Issue
Block a user