OSMesa GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT error when create a multisampling FBO - rendering

I have tried to do offscreen rendering in my linux server(a virtual machine with no graphics card and no window system) by OSMesa, refer to the osmesa demo osdemos. Every thing works fine.
For antialiasing, i tried to create a multisamping render buffer to bind to FBO, but result with GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, the single sampled render buffer works fine.
here is the code to create the FBO, change the sample_number for 1, works fine, for 4 with GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT error. Any suggestions are appricate.
#define GL_GLEXT_PROTOTYPES
#include <GL/glu.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <iostream>
#include "GL/osmesa.h"
#include <GL/glut.h>
const int Width = 1920;
const int Height = 1080;
int main(int argc, char *argv[])
{
OSMesaContext ctx;
void *buffer;
#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
ctx = OSMesaCreateContextExt( OSMESA_RGBA, 32, 0, 0, NULL );
#else
ctx = OSMesaCreateContext( OSMESA_RGBA, NULL );
#endif
if (!ctx) {
printf("OSMesaCreateContext failed!\n");
return 0;
}
buffer = malloc( Width * Height * 4 * sizeof(GLubyte) );
if (!buffer) {
printf("Alloc image buffer failed!\n");
return 0;
}
if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, Width, Height )) {
printf("OSMesaMakeCurrent failed!\n");
return 0;
}
int render_width = 200, render_height = 200;
enum { Color, Depth, NumRenderbuffers };
// multi-sampled frame buffer object as the draw target
GLuint framebuffer_ms, renderbuffer_ms[NumRenderbuffers];
// generate color and depth render buffers and allocate storage for the multi-sampled FBO
glGenRenderbuffers(NumRenderbuffers, renderbuffer_ms);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_ms[Color]);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, // here set 1 works fine
GL_RGBA8, render_width, render_height);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_ms[Depth]);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, // here set 1 works fine
GL_DEPTH_COMPONENT24, render_width, render_height);
// generate frame buffer object for the multi-sampled FBO
glGenFramebuffers(1, &framebuffer_ms);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_ms);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, renderbuffer_ms[Color]);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, renderbuffer_ms[Depth]);
auto status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
if (status == GL_FRAMEBUFFER_COMPLETE) {
std::cout << "fbo status fine!!!" << std::endl;
} else {
std::cout << "Failed:" << status << std::endl;
}
exit(__LINE__);
// render_image();
// std::vector<GLubyte> data(width *height * 4);
// glReadBuffer(GL_COLOR_ATTACHMENT0);
// glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data.data());
// write_targa(data.data(), width, height);
glDeleteFramebuffers(1, &framebuffer_ms);
glDeleteRenderbuffers(2, renderbuffer_ms);
free(buffer);
return 0;
}

Just use the post processing to do anti-aliasing. pp_jimenezmlaa and pp_jimenezmlaaa_color

Related

A problem with the form of converting ply to fbx

We are currently in the process of converting PLY or PCD data to FBX.
I did the conversion using the Assimp library as shown below, but I found a problem with missing colors.
May I know where is wrong?
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <assimp/Exporter.hpp>
#include <System.h>
int main(int argc, char* argv[]) {
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile("/app/test.ply",
aiProcess_Triangulate |
aiProcess_JoinIdenticalVertices |
aiProcess_SortByPType);
// Check that the import was successful
if (!scene) {
std::cerr << "Failed to import file: " << importer.GetErrorString() << std::endl;
return 1;
}
// Iterate over all the meshes in the scene
for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
aiMesh* mesh = scene->mMeshes[i];
// Check if the mesh has color data
if (mesh->HasVertexColors(0)) {
// Set the number of color components to 3 (for RGB)
//mesh->mNumColorComponents = 3;
// Allocate memory for the color data
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
// Fill in the color data (for example, set all vertices to red)
for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
mesh->mColors[0][j].r = 1.0f;
mesh->mColors[0][j].g = 0.0f;
mesh->mColors[0][j].b = 0.0f;
mesh->mColors[0][j].a = 1.0f;
}
}
}
// Export the scene to fbx format
Assimp::Exporter exporter;
exporter.Export(scene, "fbx", "output.fbx");
return 0;
}

