This method "glMultiDrawArrays" isn't working properly with the AMD drivers (the same problem occurs with every AMD driver regardless of the operating system 32-64 bit, not including Linux), compared to intel, nvidia and even on my old laptop with SiS MIrage 3+ graphics where this method is working properly.
The AMD graphics cards on which I have tested this method are: HD5670, IGP HD3000 and IGP X1200.
The image on the left show the way it should look compared to the right that presents the bug.
Here is a example code to this bug!
/********************************** * * controls: * F1 - exit * F2 - 1K circles * F3 - 10k * F4 - 100k * F5 - rotate * F6 - switch between glMultiDrawArrays or glVertex3f * F12 - Toggle between fullscreen * **************************************/ #include <stdio.h> #include <time.h> #include <math.h> #include "GL/glew.h" #include "GL/freeglut.h" enum _size_k{C1k = 1000, C10k = 10000, C100k = 100000}; static bool Full_screen = false, isRotation = false, isMulti = true; static int persp = 178, newPersp = 178; static float WindowSizeW = 800; static float WindowSizeH = 600; static int my_case = C1k; static int fps = 0; static clock_t t = 0, _t; struct C4UB_V3F { unsigned char RGBA[4]; float xyz[3]; }; static GLvoid *GraphInterleavedArray; static GLint first_ptr[100000]; static GLsizei count[100000]; GLvoid Display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if(isMulti) glMultiDrawArrays(GL_LINE_LOOP, first_ptr, count, my_case); else{ C4UB_V3F *cv = (C4UB_V3F *) GraphInterleavedArray; for(int i = 0 ; i < my_case ; i++){ glPushMatrix(); glBegin(GL_LINE_LOOP); glColor4ub(cv[first_ptr[i]].RGBA[0], cv[first_ptr[i]].RGBA[1], cv[first_ptr[i]].RGBA[2], cv[first_ptr[i]].RGBA[3]); for(int j = 0 ; j < count[i] ; j++) glVertex3f(cv[first_ptr[i]+j].xyz[0], cv[first_ptr[i]+j].xyz[1], cv[first_ptr[i]+j].xyz[2]); glEnd(); glPopMatrix(); } } glutSwapBuffers(); } GLvoid IdleFunc(void){ _t = clock(); if(_t - t >= 1000){ char text[36] = {0}; sprintf(text, "%dk fps:%d Multi:%s", my_case/1000, fps, (isMulti ? "On" : "Off")); glutSetWindowTitle(text); t = _t; fps = 0; } ++fps; if(isRotation)glRotatef(0.45f, 0.f, 0.f, 0.25f); glutPostRedisplay(); } GLvoid processSpecialKeys(int key, int x, int y) { switch(key) { case GLUT_KEY_F11: break; case GLUT_KEY_F12: if(Full_screen ? Full_screen = false : Full_screen = true)glutFullScreenToggle(); else glutLeaveFullScreen(); break; case GLUT_KEY_UP: break; case GLUT_KEY_DOWN: break; case GLUT_KEY_F1: glutLeaveMainLoop(); break; case GLUT_KEY_F2: my_case = C1k; break; case GLUT_KEY_F3: my_case = C10k; break; case GLUT_KEY_F4: my_case = C100k; break; case GLUT_KEY_F5: isRotation ? isRotation = false : isRotation = true; break; case GLUT_KEY_F6: isMulti ? isMulti = false : isMulti = true; break; default: break; } } GLvoid ZoomInOut(int x, int y){ if(WindowSizeH == 0) WindowSizeH = 1; float ratio = 1.0* WindowSizeW / WindowSizeH; // Reset the coordinate system before modifying glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Set the viewport to be the entire window glViewport(0, 0, WindowSizeW, WindowSizeH); // Set the correct perspective. gluPerspective(persp,ratio,1,1000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0f, 0.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); } GLvoid mouseWheel(int button, int dir, int x, int y){ if (dir < 0 && persp < 178){ newPersp+=2; } else if(dir > 0 && persp > 4){ newPersp-=2; } if(persp != newPersp){ persp = newPersp; ZoomInOut(x, y); } } GLvoid Reshape(int w, int h) { WindowSizeW = w; WindowSizeH = h; // Prevent a divide by zero, when window is too short // (you cant make a window of zero width). if(h == 0) h = 1; float ratio = 1.0* w / h; // Reset the coordinate system before modifying glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Set the viewport to be the entire window //SMenu->AutoViewPort(); glViewport(0, 0, w, h); // Set the correct perspective. gluPerspective(persp,ratio,1,1000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0f , 0.0f, 5.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); } void SpiralOFCircles(void){ size_t s100k = 100000*36*sizeof(C4UB_V3F); GraphInterleavedArray = (GLvoid *) malloc(s100k); C4UB_V3F *g100k = (C4UB_V3F *)GraphInterleavedArray; float v_angle = 2.0 * M_PI/36; float Angle = 2.0 * M_PI/360; int g = 0, var = 59; float x = 0.0f, y = 0.0f; for(int i = 0 ; i < 100000 ; i++){ if(i != 0){ x = (float)(i/var * cos(g*Angle)); y = (float)(i/var * sin(g*Angle)); for(int j = 0 ; j < 36 ; j++){ g100k[i*36+j].RGBA[0] = 0x33; g100k[i*36+j].RGBA[1] = 0x99; g100k[i*36+j].RGBA[2] = 0xFF; g100k[i*36+j].RGBA[3] = 0xFF; g100k[i*36+j].xyz[0] = x + 0.2 * cos(j*v_angle); g100k[i*36+j].xyz[1] = y + 0.2 * sin(j*v_angle); g100k[i*36+j].xyz[2] = 0.0f; } if(g >= 360) g = 0; ++g; } else{ for(int j = 0 ; j < 36 ; j++){ g100k[i*36+j].RGBA[0] = 0x33; g100k[i*36+j].RGBA[1] = 0x99; g100k[i*36+j].RGBA[2] = 0xFF; g100k[i*36+j].RGBA[3] = 0xFF; g100k[i*36+j].xyz[0] = x + 0.2 * cos(j*v_angle); g100k[i*36+j].xyz[1] = y + 0.2 * sin(j*v_angle); g100k[i*36+j].xyz[2] = 0.0f; } } count[i] = 36; first_ptr[i] = i*36; } } GLint InitGraph(int argc, char *argv[]){ GLint window; glutInit(&argc, argv); glutInitWindowSize(800 , 600); glutInitWindowPosition(0,100); glutInitDisplayMode(GLUT_DOUBLE | GLUT_MULTISAMPLE | GLUT_RGBA); window = glutCreateWindow("OGL Sample"); //Init GLEW GLenum err = glewInit(); if (GLEW_OK != err) /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); else fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); glEnable (GL_LINE_SMOOTH); glEnable(GL_POINT_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST); glLineWidth(2.0); glPointSize(10.0); glutMouseWheelFunc(mouseWheel); glutSpecialFunc(processSpecialKeys); glutReshapeFunc(Reshape); glutDisplayFunc(Display); glutIdleFunc(IdleFunc); glInterleavedArrays(GL_C4UB_V3F, 0, GraphInterleavedArray); glutMainLoop(); glutExit(); } int main(int argc, char *argv[]){ SpiralOFCircles(); InitGraph(argc, argv); return 0; }
Message was edited by: Todor Ivanov