PDA

View Full Version : Opengl segfault



benburch9
08-16-2016, 09:33 AM
Hi everyone,

I'm a total opengl noob, and I'm trying to get someone else's code to run for me. Having a segfault I can't figure out.
It's segfault right after debug point 2, on the line:

glEnable(GL_DEPTH_TEST);


glxgears works fine, not sure where I should look to fix this and any help would be hugely appreciated.





//mex RenderMex.cpp -L/opt/X11/lib/ -lOSMesa -I/opt/X11/include/
//mex RenderMex.cpp -lOSMesa -L/usr/local/Matlab/R2013a/sys/opengl/lib/glnxa64/libGL.so.1
#include "mex.h"
#include <GL/osmesa.h>
#include <GL/glu.h>

void uint2uchar(unsigned int in, unsigned char* out){
out[0] = (in & 0x00ff0000) >> 16;
out[1] = (in & 0x0000ff00) >> 8;
out[2] = in & 0x000000ff;
}

unsigned int uchar2uint(unsigned char* in){
unsigned int out = (((unsigned int)(in[0])) << 16) + (((unsigned int)(in[1])) << 8) + ((unsigned int)(in[2]));
return out;
}

// Input:
// arg0: 3x4 Projection matrix,
// arg1: image width,
// arg2: image height,
// arg3: 3xn double vertices matrix,
// arg4: 4xn uint32 face matrix, index from zero
// Output: you will need to transpose the result in Matlab manually
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
mexPrintf("RenderMex\n");
mexEvalString("drawnow");

float m_near = 0.3;
float m_far = 1e8;
int m_level = 0;

int m_linewidth = 1;
int m_pointsize = 1;

double* projection = mxGetPr(prhs[0]); // 3x4 matrix
int m_width = (int)mxGetScalar(prhs[1]);
int m_height = (int)mxGetScalar(prhs[2]);
double* vertex = mxGetPr(prhs[3]); // 3xn double vertices matrix
unsigned int num_vertex = mxGetN(prhs[3]);
unsigned int* face = (unsigned int*) mxGetData(prhs[4]); // 4xn uint32 face matrix
unsigned int num_face = mxGetN(prhs[4]);

mexPrintf("debug1\n");
mexEvalString("drawnow");

// Step 1: setup off-screen mesa's binding
OSMesaContext ctx;
ctx = OSMesaCreateContextExt(OSMESA_RGB, 32, 0, 0, NULL );
unsigned char * pbuffer = new unsigned char [3 * m_width * m_height];
// Bind the buffer to the context and make it current
if (!OSMesaMakeCurrent(ctx, (void*)pbuffer, GL_UNSIGNED_BYTE, m_width, m_height)) {
mexErrMsgTxt("OSMesaMakeCurrent failed!: ");
}
OSMesaPixelStore(OSMESA_Y_UP, 0);

mexPrintf("debug2\n");
mexEvalString("drawnow");

// Step 2: Setup basic OpenGL setting
glEnable(GL_DEPTH_TEST);
mexPrintf("debug2.1\n");
mexEvalString("drawnow");
glDisable(GL_LIGHTING);
mexPrintf("debug2.2\n");
mexEvalString("drawnow");
glDisable(GL_CULL_FACE);
mexPrintf("debug2.3\n");
mexEvalString("drawnow");
//glEnable(GL_CULL_FACE);
//glCullFace(GL_BACK);
glPolygonMode(GL_FRONT, GL_FILL);
mexPrintf("debug2.4\n");
mexEvalString("drawnow");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mexPrintf("debug2.5\n");
mexEvalString("drawnow");
//glClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], 1.0f); // this line seems useless
glViewport(0, 0, m_width, m_height);

mexPrintf("debug3\n");
mexEvalString("drawnow");

// Step 3: Set projection matrices
double scale = (0x0001) << m_level;
double final_matrix[16];

