PDA

View Full Version : redbook multisample example not work (GL_SAMPLE_BUFFERS = 0)



firegun9
02-27-2007, 02:19 PM
Hello,

I want to learn some antialiasing effects, and read it in the red book. I tried the sample program, "multisamp.c," in the book, but I couldn't see any antialiasing from the results.

The query results from
glGetIntegerv(GL_SAMPLE_BUFFERS) and
glGetIntegerv(GL_SAMPLES) are both zeros. I guess that is the reason because according to the book, if the first value is "1," and the second value is greater than "1," then I'll be able to use multisampling.

I am using a ATI mobility 9600 in my laptop. It supports OpenGL 2.0. I also adjust the settings in the control panel to force OpenGL use 2x antialiasing. But it doesn't work.

Here is the code. Any ideas?


#include <stdlib.h>
#include <stdio.h>
#include <GL/glew.h>
#include <GL/glut.h>
static int bgtoggle = 1;
void init(void)
{
static GLint buf[1], sbuf[1];
int i, j;

glClearColor(0.0, 0.0, 0.0, 0.0);
glGetIntegerv (GL_SAMPLE_BUFFERS, buf);
printf ("number of sample buffers is %d\n", buf[0]);
glGetIntegerv (GL_SAMPLES, sbuf);
printf ("number of samples is %d\n", sbuf[0]);

glNewList (1, GL_COMPILE);
for (i = 0; i < 19; i++) {
glPushMatrix();
glRotatef(360.0*(float)i/19.0, 0.0, 0.0, 1.0);
glColor3f (1.0, 1.0, 1.0);
glLineWidth((i%3)+1.0);
glBegin (GL_LINES);
glVertex2f (0.25, 0.05);
glVertex2f (0.9, 0.2);
glEnd ();
glColor3f (0.0, 1.0, 1.0);
glBegin (GL_TRIANGLES);
glVertex2f (0.25, 0.0);
glVertex2f (0.9, 0.0);
glVertex2f (0.875, 0.10);
glEnd ();
glPopMatrix();
}
glEndList ();

glNewList (2, GL_COMPILE);
glColor3f (1.0, 0.5, 0.0);
glBegin (GL_QUADS);
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j++) {
if (((i + j) % 2) == 0) {
glVertex2f (-2.0 + (i * 0.25), -2.0 + (j * 0.25));
glVertex2f (-2.0 + (i * 0.25), -1.75 + (j * 0.25));
glVertex2f (-1.75 + (i * 0.25), -1.75 + (j * 0.25));
glVertex2f (-1.75 + (i * 0.25), -2.0 + (j * 0.25));
}
}
}
glEnd ();
glEndList ();
}


void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);

if (bgtoggle)
glCallList (2);

glEnable (GL_MULTISAMPLE);
glPushMatrix();
glTranslatef (-1.0, 0.0, 0.0);
glCallList (1);
glPopMatrix();

glDisable (GL_MULTISAMPLE);
glPushMatrix();
glTranslatef (1.0, 0.0, 0.0);
glCallList (1);
glPopMatrix();
glutSwapBuffers();
}

void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= (2 * h))
gluOrtho2D (-2.0, 2.0,
-2.0*(GLfloat)h/(GLfloat)w, 2.0*(GLfloat)h/(GLfloat)w);
else
gluOrtho2D (-2.0*(GLfloat)w/(GLfloat)h,
2.0*(GLfloat)w/(GLfloat)h, -2.0, 2.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 'b':
case 'B':
bgtoggle = !bgtoggle;
glutPostRedisplay();
break;
case 27: /* Escape Key */
exit(0);
default:
break;
}
}

int main(int argc, char** argv)
{
glewInit();
glutInit(&amp;argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_MULTISAMPLE);
glutInitWindowSize (600, 300);
glutCreateWindow (argv[0]);
init();
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutDisplayFunc (display);
glutMainLoop();
return 0;
}

Joel de Vahl
02-28-2007, 05:42 AM
One tip could be to initialize GLEW after you have created the window... like the manual says =)

koz
02-28-2007, 11:38 AM
I believe glut's multi-sampling relies on the old GLX_SAMPLE_SGIS extension which your ATI card may not support. Your program needs to ask for a multi-sample visual (Linux) or pixel format (Windows). What platform are you using? I have working examples I can post although they are based on glx/glw, not glut.

