|
From: Liccese Joe-R. <Joe...@fr...> - 2009-03-18 21:21:12
|
While I can successfully build and run the osmesa_demo.c example and
generate an actual output I've been unsuccessful in doing so when I take
a modified version of NeHe's lesson24 example using OSMesa. I've ensured
that glFinsih() is called but if I actually step into the glFinish
routine that is dispatched (copied below) I see that there is no actual
address associated with ctx->Driver.Finish or for .Flush either (both
contain 0x0) so the call to ctx->Driver.Finish(ctx) is never actually
performed.
void GLAPIENTRY
_mesa_Finish(void)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->Driver.Finish) {
ctx->Driver.Finish(ctx);
}
}
This is my first intro to opengl so I'm certain I'm missing something
obvious but have been unable to determine the cause myself. We're using
OSMesa since we've actually ported openGL to a Freescale DSP in which
there is no windowing system available. Our goal is to benchmark a few
simple text and 2d renderings on this particular architecture.
Any help anyone has on resolving the missing output will be greatly
appreciated. Currently the output when using OSMesa is just a black
background. If we modify this same code using GLUT instead of OSMesa all
works as expected.
============================
The code I'm running is copied below:
============================
#include <stdlib.h>
#include <stdio.h> // Header File For Standard Input /
Output
#include <stdarg.h> // Header File For Variable Argument
Routines
#include <string.h> // Header File For String Management
#include <GL/glut.h>
#include "GL/osmesa.h"
#define SAVE_TARGA
int scroll; // Used For Scrolling The Screen
int maxtokens; // Keeps Track Of The Number Of
Extensions Supported
int swidth; // Scissor Width
int sheight; // Scissor Height
int scrollFlag = 1; // Flag to control text scrolling;
1=resume, 0=suspend
GLuint base; // Base Display List For The Font
typedef struct // Create A Structure
{
GLubyte *imageData; // Image Data (Up To 32 Bits)
GLuint bpp; // Image Color Depth In Bits Per
Pixel.
GLuint width; // Image Width
GLuint height; // Image Height
GLuint texID; // Texture ID Used To Select A Texture
} TextureImage; // Structure Name
TextureImage textures[1]; // Storage For One Texture
#define WIDTH 640
#define HEIGHT 480
bool LoadTGA(TextureImage *texture, char *filename) // Loads A
TGA File Into Memory
{
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; //
Uncompressed TGA Header
GLubyte TGAcompare[12]; // Used To Compare TGA
Header
GLubyte header[6]; // First 6 Useful Bytes From
The Header
GLuint bytesPerPixel; // Holds Number Of Bytes Per
Pixel Used In The TGA File
GLuint imageSize; // Used To Store The Image
Size When Setting Aside Ram
GLuint temp; // Temporary Variable
GLuint type=GL_RGBA; // Set The Default GL Mode
To RBGA (32 BPP)
GLuint i;
FILE *file = fopen(filename, "rb"); // Open The TGA File
// Does File Even Exist?
if( file==NULL ||
// Are There 12 Bytes To Read? Does The Header Match What We
Want?
fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare)
||
memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0
||
// If So Read Next 6 Header Bytes
fread(header,1,sizeof(header),file)!=sizeof(header))
{
if (file == NULL) // Did The File Even Exist? *Added Jim
Strong*
return false; // Return False
else
{
fclose(file); // If Anything Failed, Close The File
return false; // Return False
}
}
// Determine The TGA Width (highbyte*256+lowbyte)
texture->width = header[1] * 256 + header[0];
// Determine The TGA Height (highbyte*256+lowbyte)
texture->height = header[3] * 256 + header[2];
if( texture->width <=0 || // Is The Width Less Than
Or Equal To Zero
texture->height <=0 || // Is The Height Less Than
Or Equal To Zero
(header[4]!=24 && header[4]!=32)) // Is The TGA 24 or 32 Bit?
{
fclose(file); // If Anything Failed,
Close The File
return false; // Return False
}
texture->bpp = header[4]; // Grab The TGA's Bits Per
Pixel (24 or 32)
bytesPerPixel = texture->bpp/8; // Divide By 8 To Get The
Bytes Per Pixel
// Calculate The Memory Required For The TGA Data
imageSize = texture->width*texture->height*bytesPerPixel;
texture->imageData=(GLubyte *)malloc(imageSize); // Reserve Memory
To Hold The TGA Data
if( texture->imageData==NULL || // Does The
Storage Memory Exist?
// Does The Image Size Match The Memory Reserved?
fread(texture->imageData, 1, imageSize, file)!=imageSize)
{
if(texture->imageData!=NULL) // Was Image Data
Loaded
free(texture->imageData); // If So, Release
The Image Data
fclose(file); // Close The File
return false; // Return False
}
for(i=0; i<imageSize; i+=bytesPerPixel) // Loop Through The
Image Data
{
// Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
// Temporarily Store The Value At Image Data 'i'
temp=texture->imageData[i];
// Set The 1st Byte To The Value Of The 3rd Byte
texture->imageData[i] = texture->imageData[i + 2];
// Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
texture->imageData[i + 2] = temp;
}
fclose (file); // Close The
File
// Build A Texture From The Data
glGenTextures(1, &texture[0].texID); // Generate
OpenGL texture IDs
glBindTexture(GL_TEXTURE_2D, texture[0].texID); // Bind Our
Texture
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Linear Filtered
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Linear Filtered
if (texture[0].bpp==24) // Was The
TGA 24 Bits
{
type=GL_RGB; // If So Set
The 'type' To GL_RGB
}
glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width,
texture[0].height,
0, type, GL_UNSIGNED_BYTE, texture[0].imageData);
return true; // Texture
Building Went Ok, Return True
}
GLvoid BuildFont(GLvoid) // Build Our
Font Display List
{
int loop1;
float cx, cy;
base=glGenLists(256); // Creating
256 Display Lists
glBindTexture(GL_TEXTURE_2D, textures[0].texID); // Select
Our Font Texture
for (loop1=0; loop1<256; loop1++) // Loop Through
All 256 Lists
{
cx=(float)(loop1%16)/16.0f; // X Position Of
Current Character
cy=(float)(loop1/16)/16.0f; // Y Position Of
Current Character
glNewList(base+loop1,GL_COMPILE); // Start
Building A List
glBegin(GL_QUADS); // Use A
Quad For Each Character
glTexCoord2f(cx,1.0f-cy-0.0625f); // Texture
Coord (Bottom Left)
glVertex2d(0,16); // Vertex
Coord (Bottom Left)
glTexCoord2f(cx+0.0625f,1.0f-cy-0.0625f); // Texture
Coord (Bottom Right)
glVertex2i(16,16); // Vertex
Coord (Bottom Right)
glTexCoord2f(cx+0.0625f,1.0f-cy-0.001f); // Texture
Coord (Top Right)
glVertex2i(16,0); // Vertex
Coord (Top Right)
glTexCoord2f(cx,1.0f-cy-0.001f); // Texture
Coord (Top Left)
glVertex2i(0,0); // Vertex
Coord (Top Left)
glEnd(); // Done
Building Our Quad (Character)
glTranslated(14,0,0); // Move To
The Right Of The Character
glEndList(); // Done
Building The Display List
} // Loop
Until All 256 Are Built
}
GLvoid KillFont(GLvoid) // Delete The Font From
Memory
{
glDeleteLists(base,256); // Delete All 256 Display
Lists
}
GLvoid glPrint(GLint x, GLint y, int set, const char *fmt, ...) // Where
The Printing Happens
{
char text[1024]; // Holds Our String
va_list ap; // Pointer To List Of
Arguments
if (fmt == NULL) // If There's No Text
return; // Do Nothing
va_start(ap, fmt); // Parses The String For
Variables
vsprintf(text, fmt, ap); // And Converts Symbols To
Actual Numbers
va_end(ap); // Results Are Stored In
Text
if (set>1) // Did User Choose An
Invalid Character Set?
{
set=1; // If So, Select Set 1
(Italic)
}
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glLoadIdentity(); // Reset The Modelview
Matrix
glTranslated(x,y,0); // Position The Text (0,0 -
Top Left)
glListBase(base-32+(128*set)); // Choose The Font Set (0 or
1)
glScalef(1.0f,2.0f,1.0f); // Make The Text 2X Taller
glCallLists(strlen(text),GL_UNSIGNED_BYTE, text); // Write The
Text To The Screen
glDisable(GL_TEXTURE_2D); // Disable
Texture Mapping
}
void Resize(int width, int height) // Resize And Initialize The
GL Window
{
swidth=width; // Set Scissor Width To
Window Width
sheight=height; // Set Scissor Height To
Window Height
if (height==0) // Prevent A Divide By Zero
By
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current
Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection
Matrix
glLoadIdentity(); // Reset The Projection
Matrix
glOrtho(0.0f,WIDTH,HEIGHT,0.0f,-1.0f,1.0f); // Create Ortho 640x480
View (0,0 At Top Left)
glMatrixMode(GL_MODELVIEW); // Select The Modelview
Matrix
glLoadIdentity(); // Reset The Modelview
Matrix
}
int InitGL() // All Setup For OpenGL
Goes Here
{
if (!LoadTGA(&textures[0],"Font.tga")) // Load The Font
Texture
{
return false; // If Loading Failed,
Return False
}
BuildFont(); // Build The Font
glShadeModel(GL_SMOOTH); // Enable Smooth
Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth
Buffer Setup
glBindTexture(GL_TEXTURE_2D, textures[0].texID); // Select
Our Font Texture
return true; // Initialization Went
OK
}
void DrawGLScene() // Here's Where We Do
All The Drawing
{
char *text;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear
Screen And Depth Buffer
glColor3f(1.0f,0.5f,0.5f); // Set Color To Bright
Red
glPrint(50,16,1,"Renderer"); // Display Renderer
glPrint(80,48,1,"Vendor"); // Display Vendor Name
glPrint(66,80,1,"Version"); // Display Version
glColor3f(1.0f,0.7f,0.4f); // Set Color To Orange
glPrint(200,16,1,(char *)glGetString(GL_RENDERER)); // Display
Renderer
glPrint(200,48,1,(char *)glGetString(GL_VENDOR)); // Display
Vendor Name
glPrint(200,80,1,(char *)glGetString(GL_VERSION)); // Display
Version
glLoadIdentity(); // Reset The ModelView
Matrix
glColor3f(1.0f,1.0f,1.0f); // Set The Color To
White
glBegin(GL_LINE_STRIP); // Start Drawing Line
Strips (Something New)
glVertex2d(639,417); // Top Right Of Bottom
Box
glVertex2d( 0,417); // Top Left Of Bottom
Box
glVertex2d( 0,480); // Lower Left Of Bottom
Box
glVertex2d(639,480); // Lower Right Of
Bottom Box
glVertex2d(639,128); // Up To Bottom Right
Of Top Box
glEnd(); // Done First Line
Strip
glBegin(GL_LINE_STRIP); // Start Drawing
Another Line Strip
glVertex2d( 0,128); // Bottom Left Of Top
Box
glVertex2d(639,128); // Bottom Right Of Top
Box
glVertex2d(639, 1); // Top Right Of Top Box
glVertex2d( 0, 1); // Top Left Of Top Box
glVertex2d( 0,417); // Down To Top Left Of
Bottom Box
glEnd(); // Done Second Line
Strip
// draw 2D square
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
glColor3f(0,1,0);//Change the object colors to green
glBegin(GL_QUADS);//Start drawing quads
glVertex2f(100,100);//first coordinate
glVertex2f(100,170);//second coordinate
glColor3f(0,0,1);//Change the color to blue halfway through to
create a neat color effect
glVertex2f(208,170);//third coordinate (now blue)
glVertex2f(208,100);//last coordinate
glEnd();//Stop drawing quads
// Define Scissor Region
glScissor(2,3,635,75);
glEnable(GL_SCISSOR_TEST); // Enable Scissor
Testing
// Allocate Memory For Our Extension String
text=(char *)malloc(120);
strcpy(text,"Scrolling Text Demo");
maxtokens = strlen(text);
glColor3f(0.5f,1.0f,0.5f); // Set Color To Bright
Green
glColor3f(1.0f,1.0f,0.5f); // Set Color To Yellow
glPrint(1-scroll,400+32,0,text);
glDisable(GL_SCISSOR_TEST); // Disable Scissor
Testing
free(text); // Free Allocated
Memory
glFinish();
return; // Everything Went OK
}
static void
write_targa(const char *filename, const GLubyte *buffer, int width, int
height)
{
FILE *f = fopen( filename, "w" );
if (f) {
int i, x, y;
const GLubyte *ptr = buffer;
printf ("osmesa test, writing tga file \n");
fputc (0x00, f); /* ID Length, 0 => No ID */
fputc (0x00, f); /* Color Map Type, 0 => No color map included */
fputc (0x02, f); /* Image Type, 2 => Uncompressed, True-color
Image */
fputc (0x00, f); /* Next five bytes are about the color map
entries */
fputc (0x00, f); /* 2 bytes Index, 2 bytes length, 1 byte size */
fputc (0x00, f);
fputc (0x00, f);
fputc (0x00, f);
fputc (0x00, f); /* X-origin of Image */
fputc (0x00, f);
fputc (0x00, f); /* Y-origin of Image */
fputc (0x00, f);
fputc (WIDTH & 0xff, f); /* Image Width */
fputc ((WIDTH>>8) & 0xff, f);
fputc (HEIGHT & 0xff, f); /* Image Height */
fputc ((HEIGHT>>8) & 0xff, f);
fputc (0x18, f); /* Pixel Depth, 0x18 => 24 Bits */
fputc (0x20, f); /* Image Descriptor */
fclose(f);
f = fopen( filename, "ab" ); /* reopen in binary append mode */
for (y=height-1; y>=0; y--) {
for (x=0; x<width; x++) {
i = (y*width + x) * 4;
fputc(ptr[i+2], f); /* write blue */
fputc(ptr[i+1], f); /* write green */
fputc(ptr[i], f); /* write red */
}
}
fclose(f);
}
}
int main(int argc, char **argv)
{
OSMesaContext ctx;
void *buffer;
/* Create an RGBA-mode context */
#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
/* specify Z, stencil, accum sizes */
ctx = OSMesaCreateContextExt( OSMESA_RGBA, 16, 0, 0, NULL );
#else
ctx = OSMesaCreateContext( OSMESA_RGBA, NULL );
#endif
if (!ctx) {
printf("OSMesaCreateContext failed!\n");
return 0;
}
/* Allocate the image buffer */
buffer = malloc( WIDTH * HEIGHT * 4 * sizeof(GLubyte) );
if (!buffer) {
printf("Alloc image buffer failed!\n");
return 0;
}
/* Bind the buffer to the context and make it current */
if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, WIDTH, HEIGHT
)) {
printf("OSMesaMakeCurrent failed!\n");
return 0;
}
if(!InitGL()) {
printf("InitGL Failed\n");
exit(0);
}
DrawGLScene();
#ifdef SAVE_TARGA
write_targa("scrolltext.tga", buffer, WIDTH, HEIGHT);
#endif
free( buffer );
OSMesaDestroyContext( ctx );
}
|