// new way: faster way by reuse computation and symbolic derive. See sym_derive.m to check the math.
double inv_width_scale = 1.0/(m_width*scale);
double inv_height_scale = 1.0/(m_height*scale);
double inv_width_scale_1 =inv_width_scale - 1.0;
double inv_height_scale_1_s = -(inv_height_scale - 1.0);
double inv_width_scale_2 = inv_width_scale*2.0;
double inv_height_scale_2_s = -inv_height_scale*2.0;
double m_far_a_m_near = m_far + m_near;
double m_far_s_m_near = m_far - m_near;
double m_far_d_m_near = m_far_a_m_near/m_far_s_m_near;
final_matrix[ 0]= projection[2+0*3]*inv_width_scale_1 + projection[0+0*3]*inv_width_scale_2;
final_matrix[ 1]= projection[2+0*3]*inv_height_scale_1_s + projection[1+0*3]*inv_height_scale_2_s;
final_matrix[ 2]= projection[2+0*3]*m_far_d_m_near;
final_matrix[ 3]= projection[2+0*3];
final_matrix[ 4]= projection[2+1*3]*inv_width_scale_1 + projection[0+1*3]*inv_width_scale_2;
final_matrix[ 5]= projection[2+1*3]*inv_height_scale_1_s + projection[1+1*3]*inv_height_scale_2_s;
final_matrix[ 6]= projection[2+1*3]*m_far_d_m_near;
final_matrix[ 7]= projection[2+1*3];
final_matrix[ 8]= projection[2+2*3]*inv_width_scale_1 + projection[0+2*3]*inv_width_scale_2;
final_matrix[ 9]= projection[2+2*3]*inv_height_scale_1_s + projection[1+2*3]*inv_height_scale_2_s;
final_matrix[10]= projection[2+2*3]*m_far_d_m_near;
final_matrix[11]= projection[2+2*3];
final_matrix[12]= projection[2+3*3]*inv_width_scale_1 + projection[0+3*3]*inv_width_scale_2;
final_matrix[13]= projection[2+3*3]*inv_height_scale_1_s + projection[1+3*3]*inv_height_scale_2_s;
final_matrix[14]= projection[2+3*3]*m_far_d_m_near - (2*m_far*m_near)/m_far_s_m_near;
final_matrix[15]= projection[2+3*3];

mexPrintf("debug4\n");
mexEvalString("drawnow");

// matrix is ready. use it
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(final_matrix);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Step 3: render the mesh with encoded color from their ID
unsigned char colorBytes[3];
unsigned int base_offset;

// render face
// printf("face begin\n");
base_offset = 1;
for (unsigned int i = 0; i < num_face; ++i) {
uint2uchar(base_offset+i,colorBytes);
glColor3ubv(colorBytes);
glBegin(GL_POLYGON);
glVertex3dv(vertex+3*(*face++));
glVertex3dv(vertex+3*(*face++));
glVertex3dv(vertex+3*(*face++));
glVertex3dv(vertex+3*(*face++));
glEnd();
}

mexPrintf("debug5\n");
mexEvalString("drawnow");
// printf("face done\n");

// // render vertex
// base_offset = 1+num_face;
// glPointSize(m_pointsize);
// glBegin(GL_POINTS);
// for (unsigned int i = 0; i < num_vertex; ++i) {
// uint2uchar(base_offset+i,colorBytes);
// glColor3ubv(colorBytes);
// glVertex3dv(vertex);
// // printf("%lf %lf %lf\n", vertex[0], vertex[1], vertex[2]);
// vertex+=3;
// }
// glEnd();

mexPrintf("debug6\n");
mexEvalString("drawnow");

glFinish(); // done rendering