Teaching myself OOP in C++

So I've been working on this program for the last month. The original code is from this tutorial https://www.youtube.com/watch?v=KjHKwCZyAhQ&list=PLHm_I0tE5kKPPWXkTTtOn8fkcwEGZNETh&index=3
However, I thought I would turn it into an object oriented program before I went on. Doing rather than copying is the best way to learn. The code generated a bmp file before i divided it up, but not anymore. The program executes but it doesn't create a file. Additionally I added Hello World in my .cpp files to see if they were even being executed and it looks like they aren't. I realize in copying this that I have a lot of code, I think the problem is in the main file so hopefully if anyone is nice enough to help me they can pick it out much more quickly!
*edit
Also in the original code he had the strut as a global variable but wasn't sure which file to implement it in or even how to make something global in an OOP! Would I just put it in main above int main() ?
Output.h
#pragma once
#include "ProProcess.h" //this is just a bunch of preprocessor directives
//this program creats a single color bmp file using red, blue, and green (rgb)
class OutPut
{
public:
OutPut(const int height, std::string file_name, int dpi, int index);
~OutPut();
//savebmp_str(std::string* file_name, const int width, const int height, int dpi, int pixels, struct RGBtype);
//commented this out because I wasn't sure how I should pass all these values. Ultimately I used OutPut Object_Output in bmp.cpp so that these variables could be passed in there
const int Getwidth() { return width; }
const int Setwidth(const int x) { const int width = x; }
private:
struct RGBtype //Could be a global variable but I dont know which file to put it in
{
int r;
int g;
int b;
};
const int width = 1960; //window size
const int height = 1080;
int dpi = 72;
int number_of_pixels = width*height;
int index;
const char* file_name = "Scene.bmp";
RGBtype *pixels = new RGBtype[number_of_pixels];//creates an array so that each pixel is comprised of a mix of rgb
};
Output.cpp
#include "OutPut.h"
#include "ProProcess.h"
OutPut::OutPut(const int height, std::string file_name, int dpi, int index)
{
OutPut::RGBtype color;
for (int x = 0; x < height; x++) //nested for loop that draws out each pixel totalling 1920x1080 in all
{
for (int y = 0; y < width; y++)
{
index = y*height + x;
pixels[index].r = 311;//changing the number here changes the color
pixels[index].g = 311;
pixels[index].b = 311;
}
}
std::cout << "Hello World";
}
OutPut::~OutPut()
{
}
BMP.h
#pragma once
#include "ProProcess.h"
#include "OutPut.h"
struct RGBtype
{
int r;
int g;
int b;
};
class BMP
{
public:
BMP(const char *filename, int passed_width, int passed_height, int dpi, RGBtype* data);
~BMP();
private:
OutPut Object_Output(std::string* file_name, const int width, const int height, int dpi, int pixels, struct RGBtype);//this is to pass the variables declared in output.h so bmp.h and bmp.cpp can use them too. Not sure how I would even verify i am doing this properly!
//const char* savebmp_str();
int passed_width;
int passed_height;
int dpi;
RGBtype *data;
};
BMP.cpp
#include "BMP.h"
#include "ProProcess.h"
#include "OutPut.h"
BMP::BMP(const char *filename, int passed_width, int passed_height, int dpi, RGBtype *data)
{
std::cout << passed_height;
FILE *pFile;
int k = passed_width*passed_height;
std::cout << "The value k is" << k;
int s = 4 * k;
int filesize = 54 + s; //s is a function of width and height
double factor = 39.375;
int m = static_cast<int>(factor);
int ppm = dpi*m;
unsigned char bmpfileheader[14] = { 'B','M',0,0,0,0 ,0,0,0,0, 54,0,0,0 }; //B and M are case sensitive. They make a bmp file
unsigned char bmpinfoheader[40] = { 40,0,0,0, 0,0,0,0 ,0,0,0,0, 1,0,24,0 };// the header size 14 and 40 are part of the BMP format
bmpfileheader[2] = (unsigned char)(filesize);
bmpfileheader[3] = (unsigned char)(filesize >> 8);
bmpfileheader[4] = (unsigned char)(filesize >> 16);
bmpfileheader[5] = (unsigned char)(filesize >> 24);
bmpinfoheader[4] = (unsigned char)(passed_width);
bmpinfoheader[5] = (unsigned char)(passed_width >> 8);
bmpinfoheader[6] = (unsigned char)(passed_width >> 16);
bmpinfoheader[7] = (unsigned char)(passed_width >> 24);
bmpinfoheader[8] = (unsigned char)(passed_height);
bmpinfoheader[9] = (unsigned char)(passed_height >> 8);
bmpinfoheader[10] = (unsigned char)(passed_height >> 16);
bmpinfoheader[11] = (unsigned char)(passed_height >> 24);
bmpinfoheader[21] = (unsigned char)(s);
bmpinfoheader[22] = (unsigned char)(s >> 8);
bmpinfoheader[23] = (unsigned char)(s >> 16);
bmpinfoheader[24] = (unsigned char)(s >> 24);
bmpinfoheader[25] = (unsigned char)(ppm);
bmpinfoheader[26] = (unsigned char)(ppm >> 8);
bmpinfoheader[27] = (unsigned char)(ppm >> 16);
bmpinfoheader[28] = (unsigned char)(ppm >> 24);
bmpinfoheader[29] = (unsigned char)(ppm);
bmpinfoheader[30] = (unsigned char)(ppm >> 8);
bmpinfoheader[31] = (unsigned char)(ppm >> 16);
bmpinfoheader[32] = (unsigned char)(ppm >> 24);
pFile = fopen(filename, "wb");
fwrite(bmpfileheader, sizeof(char), 14, pFile);
fwrite(bmpinfoheader, sizeof(char), 40, pFile);
for (int i = 0; i < k; i++)
{
RGBtype rgb = data[i];
double red = (data[i].r);
double green = (data[i].g);
double blue = (data[i].b);
int color[3] = { (int)floor(blue), (int)floor(green), (int)floor(red) };
fwrite(color, 1, 3, pFile);
}
fclose(pFile);
std::cout << "Hello World";
}
BMP::~BMP()
{
}
main.cpp
#include <iostream>
#include "OutPut.h"
#include "ProProcess.h"
#include "BMP.h"
int main()
{
OutPut Pixel_gen();
BMP BMP_Format_Maker();
OutPut Object_Output();
system("Pause");
return 0;
}

