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].RGBA[0],
cv[first_ptr].RGBA[1],
cv[first_ptr].RGBA[2],
cv[first_ptr].RGBA[3]);
for(int j = 0 ; j < count ; j++)
glVertex3f(cv[first_ptr+j].xyz[0],
cv[first_ptr+j].xyz[1],
cv[first_ptr+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 = 36;
first_ptr = 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
GL 1.0 code in 2014 ? are you serious ? Try to move it to at least GL 2.0 core and then complain.