// Step 5: convert the result from color to interger array
// plhs[0] = mxCreateNumericMatrix(m_width, m_height, mxUINT32_CLASS, mxREAL);
// unsigned int* result = (unsigned int*) mxGetData(plhs[0]);
//
// unsigned int* resultCur = result;
// unsigned int* resultEnd = result + m_width * m_height;
// unsigned char * pbufferCur = pbuffer;
// while(resultCur != resultEnd){
// *resultCur = uchar2uint(pbufferCur);
// pbufferCur += 3;
// ++resultCur;
// }

mexPrintf("debug7\n");
mexEvalString("drawnow");

unsigned int* pDepthBuffer;
GLint outWidth, outHeight, bitPerDepth;
GLboolean ret = OSMesaGetDepthBuffer(ctx, &outWidth, &outHeight, &bitPerDepth, (void**)&pDepthBuffer);
if (ret == GL_FALSE) {
mexPrintf("failed to get depth buffer\n");
} else {
//mexPrintf("get depth buffer successfully\n");
}

mexPrintf("debug8\n");
mexEvalString("drawnow");

//mexPrintf("w = %d, h = %d, bitPerDepth = %d\n", outWidth, outHeight, bitPerDepth);
plhs[0] = mxCreateNumericMatrix((int)outWidth, (int)outHeight, mxUINT32_CLASS, mxREAL);
unsigned int* result = (unsigned int*) mxGetData(plhs[0]);
for(int i=0; i<outWidth*outHeight; i++){
result[i] = pDepthBuffer[i];
}

OSMesaDestroyContext(ctx);
delete [] pbuffer;

mexPrintf("debug9\n");
mexEvalString("drawnow");
}

Silence
08-17-2016, 06:57 AM
Most certainly nothing has been initialized for GL to operate.
But I would suggest to use glut instead of osmesa.

benburch9
08-17-2016, 07:09 AM
Most certainly nothing has been initialized for GL to operate.
But I would suggest to use glut instead of osmesa.


Thank you for the reply! by ideas on what I should do to initialize things? This is someone else's code, so I'm hesitant to make drastic changes. Hypothetically, this was working on their system.

Silence
08-17-2016, 07:41 AM
As said, move from OSMesa to glut. There are plainty of tutorials here and there. See this one for example: http://www.lighthouse3d.com/tutorials/glut-tutorial/ or here: http://www.cs.arizona.edu/classes/cs433/spring02/opengl/

Also, -L/usr/local/Matlab/R2013a/sys/opengl/lib/glnxa64/libGL.so.1 seems a weird location to me.

kaufenpreis
12-04-2016, 03:30 AM
Both OpenGL and GLUT work with the C or C++ programming languages.

advorkin
01-12-2017, 10:06 AM
Hello,

were you able to resolve this? I am seeing a very similar issue.

Thank you.


Hi everyone,

I'm a total opengl noob, and I'm trying to get someone else's code to run for me. Having a segfault I can't figure out.
It's segfault right after debug point 2, on the line:

glEnable(GL_DEPTH_TEST);


glxgears works fine, not sure where I should look to fix this and any help would be hugely appreciated.





//mex RenderMex.cpp -L/opt/X11/lib/ -lOSMesa -I/opt/X11/include/
//mex RenderMex.cpp -lOSMesa -L/usr/local/Matlab/R2013a/sys/opengl/lib/glnxa64/libGL.so.1
#include "mex.h"
#include <GL/osmesa.h>
#include <GL/glu.h>

void uint2uchar(unsigned int in, unsigned char* out){
out[0] = (in & 0x00ff0000) >> 16;
out[1] = (in & 0x0000ff00) >> 8;
out[2] = in & 0x000000ff;
}

unsigned int uchar2uint(unsigned char* in){
unsigned int out = (((unsigned int)(in[0])) << 16) + (((unsigned int)(in[1])) << 8) + ((unsigned int)(in[2]));
return out;
}

// Input:
// arg0: 3x4 Projection matrix,
// arg1: image width,
// arg2: image height,
// arg3: 3xn double vertices matrix,
// arg4: 4xn uint32 face matrix, index from zero
// Output: you will need to transpose the result in Matlab manually
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
mexPrintf("RenderMex\n");
mexEvalString("drawnow");

