|
|
|
@ -25,6 +25,7 @@ using std::stringstream; |
|
|
|
|
int main(int argc, char **argv) { |
|
|
|
|
using namespace kb; |
|
|
|
|
|
|
|
|
|
//Initialize the application
|
|
|
|
|
kb::init(WIDTH, HEIGHT); |
|
|
|
|
|
|
|
|
|
//Initialize VP9 HW encoding using VAAPI
|
|
|
|
@ -34,39 +35,52 @@ int main(int argc, char **argv) { |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
//Copy OpenCL Context for VAAPI. Must be called right after VideoWriter/VideoCapture initialization.
|
|
|
|
|
va::init(); |
|
|
|
|
|
|
|
|
|
va::copy(); |
|
|
|
|
|
|
|
|
|
//If we render offscreen we don't need x11.
|
|
|
|
|
if (!OFFSCREEN) |
|
|
|
|
x11::init(); |
|
|
|
|
//Passing 'true' to egl::init() creates a debug OpenGL-context.
|
|
|
|
|
egl::init(); |
|
|
|
|
//Initialize OpenGL.
|
|
|
|
|
gl::init(); |
|
|
|
|
//Initialize nanovg.
|
|
|
|
|
nvg::init(); |
|
|
|
|
|
|
|
|
|
cerr << "EGL Version: " << egl::get_info() << endl; |
|
|
|
|
cerr << "OpenGL Version: " << gl::get_info() << endl; |
|
|
|
|
cerr << "OpenCL Platforms: " << endl << cl::get_info() << endl; |
|
|
|
|
|
|
|
|
|
//BGRA frame buffer.
|
|
|
|
|
cv::UMat frameBuffer; |
|
|
|
|
//BGR video frame.
|
|
|
|
|
cv::UMat videoFrame; |
|
|
|
|
|
|
|
|
|
//The text to display
|
|
|
|
|
string text = cv::getBuildInformation(); |
|
|
|
|
//Create a istringstream that we will read and the rewind. over again.
|
|
|
|
|
std::istringstream iss(text); |
|
|
|
|
//Count the number of lines.
|
|
|
|
|
off_t numLines = std::count(text.begin(), text.end(), '\n'); |
|
|
|
|
|
|
|
|
|
//Derive the transformation matrix M for the pseudo 3D effect from src and dst.
|
|
|
|
|
vector<cv::Point2f> src = {{0,0},{WIDTH,0},{WIDTH,HEIGHT},{0,HEIGHT}}; |
|
|
|
|
vector<cv::Point2f> dst = {{WIDTH/3,0},{WIDTH/1.5,0},{WIDTH,HEIGHT},{0,HEIGHT}}; |
|
|
|
|
cv::Mat M = cv::getPerspectiveTransform(src, dst); |
|
|
|
|
|
|
|
|
|
//Frame count.
|
|
|
|
|
size_t cnt = 0; |
|
|
|
|
//Y-position of the current line in pixels.
|
|
|
|
|
float y; |
|
|
|
|
|
|
|
|
|
while (true) { |
|
|
|
|
y = 0; |
|
|
|
|
|
|
|
|
|
//Activate the OpenCL context for OpenGL
|
|
|
|
|
//Activate the OpenCL context for OpenGL.
|
|
|
|
|
gl::bind(); |
|
|
|
|
//Render using nanovg
|
|
|
|
|
//Begin a nanovg frame.
|
|
|
|
|
nvg::begin(); |
|
|
|
|
//Clear the screen with black. The clear color can be specified.
|
|
|
|
|
nvg::clear(); |
|
|
|
|
{ |
|
|
|
|
using kb::nvg::vg; |
|
|
|
@ -75,54 +89,67 @@ int main(int argc, char **argv) { |
|
|
|
|
nvgFillColor(vg, nvgHSLA(0.15, 1, 0.5, 255)); |
|
|
|
|
nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_TOP); |
|
|
|
|
|
|
|
|
|
//only draw lines that are visible
|
|
|
|
|
/** only draw lines that are visible **/ |
|
|
|
|
|
|
|
|
|
//Progress measured in lines.
|
|
|
|
|
off_t progressLines = cnt / FONT_SIZE; |
|
|
|
|
//How many lines to skip.
|
|
|
|
|
off_t skipLines = (numLines - progressLines) - 1; |
|
|
|
|
skipLines = skipLines < 0 ? 0 : skipLines; |
|
|
|
|
off_t maxLines = HEIGHT / FONT_SIZE; |
|
|
|
|
off_t translateY = cnt - (numLines - skipLines) * FONT_SIZE; |
|
|
|
|
//How many lines fit on the page.
|
|
|
|
|
off_t pageLines = HEIGHT / FONT_SIZE; |
|
|
|
|
//How many pixels to translate the text down.
|
|
|
|
|
off_t translateY = cnt - ((numLines - skipLines) * FONT_SIZE); |
|
|
|
|
nvgTranslate(vg, 0, translateY); |
|
|
|
|
|
|
|
|
|
for (std::string line; std::getline(iss, line); ) { |
|
|
|
|
//Check if all yet-to-crawl lines have been skipped.
|
|
|
|
|
if(skipLines == 0) { |
|
|
|
|
if(((translateY + y) / FONT_SIZE) < maxLines) { |
|
|
|
|
//Check if the current lines fits in the page.
|
|
|
|
|
if(((translateY + y) / FONT_SIZE) < pageLines) { |
|
|
|
|
nvgText(vg, WIDTH/2.0, y, line.c_str(), line.c_str() + line.size()); |
|
|
|
|
y += FONT_SIZE; |
|
|
|
|
} else |
|
|
|
|
} else { |
|
|
|
|
//We can stop reading lines if the current line exceeds the page.
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
--skipLines; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
//End a nanovg frame
|
|
|
|
|
nvg::end(); |
|
|
|
|
|
|
|
|
|
if(y == 0) //nothing drawn, exit
|
|
|
|
|
if(y == 0) { |
|
|
|
|
//Nothing drawn, exit.
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//rewind the istringstream
|
|
|
|
|
//Rewind the istringstream.
|
|
|
|
|
iss.clear(std::stringstream::goodbit); |
|
|
|
|
iss.seekg(0); |
|
|
|
|
|
|
|
|
|
//Aquire frame buffer from OpenGL
|
|
|
|
|
//Aquire frame buffer from OpenGL.
|
|
|
|
|
gl::acquire_from_gl(frameBuffer); |
|
|
|
|
//Fake 3D text effect
|
|
|
|
|
//Pseudo 3D text effect.
|
|
|
|
|
cv::warpPerspective(frameBuffer, frameBuffer, M, videoFrame.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar()); |
|
|
|
|
//Color-conversion from BGRA to RGB. OpenCV/OpenCL.
|
|
|
|
|
cv::cvtColor(frameBuffer, videoFrame, cv::COLOR_BGRA2RGB); |
|
|
|
|
//Transfer buffer ownership back to OpenGL
|
|
|
|
|
//Transfer buffer ownership back to OpenGL.
|
|
|
|
|
gl::release_to_gl(frameBuffer); |
|
|
|
|
|
|
|
|
|
//if x11 is enabled it displays the framebuffer in the native window. returns false if the window was closed.
|
|
|
|
|
//If x11 is enabled it displays the framebuffer in the native window. returns false if the window was closed.
|
|
|
|
|
if(!gl::display()) |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
//Activate the OpenCL context for VAAPI
|
|
|
|
|
//Activate the OpenCL context for VAAPI.
|
|
|
|
|
va::bind(); |
|
|
|
|
//Encode the frame using VAAPI on the GPU.
|
|
|
|
|
writer << videoFrame; |
|
|
|
|
|
|
|
|
|
++cnt; |
|
|
|
|
//Wrap the cnt around if it becomes to big.
|
|
|
|
|
if(cnt == std::numeric_limits<size_t>().max()) |
|
|
|
|
cnt = 1; |
|
|
|
|
|
|
|
|
|