Opengl segfault

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
"); 
   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
"); 
   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
"); 
   mexEvalString("drawnow");

  // Step 2: Setup basic OpenGL setting
  glEnable(GL_DEPTH_TEST);
         mexPrintf("debug2.1
"); 
   mexEvalString("drawnow");
  glDisable(GL_LIGHTING);
           mexPrintf("debug2.2
"); 
   mexEvalString("drawnow");
  glDisable(GL_CULL_FACE);
           mexPrintf("debug2.3
"); 
   mexEvalString("drawnow");
  //glEnable(GL_CULL_FACE);
  //glCullFace(GL_BACK);
  glPolygonMode(GL_FRONT, GL_FILL);
           mexPrintf("debug2.4
"); 
   mexEvalString("drawnow");
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
           mexPrintf("debug2.5
"); 
   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
"); 
   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
"); 
   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
");
  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
"); 
   mexEvalString("drawnow");
  // printf("face done
");

//   // 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
", vertex[0], vertex[1], vertex[2]);
//     vertex+=3;
//   }
//   glEnd();
  
     mexPrintf("debug6
"); 
   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
"); 
   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
");
  } else {
      //mexPrintf("get depth buffer successfully
");
  }
  
       mexPrintf("debug8
"); 
   mexEvalString("drawnow");
  
  //mexPrintf("w = %d, h = %d, bitPerDepth = %d
", 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
"); 
   mexEvalString("drawnow");
} 

Most certainly nothing has been initialized for GL to operate.
But I would suggest to use glut instead of osmesa.

[QUOTE=Silence;1283518]Most certainly nothing has been initialized for GL to operate.
But I would suggest to use glut instead of osmesa.[/QUOTE]

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.

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.

Both OpenGL and GLUT work with the C or C++ programming languages.

Hello,

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

Thank you.

[QUOTE=benburch9;1283511]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
"); 
   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
"); 
   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
"); 
   mexEvalString("drawnow");

  // Step 2: Setup basic OpenGL setting
  glEnable(GL_DEPTH_TEST);
         mexPrintf("debug2.1
"); 
   mexEvalString("drawnow");
  glDisable(GL_LIGHTING);
           mexPrintf("debug2.2
"); 
   mexEvalString("drawnow");
  glDisable(GL_CULL_FACE);
           mexPrintf("debug2.3
"); 
   mexEvalString("drawnow");
  //glEnable(GL_CULL_FACE);
  //glCullFace(GL_BACK);
  glPolygonMode(GL_FRONT, GL_FILL);
           mexPrintf("debug2.4
"); 
   mexEvalString("drawnow");
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
           mexPrintf("debug2.5
"); 
   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
"); 
   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
"); 
   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
");
  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
"); 
   mexEvalString("drawnow");
  // printf("face done
");

//   // 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
", vertex[0], vertex[1], vertex[2]);
//     vertex+=3;
//   }
//   glEnd();
  
     mexPrintf("debug6
"); 
   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
"); 
   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
");
  } else {
      //mexPrintf("get depth buffer successfully
");
  }
  
       mexPrintf("debug8
"); 
   mexEvalString("drawnow");
  
  //mexPrintf("w = %d, h = %d, bitPerDepth = %d
", 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
"); 
   mexEvalString("drawnow");
} 

[/QUOTE]

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.