float m_near = 0.3;
float m_far = 1e8;
int m_level = 0;

int m_linewidth = 1;
int m_pointsize = 1;

double* projection = mxGetPr(prhs[0]); // 3x4 matrix
int m_width = (int)mxGetScalar(prhs[1]);
int m_height = (int)mxGetScalar(prhs[2]);
double* vertex = mxGetPr(prhs[3]); // 3xn double vertices matrix
unsigned int num_vertex = mxGetN(prhs[3]);
unsigned int* face = (unsigned int*) mxGetData(prhs[4]); // 4xn uint32 face matrix
unsigned int num_face = mxGetN(prhs[4]);

mexPrintf("debug1\n");
mexEvalString("drawnow");

// Step 1: setup off-screen mesa's binding
OSMesaContext ctx;
ctx = OSMesaCreateContextExt(OSMESA_RGB, 32, 0, 0, NULL );
unsigned char * pbuffer = new unsigned char [3 * m_width * m_height];
// Bind the buffer to the context and make it current
if (!OSMesaMakeCurrent(ctx, (void*)pbuffer, GL_UNSIGNED_BYTE, m_width, m_height)) {
mexErrMsgTxt("OSMesaMakeCurrent failed!: ");
}
OSMesaPixelStore(OSMESA_Y_UP, 0);

mexPrintf("debug2\n");
mexEvalString("drawnow");

// Step 2: Setup basic OpenGL setting
glEnable(GL_DEPTH_TEST);
mexPrintf("debug2.1\n");
mexEvalString("drawnow");
glDisable(GL_LIGHTING);
mexPrintf("debug2.2\n");
mexEvalString("drawnow");
glDisable(GL_CULL_FACE);
mexPrintf("debug2.3\n");
mexEvalString("drawnow");
//glEnable(GL_CULL_FACE);
//glCullFace(GL_BACK);
glPolygonMode(GL_FRONT, GL_FILL);
mexPrintf("debug2.4\n");
mexEvalString("drawnow");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mexPrintf("debug2.5\n");
mexEvalString("drawnow");
//glClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], 1.0f); // this line seems useless
glViewport(0, 0, m_width, m_height);

mexPrintf("debug3\n");
mexEvalString("drawnow");

// Step 3: Set projection matrices
double scale = (0x0001) << m_level;
double final_matrix[16];

// new way: faster way by reuse computation and symbolic derive. See sym_derive.m to check the math.
double inv_width_scale = 1.0/(m_width*scale);
double inv_height_scale = 1.0/(m_height*scale);
double inv_width_scale_1 =inv_width_scale - 1.0;
double inv_height_scale_1_s = -(inv_height_scale - 1.0);
double inv_width_scale_2 = inv_width_scale*2.0;
double inv_height_scale_2_s = -inv_height_scale*2.0;
double m_far_a_m_near = m_far + m_near;
double m_far_s_m_near = m_far - m_near;
double m_far_d_m_near = m_far_a_m_near/m_far_s_m_near;
final_matrix[ 0]= projection[2+0*3]*inv_width_scale_1 + projection[0+0*3]*inv_width_scale_2;
final_matrix[ 1]= projection[2+0*3]*inv_height_scale_1_s + projection[1+0*3]*inv_height_scale_2_s;
final_matrix[ 2]= projection[2+0*3]*m_far_d_m_near;
final_matrix[ 3]= projection[2+0*3];
final_matrix[ 4]= projection[2+1*3]*inv_width_scale_1 + projection[0+1*3]*inv_width_scale_2;
final_matrix[ 5]= projection[2+1*3]*inv_height_scale_1_s + projection[1+1*3]*inv_height_scale_2_s;
final_matrix[ 6]= projection[2+1*3]*m_far_d_m_near;
final_matrix[ 7]= projection[2+1*3];
final_matrix[ 8]= projection[2+2*3]*inv_width_scale_1 + projection[0+2*3]*inv_width_scale_2;
final_matrix[ 9]= projection[2+2*3]*inv_height_scale_1_s + projection[1+2*3]*inv_height_scale_2_s;
final_matrix[10]= projection[2+2*3]*m_far_d_m_near;
final_matrix[11]= projection[2+2*3];
final_matrix[12]= projection[2+3*3]*inv_width_scale_1 + projection[0+3*3]*inv_width_scale_2;
final_matrix[13]= projection[2+3*3]*inv_height_scale_1_s + projection[1+3*3]*inv_height_scale_2_s;
final_matrix[14]= projection[2+3*3]*m_far_d_m_near - (2*m_far*m_near)/m_far_s_m_near;
final_matrix[15]= projection[2+3*3];

