OpenGL in Haiku - glaux and Textures

So I was able to download the BeOS code for Lesson 4 from NeHe, and I was able to successfully compile the code in Palidin and run the program in Haiku. So phase 1 of getting a small OpenGL app to compile and run is completed.

The question I have is how are textures loaded in OpenGL for HaikuOS? In NeHe Lesson 6 for loading textures, these lines wouldn’t compile:

#include <gl\glaux.h>
AUX_RGBImageRec *TextureImage[1];
TextureImage[0]=LoadBMP(“Data/NeHe.bmp”);

These 3 lines (and only these 3 lines) were added at the appropriate places in the code from Lesson 4. The compiler can’t find glaux.h.

I couldn’t find “glaux” in the Paladin menu under “Project/Change System Libraries”. Do I need to download GLaux from somewhere or does Haiku use a different library for loading BMP, PNG images for OpenGL?

Thanks.

Sorry,

“include” above is supposed to be: #include < glaux.h >

From what I’ve discovered, it seems GLAUX is discontinued, look here: https://www.khronos.org/opengl/wiki/Image_Libraries#GLAUX
Coincidently, it actually mentions the NeHe lessons.:relaxed:

@CodeforEvolution, thanks for the reply and link.

I downloaded the Linux version of Lesson 6 and it didn’t have GLAUX. The Linux version loads the BMP with a “quick and dirty bitmap loader…for 24 bit bitmaps with 1 plane only” that’s part of the code. I was able to compile and run that lesson on Linux but the same code renders a blank window in Haiku.

So now I’ve encountered another problem with my OpenGL experiment on Haiku.

I kept getting an empty OpenGL rendering when attempting to texture a GL_QUAD, so I tried to only draw a GL_QUAD with glColor3f but Haiku still won’t draw the GL_QUAD. Haiku will draw a 3D triangle with GL_POLYGON but not a box with GL_QUAD.

On Linux using the same code, I am successfully able to draw a GL_QUAD with glColor3f and with texturing.

Does OpenGL on Haiku have a bug or a limitation with GL_QUAD (specifically glBegin(GL_QUADS)…glEnd())?

Hard to tell without seeing your code.
You can always open a bug ticket on dev.haiku-os.org if you catch something looking like a bug.

IIRC, GL_QUAD are actually two QL_TRIANGLES internally. And QL_QUAD API was removed since OpenGL 3.1+.
It doesn’t explain why the same code works fine under Linux and not under Haiku, but first report the OpenGL version you have on both sides, and maybe there is some backward code path in Mesa we didn’t enable on Haiku.

At least we would need to know if you are building with gcc2 (and using an old Mesa maintained by Haiku), or gcc5 (and using a more recent mesa from upstream sources). The latter should be closer to what Linux is doing.

Haiku Specs:

  • OS Version Walter (Revision hrev51176) x86_gcc2
  • Kernel: May 22, 2017 at 5:45:16 PM
  • Processor: Intel Core i7-3770 3.39GHz (Virtual in Oracle VM)
  • Mesa version: two are showing as Active in HaikuDepot: “mesa_x86” v10.1.0-2 and “mesa” v7.9.2-10" so I’m not sure which one the system is using. Should I remove one of them and if so, then which one?
  • GCC versions showing Active in HaikuDepot: gcc v2.95.3_2014_10_14-4 and gcc_x86 v5.4.0_2016_06_04-1.
  • Compiling App: Paladin v 1.4 d1. I unsure which compiler Paladin is using. I checked the Menu items but can’t find which compiler (gcc2 or gcc5) it’s using. When I type “gcc --version” in Terminal, it shows “2.95.3-haiku-2014_07_26” so I guess Paladin is using gcc2. Any way to change from gcc2 to gcc5 other than uninstalling gcc2 in HaikuDepot?

If GL_QUAD is no longer used in OGL 3.1+, then I may drop that part in the code and try using GL_POLYGON instead.

Thanks for the help!

Here’s the code… There’s no BView yet as I was just trying to get OpenGL to run on Haiku, then I was going to put it into a BView/BApp.

//
#include <GL/glut.h>    // Header File For The GLUT Library 
#include <GL/gl.h>	// Header File For The OpenGL32 Library
#include <GL/glu.h>	// Header File For The GLu32 Library
#include <unistd.h>     // needed to sleep