It also possible that SDL (http://www.libsdl.org/) may support ms out of the box.

Koz

firegun9
02-28-2007, 02:14 PM
Hi Joel, it doesn't work.

To koz:
I am under windows.

If I don't include glew.h, then there are compilor errors:

.\multisamp.c(75) : error C2065: 'GL_SAMPLE_BUFFERS' : undeclared identifier
.\multisamp.c(77) : error C2065: 'GL_SAMPLES' : undeclared identifier
.\multisamp.c(130) : error C2065: 'GL_MULTISAMPLE' : undeclared identifierSo glew takes care of the multi-sampling thing. Am I right?

koz
02-28-2007, 02:39 PM
//
//
// fsaa.c - Multi-sample example.
//
// cl fsaa.c opengl32.lib gdi32.lib user32.lib
//
#include <windows.h> // standard Windows headers
#include <math.h>
#include <GL/gl.h> // OpenGL interface
#include <GL/glu.h> // OpenGL utility Library interface
//
// You may need to grab the following headers from
// http://www.opengl.org/registry/
//
#include <GL/glext.h>
#include <GL/wglext.h>

LONG WINAPI WndProc(HWND, UINT, WPARAM, LPARAM);
void DrawOpenGLScene(void);
HGLRC SetUpOpenGL(HWND hWnd);

int bestFormat = 0;

//
// Check for an OpenGL extension
//
static GLboolean CheckExtension(char *extName, const char *extString)
{
char *p = (char *)extString;
char *end;
int extNameLen;

extNameLen = strlen(extName);
end = p + strlen(p);

while (p < end) {
int n = strcspn(p, " ");
if ((extNameLen == n) &amp;&amp; (strncmp(extName, p, n) == 0)) {
return GL_TRUE;
}
p += (n + 1);
}
return GL_FALSE;
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow) {
static char szAppName[] = "OpenGL";
static char szTitle[]="FSAA";
WNDCLASS wc;
MSG msg;
HWND hWnd;
HWND hWndGL;

wc.style =
CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc =
(WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance =
hInstance;
wc.hIcon = NULL;
wc.hCursor =
LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground =
(HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName =
szAppName;

RegisterClass( &amp;wc );

//
// Create a temporary window so OpenGL can query the pixel formats
//
hWndGL = CreateWindow(szAppName, szTitle, WS_OVERLAPPEDWINDOW |
WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (!hWndGL) {
return (0);
} else {
SetUpOpenGL(hWndGL);
}

//
// Create a main window for this application instance.
//
hWnd = CreateWindow(szAppName, szTitle, WS_OVERLAPPEDWINDOW |
WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if ( !hWnd ) {
return( 0 );
}

ShowWindow( hWnd, nCmdShow );
UpdateWindow( hWnd );

while (GetMessage(&amp;msg, NULL, 0, 0)) {
TranslateMessage( &amp;msg ); // Translates messages
DispatchMessage( &amp;msg ); // then dispatches
}

return( msg.wParam );
}

LONG WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
HDC hDC;
static HGLRC hRC;
PAINTSTRUCT ps;
GLdouble gldAspect;
GLsizei glnWidth, glnHeight;

switch (msg)
{
case WM_CREATE:
hDC = GetDC(hWnd);
SetPixelFormat(hDC, bestFormat, NULL);
hRC = wglCreateContext(hDC);
ReleaseDC(hWnd, hDC);
return 0;

case WM_SIZE:
hDC = GetDC (hWnd);
wglMakeCurrent (hDC, hRC);

glnWidth = (GLsizei) LOWORD (lParam);
glnHeight = (GLsizei) HIWORD (lParam);
gldAspect =
(GLdouble)glnWidth/(GLdouble)glnHeight;

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 30.0, gldAspect, 1.0, 10.0 );

glViewport( 0, 0, glnWidth, glnHeight );
wglMakeCurrent( NULL, NULL );
ReleaseDC( hWnd, hDC );
return 0;

case WM_PAINT:
hDC = BeginPaint( hWnd, &amp;ps );
wglMakeCurrent( hDC, hRC );

DrawOpenGLScene();
SwapBuffers(hDC);

wglMakeCurrent( NULL, NULL );

EndPaint( hWnd, &amp;ps );
return 0;

case WM_DESTROY:
wglDeleteContext( hRC );
PostQuitMessage( 0 );
return 0;
}

return DefWindowProc( hWnd, msg, wParam, lParam );
}

HGLRC SetUpOpenGL(HWND hWnd) {
static PIXELFORMATDESCRIPTOR pfd = {
sizeof (PIXELFORMATDESCRIPTOR), // strcut size
1, // Version number
PFD_DRAW_TO_WINDOW | // Flags, draw to a window,
PFD_SUPPORT_OPENGL, // use OpenGL
PFD_TYPE_RGBA, // RGBA pixel values
24, // 24-bit color
0, 0, 0, // RGB bits & shift sizes.
0, 0, 0, // Don't care about them
0, 0, // No alpha buffer info
0, 0, 0, 0, 0, // No accumulation buffer
32, // 32-bit depth buffer
0, // No stencil buffer
0, // No auxiliary buffers
PFD_MAIN_PLANE, // Layer type
0, // Reserved (must be 0)
0, // No layer mask
0, // No visible mask
0 // No damage mask
};

int nMyPixelFormatID;
HDC hDC;
HGLRC hRC;
static char myExtension[] = "GL_ARB_multisample";
static char myWglExtension[] = "WGL_ARB_multisample";
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = NULL;
int formatCount = 0;
int attrib[] = { WGL_NUMBER_PIXEL_FORMATS_ARB };
int formatResults[9];
int formatAttribs[9] = { WGL_SUPPORT_OPENGL_ARB,
WGL_ACCELERATION_ARB,
WGL_DRAW_TO_WINDOW_ARB,
WGL_DOUBLE_BUFFER_ARB,
WGL_PIXEL_TYPE_ARB,
WGL_DEPTH_BITS_ARB,
WGL_STENCIL_BITS_ARB,
WGL_SAMPLE_BUFFERS_ARB,
WGL_SAMPLES_ARB };
int i, j;
int maxSamples = 0;
int depth = 0;
int stencil = 0;

hDC = GetDC( hWnd );
nMyPixelFormatID = ChoosePixelFormat( hDC, &amp;pfd );

SetPixelFormat( hDC, nMyPixelFormatID, &amp;pfd );

hRC = wglCreateContext( hDC );

//
// Extension check
//
wglMakeCurrent(hDC, hRC);
if(CheckExtension(myExtension,
glGetString(GL_EXTENSIONS))){
printf("%s is supported\n", myExtension);
}
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
wglGetProcAddress("wglGetExtensionsStringARB");

if(CheckExtension(myWglExtension,
wglGetExtensionsStringARB(hDC))){
printf("%s is supported\n", myWglExtension);
}
if(CheckExtension("WGL_ARB_pixel_format",
wglGetExtensionsStringARB(hDC)))
if(wglGetPixelFormatAttribivARB == NULL)
wglGetPixelFormatAttribivARB =
(PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
wglGetProcAddress("wglGetPixelFormatAttribivARB");

wglGetPixelFormatAttribivARB(hDC, 1, 0, 1, attrib, &amp;formatCount);

for(i=0;i<formatCount;i+=1) {
wglGetPixelFormatAttribivARB(hDC, i+1, 0, 9,
formatAttribs, formatResults);
//
// Find the best double buffered fsaa pixel format with z.
//
if(formatResults[3] &amp;&amp; (formatResults[8] > maxSamples)) {
maxSamples = formatResults[8];
depth = formatResults[5];
stencil = formatResults[6];
bestFormat = i+1;
}
}
if(maxSamples > 0) {
printf("Pixel format: \n id = %d, z = %d, stencil = %d, samples = %d\n", bestFormat, depth, stencil, maxSamples);
_flushall();
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
}

ReleaseDC(hWnd, hDC);
return hRC;
}

void drawLines() {

int a;
float r;

for(a=0; a<360; a+=8) {
glBegin(GL_LINES);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
r = 3.1459 * a / 180.0;
glVertex3f(sin(r), cos(r), 0.0f);
glEnd();
}

}

void DrawOpenGLScene( )
{

glEnable( GL_DEPTH_TEST );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

glTranslatef( 0.0f, 0.0f, -5.0f );

drawLines();

glFlush ();

}

Juan Aranda-Alvarez
09-10-2007, 06:45 AM
Could I see the GLX code for it?, thank you.

Simon Chan
09-12-2007, 09:53 PM
NEHE Lesson 46 is a multsample example.I think you can try it. Since having not encapsulated by glut, maybe it can disclose more detail.

dorbie
09-17-2007, 05:19 PM
You need to create a window with a gl context and make it current to query the wgl extension to request advanced visuals, because the PFD approach is inherently flawed.


wglChoosePixelFormatARB =
(PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");Once you have this pointer you can delete your first window and create a new one and request a gl context with multisample attributes.

Yep it's a pain in the ass but you gotta do it that way to get ChoosePixelFormat and as an API it is inherently useful and brings some normality to visual selection on Windows.