OpenKinect acquire raw depth image

I am trying to use the example code from here.
I have made some changes in order to save the images to the computer. When I read the data in MATLAB it seems like values that should be 0 are set to 2047, and overall it does not seem to be correct when I reconstruct the 3D points using the default intrinsic camera parameters.
What I want to achieve is to save the images so that I can use
img = single(imread(depth.png'))/ 1000
and have the depth values in meters, and pixels with no measurements should be zero.
It is the Kinect V1 by the way.
Here is the code with comments where I have tried to change.
#include "libfreenect.hpp"
#include <iostream>
#include <vector>
#include <cmath>
#include <pthread.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
using namespace cv;
using namespace std;
class myMutex {
public:
myMutex() {
pthread_mutex_init( &m_mutex, NULL );
}
void lock() {
pthread_mutex_lock( &m_mutex );
}
void unlock() {
pthread_mutex_unlock( &m_mutex );
}
private:
pthread_mutex_t m_mutex;
};
// Should one use FREENECT_DEPTH_REGISTERED instead of FREENECT_DEPTH_11BIT?
class MyFreenectDevice : public Freenect::FreenectDevice {
public:
MyFreenectDevice(freenect_context *_ctx, int _index)
: Freenect::FreenectDevice(_ctx, _index), m_buffer_depth(FREENECT_DEPTH_11BIT),
m_buffer_rgb(FREENECT_VIDEO_RGB), m_gamma(2048), m_new_rgb_frame(false),
m_new_depth_frame(false), depthMat(Size(640,480),CV_16UC1),
rgbMat(Size(640,480), CV_8UC3, Scalar(0)),
ownMat(Size(640,480),CV_8UC3,Scalar(0)) {
for( unsigned int i = 0 ; i < 2048 ; i++) {
float v = i/2048.0;
v = std::pow(v, 3)* 6;
m_gamma[i] = v*6*256;
}
}
// Do not call directly even in child
void VideoCallback(void* _rgb, uint32_t timestamp) {
std::cout << "RGB callback" << std::endl;
m_rgb_mutex.lock();
uint8_t* rgb = static_cast<uint8_t*>(_rgb);
rgbMat.data = rgb;
m_new_rgb_frame = true;
m_rgb_mutex.unlock();
};
// Do not call directly even in child
void DepthCallback(void* _depth, uint32_t timestamp) {
std::cout << "Depth callback" << std::endl;
m_depth_mutex.lock();
uint16_t* depth = static_cast<uint16_t*>(_depth);
// Here I use memcpy instead so I can use uint16
// memcpy(depthMat.data,depth,depthMat.rows*depthMat.cols*sizeof(uint16_t));
depthMat.data = (uchar*) depth;
m_new_depth_frame = true;
m_depth_mutex.unlock();
}
bool getVideo(Mat& output) {
m_rgb_mutex.lock();
if(m_new_rgb_frame) {
cv::cvtColor(rgbMat, output, CV_RGB2BGR);
m_new_rgb_frame = false;
m_rgb_mutex.unlock();
return true;
} else {
m_rgb_mutex.unlock();
return false;
}
}
bool getDepth(Mat& output) {
m_depth_mutex.lock();
if(m_new_depth_frame) {
depthMat.copyTo(output);
m_new_depth_frame = false;
m_depth_mutex.unlock();
return true;
} else {
m_depth_mutex.unlock();
return false;
}
}
private:
// Should it be uint16_t instead or even higher?
std::vector<uint8_t> m_buffer_depth;
std::vector<uint8_t> m_buffer_rgb;
std::vector<uint16_t> m_gamma;
Mat depthMat;
Mat rgbMat;
Mat ownMat;
myMutex m_rgb_mutex;
myMutex m_depth_mutex;
bool m_new_rgb_frame;
bool m_new_depth_frame;
};
int main(int argc, char **argv) {
bool die(false);
string filename("snapshot");
string suffix(".png");
int i_snap(0),iter(0);
Mat depthMat(Size(640,480),CV_16UC1);
Mat depthf (Size(640,480),CV_8UC1);
Mat rgbMat(Size(640,480),CV_8UC3,Scalar(0));
Mat ownMat(Size(640,480),CV_8UC3,Scalar(0));
// The next two lines must be changed as Freenect::Freenect
// isn't a template but the method createDevice:
// Freenect::Freenect<MyFreenectDevice> freenect;
// MyFreenectDevice& device = freenect.createDevice(0);
// by these two lines:
Freenect::Freenect freenect;
MyFreenectDevice& device = freenect.createDevice<MyFreenectDevice>(0);
namedWindow("rgb",CV_WINDOW_AUTOSIZE);
namedWindow("depth",CV_WINDOW_AUTOSIZE);
device.startVideo();
device.startDepth();
while (!die) {
device.getVideo(rgbMat);
device.getDepth(depthMat);
// Here I save the depth images
std::ostringstream file;
file << filename << i_snap << suffix;
cv::imwrite(file.str(),depthMat);
cv::imshow("rgb", rgbMat);
depthMat.convertTo(depthf, CV_8UC1, 255.0/2048.0);
cv::imshow("depth",depthf);
if(iter >= 1000) break;
iter++;
}
device.stopVideo();
device.stopDepth();
return 0;
}
Thanks in advance!
Erik
I dont have any experience with OpenKinect in particular; but should your depth buffer be uint16?
std::vector<uint8_t> m_buffer_depth;
Also; for Matlab, do check if the image that you are reading is a uint16 or uint8. If its the latter then convert it to uint16
uint16(imread('depth.png'));
Sorry couldn't help more. Hope this helps.
The values you have are the raw depth values. You need to remap those into MM for the numbers to make sense. Kinect 1 can see up to 10 meters. So I would go with raw_values/2407*10000.
If the values are saturated at 2047, you are probably using the FREENECT_DEPTH_11BIT_PACKED depth format.
For work in Matlab, it is always easier to use FREENECT_DEPTH_MM or FREENECT_DEPTH_REGISTERED.
Enjoy.

XCB - How to set WM_SIZE_HINTS?

I'm writing a minimalistic library for window creation in xcb.
I want to be able to create a non-resizeable window. I found out, that it is possible to give hints to the window manager with:
xcb_void_cookie_t xcb_change_property (xcb_connection_t *c, /* Connection to the X server */
uint8_t mode, /* Property mode */
xcb_window_t window, /* Window */
xcb_atom_t property, /* Property to change */
xcb_atom_t type, /* Type of the property */
uint8_t format, /* Format of the property (8, 16, 32) */
uint32_t data_len, /* Length of the data parameter */
const void *data); /* Data */
I tried to change the WM_NORMAL_HINTS and WM_SIZE_HINTS with this function, but how do I know what data I have to put in the *data parameter? Is the type XCB_ATOM_INTEGER or something else?
If you want to do this without depending on xcb_icccm you can directly change the property.
struct WMSizeHints
{
uint32_t flags;
int32_t x, y;
int32_t width, height;
int32_t min_width, min_height;
int32_t max_width, max_height;
int32_t width_inc, height_inc;
int32_t min_aspect_num, min_aspect_den;
int32_t max_aspect_num, max_aspect_den;
int32_t base_width, base_height;
uint32_t win_gravity;
};
enum WMSizeHintsFlag
{
WM_SIZE_HINT_US_POSITION = 1U << 0,
WM_SIZE_HINT_US_SIZE = 1U << 1,
WM_SIZE_HINT_P_POSITION = 1U << 2,
WM_SIZE_HINT_P_SIZE = 1U << 3,
WM_SIZE_HINT_P_MIN_SIZE = 1U << 4,
WM_SIZE_HINT_P_MAX_SIZE = 1U << 5,
WM_SIZE_HINT_P_RESIZE_INC = 1U << 6,
WM_SIZE_HINT_P_ASPECT = 1U << 7,
WM_SIZE_HINT_BASE_SIZE = 1U << 8,
WM_SIZE_HINT_P_WIN_GRAVITY = 1U << 9
};
struct WMSizeHints hints =
{
.flags = WM_SIZE_HINT_P_WIN_GRAVITY,
.win_gravity = XCB_GRAVITY_STATIC
};
if (centerWindow)
hints.win_gravity = XCB_GRAVITY_CENTER;
else
{
hints.flags |= WM_SIZE_HINT_P_SIZE;
hints.x = x;
hints.y = y;
}
xcb_change_property(xcb, XCB_PROP_MODE_REPLACE, window,
XCB_ATOM_WM_NORMAL_HINTS, XCB_ATOM_WM_SIZE_HINTS,
32, sizeof(struct WMSizeHints) >> 2, &hints);
Here is the solution:
#include <xcb/xcb.h>
#include <xcb/xcb_icccm.h>
#define WIDTH 900
#define HEIGHT 600
int main(){
//...
//Connect to X Server and
//Create a window
//...
xcb_size_hints_t hints;
xcb_icccm_size_hints_set_min_size(&hints, WIDTH, HEIGHT);
xcb_icccm_size_hints_set_max_size(&hints, WIDTH, HEIGHT);
xcb_icccm_set_wm_size_hints(connection, window, XCB_ATOM_WM_NORMAL_HINTS, &hints);
return 0;
}

AABB Tree Constructor function very very slow for std::vector

I found a phenomenon, CGAL AABB tree Constructor function is very very slow for std::vector.
Here is a minimal test code:
Point a(1.0, 0.0, 0.0);
Point b(0.0, 1.0, 0.0);
Point c(0.0, 0.0, 1.0);
std::vector<Triangle> triangles;
for (size_t I=0;I<245000;I++)
{
triangles.push_back(Triangle(a,b,c));
}
// constructs AABB tree
MyTree tree(triangles.begin(),triangles.end());
245000 Primitive, not built, run much slower. I find source:
template<typename Tr>
template<typename ConstPrimitiveIterator, typename ... T>
void AABB_tree<Tr>::insert(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T ... t)
{
set_shared_data(t...);
while(first != beyond)
{
m_primitives.push_back(Primitive(first,t...));
++first;
}
m_need_build = true;
}
I suspect vector push_back function will reallocate memory, but I'm not sure is the reason, So I tried this code:
template<typename Tr>
template<typename ConstPrimitiveIterator, typename ... T>
void AABB_tree<Tr>::insert(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond,
T ... t)
{
set_shared_data(t...);
m_primitives.assign(beyond-first,first);//pre allcate promitives
size_t Index = 0;
while(first != beyond)
{
m_primitives[Index] = Primitive(first,t...);
++first;
++Index;
}
m_need_build = true;
}
The problem solves! I need more advices, and I think this needs to be updated to CGAL source?
==================14-9-18 update ===============
I make an simple test:
#include <iostream>
#include <list>
#include "boost/timer/timer.hpp"
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_triangle_primitive.h>
#include <CGAL/Polyhedron_3.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::FT FT;
typedef K::Ray_3 Ray;
typedef K::Line_3 Line;
typedef K::Point_3 Point;
typedef K::Triangle_3 Triangle;
typedef std::vector<Triangle>::iterator Iterator;
typedef CGAL::AABB_triangle_primitive<K, Iterator> Primitive;
typedef CGAL::AABB_traits<K, Primitive> AABB_triangle_traits;
typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
int main()
{
Point a(1.0, 0.0, 0.0);
Point b(0.0, 1.0, 0.0);
Point c(0.0, 0.0, 1.0);
std::vector<Triangle> triangles;
for (size_t I=0;I<245000;I++)
{
triangles.push_back(Triangle(a,b,c));
}
#define TIMER_SECOND boost::timer::nanosecond_type(1000000000LL)
auto first = triangles.begin();
auto beyond = triangles.end();
boost::timer::cpu_timer CountTimer;
//Test 1
std::vector<Primitive> TestV1;
CountTimer.start();
while(first != beyond)
{
TestV1.push_back(Primitive(first));
++first;
}
std::cout << "Test1 Time:" << CountTimer.elapsed().wall << std::endl;
//Test 2
first = triangles.begin();
beyond = triangles.end();
std::vector<Primitive> TestV2;
CountTimer.start();
TestV2.reserve(std::distance(first,beyond));
while(first != beyond)
{
TestV2.push_back(Primitive(first));
++first;
}
std::cout << "Test2 Time:" << CountTimer.elapsed().wall << std::endl;
system("pause");
return EXIT_SUCCESS;
}
in release mode:
Test1 Time:3426459
Test2 Time:926136
in debug mode:
Test1 Time:503719044580
Test2 Time:224280791