/* ASCII code for the escape key. */
#define ESCAPE 27

/* The number of our GLUT window */
int window; 

/* rotation angle for the triangle. */
float rtri = 0.0f;

/* rotation angle for the quadrilateral. */
float rquad = 0.0f;

/* A general OpenGL initialization function.  Sets all of the initial parameters. */
void InitGL(int Width, int Height)	        // We call this right after our OpenGL window is created.
{
  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);		// This Will Clear The Background Color To Black
  glClearDepth(1.0);				// Enables Clearing Of The Depth Buffer
  glDepthFunc(GL_LESS);			        // The Type Of Depth Test To Do
  glEnable(GL_DEPTH_TEST);		        // Enables Depth Testing
  glShadeModel(GL_SMOOTH);			// Enables Smooth Color Shading

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();				// Reset The Projection Matrix

  gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);	// Calculate The Aspect Ratio Of The Window

  glMatrixMode(GL_MODELVIEW);
}

/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
void ReSizeGLScene(int Width, int Height)
{
  if (Height==0)				// Prevent A Divide By Zero If The Window Is Too Small
    Height=1;

  glViewport(0, 0, Width, Height);		// Reset The Current Viewport And Perspective Transformation

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
  glMatrixMode(GL_MODELVIEW);
}

/* The main drawing function. */
void DrawGLScene()
{
  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
  glLoadIdentity();				// Reset The View

  glTranslatef(-1.5f,0.0f,-6.0f);		// Move Left 1.5 Units And Into The Screen 6.0
	
  glRotatef(rtri,0.0f,1.0f,0.0f);		// Rotate The Pyramid On The Y axis 

  // draw a pyramid (in smooth coloring mode)
  glBegin(GL_POLYGON);				// start drawing a pyramid

  // front face of pyramid
  glColor3f(1.0f,0.0f,0.0f);			// Set The Color To Red
  glVertex3f(0.0f, 1.0f, 0.0f);		        // Top of triangle (front)
  glColor3f(0.0f,1.0f,0.0f);			// Set The Color To Green
  glVertex3f(-1.0f,-1.0f, 1.0f);		// left of triangle (front)
  glColor3f(0.0f,0.0f,1.0f);			// Set The Color To Blue
  glVertex3f(1.0f,-1.0f, 1.0f);		        // right of traingle (front)	

  // right face of pyramid
  glColor3f(1.0f,0.0f,0.0f);			// Red
  glVertex3f( 0.0f, 1.0f, 0.0f);		// Top Of Triangle (Right)
  glColor3f(0.0f,0.0f,1.0f);			// Blue
  glVertex3f( 1.0f,-1.0f, 1.0f);		// Left Of Triangle (Right)
  glColor3f(0.0f,1.0f,0.0f);			// Green
  glVertex3f( 1.0f,-1.0f, -1.0f);		// Right Of Triangle (Right)

  // back face of pyramid
  glColor3f(1.0f,0.0f,0.0f);			// Red
  glVertex3f( 0.0f, 1.0f, 0.0f);		// Top Of Triangle (Back)
  glColor3f(0.0f,1.0f,0.0f);			// Green
  glVertex3f( 1.0f,-1.0f, -1.0f);		// Left Of Triangle (Back)
  glColor3f(0.0f,0.0f,1.0f);			// Blue
  glVertex3f(-1.0f,-1.0f, -1.0f);		// Right Of Triangle (Back)

  // left face of pyramid.
  glColor3f(1.0f,0.0f,0.0f);			// Red
  glVertex3f( 0.0f, 1.0f, 0.0f);		// Top Of Triangle (Left)
  glColor3f(0.0f,0.0f,1.0f);			// Blue
  glVertex3f(-1.0f,-1.0f,-1.0f);		// Left Of Triangle (Left)
  glColor3f(0.0f,1.0f,0.0f);			// Green
  glVertex3f(-1.0f,-1.0f, 1.0f);		// Right Of Triangle (Left)

  glEnd();					// Done Drawing The Pyramid

  glLoadIdentity();				// make sure we're no longer rotated.
  glTranslatef(1.5f,0.0f,-7.0f);		// Move Right 3 Units, and back into the screen 7
	
  glRotatef(rquad,1.0f,1.0f,1.0f);		// Rotate The Cube On X, Y, and Z

  // draw a cube (6 quadrilaterals)
  glBegin(GL_QUADS);				// start drawing the cube.
  
  // top of cube
  glColor3f(0.0f,1.0f,0.0f);			// Set The Color To Blue
  glVertex3f( 1.0f, 1.0f,-1.0f);		// Top Right Of The Quad (Top)
  glVertex3f(-1.0f, 1.0f,-1.0f);		// Top Left Of The Quad (Top)
  glVertex3f(-1.0f, 1.0f, 1.0f);		// Bottom Left Of The Quad (Top)
  glVertex3f( 1.0f, 1.0f, 1.0f);		// Bottom Right Of The Quad (Top)

  // bottom of cube
  glColor3f(1.0f,0.5f,0.0f);			// Set The Color To Orange
  glVertex3f( 1.0f,-1.0f, 1.0f);		// Top Right Of The Quad (Bottom)
  glVertex3f(-1.0f,-1.0f, 1.0f);		// Top Left Of The Quad (Bottom)
  glVertex3f(-1.0f,-1.0f,-1.0f);		// Bottom Left Of The Quad (Bottom)
  glVertex3f( 1.0f,-1.0f,-1.0f);		// Bottom Right Of The Quad (Bottom)

  // front of cube
  glColor3f(1.0f,0.0f,0.0f);			// Set The Color To Red
  glVertex3f( 1.0f, 1.0f, 1.0f);		// Top Right Of The Quad (Front)
  glVertex3f(-1.0f, 1.0f, 1.0f);		// Top Left Of The Quad (Front)
  glVertex3f(-1.0f,-1.0f, 1.0f);		// Bottom Left Of The Quad (Front)
  glVertex3f( 1.0f,-1.0f, 1.0f);		// Bottom Right Of The Quad (Front)

  // back of cube.
  glColor3f(1.0f,1.0f,0.0f);			// Set The Color To Yellow
  glVertex3f( 1.0f,-1.0f,-1.0f);		// Top Right Of The Quad (Back)
  glVertex3f(-1.0f,-1.0f,-1.0f);		// Top Left Of The Quad (Back)
  glVertex3f(-1.0f, 1.0f,-1.0f);		// Bottom Left Of The Quad (Back)
  glVertex3f( 1.0f, 1.0f,-1.0f);		// Bottom Right Of The Quad (Back)

  // left of cube
  glColor3f(0.0f,0.0f,1.0f);			// Blue
  glVertex3f(-1.0f, 1.0f, 1.0f);		// Top Right Of The Quad (Left)
  glVertex3f(-1.0f, 1.0f,-1.0f);		// Top Left Of The Quad (Left)
  glVertex3f(-1.0f,-1.0f,-1.0f);		// Bottom Left Of The Quad (Left)
  glVertex3f(-1.0f,-1.0f, 1.0f);		// Bottom Right Of The Quad (Left)

  // Right of cube
  glColor3f(1.0f,0.0f,1.0f);			// Set The Color To Violet
  glVertex3f( 1.0f, 1.0f,-1.0f);	        // Top Right Of The Quad (Right)
  glVertex3f( 1.0f, 1.0f, 1.0f);		// Top Left Of The Quad (Right)
  glVertex3f( 1.0f,-1.0f, 1.0f);		// Bottom Left Of The Quad (Right)
  glVertex3f( 1.0f,-1.0f,-1.0f);		// Bottom Right Of The Quad (Right)
  glEnd();					// Done Drawing The Cube

  rtri+=1.0f;					// Increase The Rotation Variable For The Pyramid
  rquad-=1.0f;					// Decrease The Rotation Variable For The Cube

  // swap the buffers to display, since double buffering is used.
  glutSwapBuffers();
}