mexPrintf("debug4\n");
mexEvalString("drawnow");

// matrix is ready. use it
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(final_matrix);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Step 3: render the mesh with encoded color from their ID
unsigned char colorBytes[3];
unsigned int base_offset;

// render face
// printf("face begin\n");
base_offset = 1;
for (unsigned int i = 0; i < num_face; ++i) {
uint2uchar(base_offset+i,colorBytes);
glColor3ubv(colorBytes);
glBegin(GL_POLYGON);
glVertex3dv(vertex+3*(*face++));
glVertex3dv(vertex+3*(*face++));
glVertex3dv(vertex+3*(*face++));
glVertex3dv(vertex+3*(*face++));
glEnd();
}

mexPrintf("debug5\n");
mexEvalString("drawnow");
// printf("face done\n");

// // render vertex
// base_offset = 1+num_face;
// glPointSize(m_pointsize);
// glBegin(GL_POINTS);
// for (unsigned int i = 0; i < num_vertex; ++i) {
// uint2uchar(base_offset+i,colorBytes);
// glColor3ubv(colorBytes);
// glVertex3dv(vertex);
// // printf("%lf %lf %lf\n", vertex[0], vertex[1], vertex[2]);
// vertex+=3;
// }
// glEnd();

mexPrintf("debug6\n");
mexEvalString("drawnow");

glFinish(); // done rendering

// Step 5: convert the result from color to interger array
// plhs[0] = mxCreateNumericMatrix(m_width, m_height, mxUINT32_CLASS, mxREAL);
// unsigned int* result = (unsigned int*) mxGetData(plhs[0]);
//
// unsigned int* resultCur = result;
// unsigned int* resultEnd = result + m_width * m_height;
// unsigned char * pbufferCur = pbuffer;
// while(resultCur != resultEnd){
// *resultCur = uchar2uint(pbufferCur);
// pbufferCur += 3;
// ++resultCur;
// }

mexPrintf("debug7\n");
mexEvalString("drawnow");

unsigned int* pDepthBuffer;
GLint outWidth, outHeight, bitPerDepth;
GLboolean ret = OSMesaGetDepthBuffer(ctx, &outWidth, &outHeight, &bitPerDepth, (void**)&pDepthBuffer);
if (ret == GL_FALSE) {
mexPrintf("failed to get depth buffer\n");
} else {
//mexPrintf("get depth buffer successfully\n");
}

mexPrintf("debug8\n");
mexEvalString("drawnow");

//mexPrintf("w = %d, h = %d, bitPerDepth = %d\n", outWidth, outHeight, bitPerDepth);
plhs[0] = mxCreateNumericMatrix((int)outWidth, (int)outHeight, mxUINT32_CLASS, mxREAL);
unsigned int* result = (unsigned int*) mxGetData(plhs[0]);
for(int i=0; i<outWidth*outHeight; i++){
result[i] = pDepthBuffer[i];
}

OSMesaDestroyContext(ctx);
delete [] pbuffer;

mexPrintf("debug9\n");
mexEvalString("drawnow");
}