/* The function called whenever a key is pressed. */
void keyPressed(unsigned char key, int x, int y) 
{
    /* avoid thrashing this call */
    usleep(100);

    /* If escape is pressed, kill everything. */
    if (key == ESCAPE) 
    { 
      /* shut down our window */
      glutDestroyWindow(window); 
      
      /* exit the program...normal termination. */
      exit(0);                   
    }
}

int main(int argc, char **argv) 
{  
  /* Initialize GLUT state - glut will take any command line arguments that pertain to it or 
     X Windows - look at its documentation at http://reality.sgi.com/mjk/spec3/spec3.html */  
  glutInit(&argc, argv);  

  /* Select type of Display mode:   
     Double buffer 
     RGBA color
     Alpha components supported 
     Depth buffered for automatic clipping */  
  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);  

  /* get a 640 x 480 window */
  glutInitWindowSize(800, 600);  

  /* the window starts at the upper left corner of the screen */
  //glutInitWindowPosition(0, 0);  

  /* Open a window */  
  window = glutCreateWindow("OpenGL HaikuOS");  

  /* Register the function to do all our OpenGL drawing. */
  glutDisplayFunc(&DrawGLScene);  

  /* Go fullscreen.  This is as soon as possible. */
  //glutFullScreen();

  /* Even if there are no events, redraw our gl scene. */
  glutIdleFunc(&DrawGLScene);

  /* Register the function called when our window is resized. */
  glutReshapeFunc(&ReSizeGLScene);

  /* Register the function called when the keyboard is pressed. */
  glutKeyboardFunc(&keyPressed);

  /* Initialize our window. */
  InitGL(800, 600);
  
  /* Start Event Processing Engine */  
  glutMainLoop();  

  return 1;
}

You’d actually want to use a BGLView as it integrates OpenGL into a BView:
https://www.haiku-os.org/legacy-docs/bebook/BGLView.html

Everything in the x86_gcc2 version of Haiku comes in two versions, for gcc2 and gcc5. The gcc5 things are suffixed _x86 in package names so you can easily identify them.

To switch terminal to gcc5, use “setarch x86”. There you get a modern gcc and an up to date Mesa, which could behave closer to Linux versions. The drawback is that this architecture is a moving target, from time to time there will be ABI changes. For the gcc2 part we try to keep things more stable.

I don’t know how to set Paladin to use gcc5.

You’d actually want to use a BGLView as it integrates OpenGL into a BView:

His code is using GLUT, and GLUT uses a BGLView behind the scene.

I don’t know how to set Paladin to use gcc5.

AFAIK, Paladin don’t allow to specify which GCC to use, and just call the active GCC.
So, just run setarch x86 and (re)build with Paladin will use gcc5 I think.

I just try the code under Haiku x86_64 hrev51173 with mesa_swpipe 17.0.2-2 as GL renderer, as it does works as expected: I can see a spining smoothed colors gradiants pyramide near a spinning one-color-per-face cube (so, GL_QUAD are still supported):

As I don’t have a gcc2 hybrid Haiku VM at hand, I can’t tell what wrong with your config, but the good news is that this code could works fine.

Regarding loading image file as a texture, there is sample code in 3dmov source code, in ViewObject.cpp :

It uses Haiku’s translators to convert whatever image format into a BBitmap object, and from there there are few easy steps to publish it as a GL texture.

Oh, ok, I thought he was coding the window and everything from scratch.

I’m curious how one would handle opening a window without the BWindow class somewhere. Since we don’t document the protocol used by app_server, this seems very unlikely to happen. In Haiku, BWindow and BView is as “from scratch” as you can get.

All, I installed “mesa_swpipe 17.0.2-2” via HaikuDepot as phoudoin mentioned, and now it is showing the cube on the right as expected. I tried “setarch x86” and recompiled but that didn’t help. Once I installed the mesa_swpipe software the program ran as expected with a rotating cube. Thanks everyone for your help. Now I can move onward. Many thanks.

Glad to hear that. I guess old mesa 7.9.2 was broken regarding Gl_QUADS or it was when the API was removed officially but its backward support was not yet reintroduced.

Regarding the lack of GLAUX-like function to easily load an image file as a GL texture, I may looks where such thing will make sense today. Or, maybe, we can introduce along BGLView class a BGLTextureLoader utility class too…

@phoudoin, btw, what did you use to compile the code? Do you have an IDE or did you compile in Terminal? If you compiled in terminal, what parameters did you use? I ask because I was wondering if there is a way to compile the code in such a way as to force it to use a certain version of a GL runtime library.