PDA

View Full Version : glDrawElements Problem

Henry Rust
08-14-2010, 11:03 AM
I am actually trying to write a small program using OpenGL which displays the following function: z=sin(sqrt(x² + y²)).

I use a Vertex array to store the vertex data and a indices array to specify the order in which the vertices are drawn.

My problem is that somehow not all vertices are drawn.

My Code so far is:

#include <cmath>
#include <iostream>
#include <GL/glut.h>
#include <GL/freeglut_ext.h>

void init();
void displayFunc();
void reshapeFunc(int w, int h);
void keyFunc(unsigned char key, int x, int y);
GLfloat* accessPoints(unsigned int i, unsigned int j, unsigned int k);
void calcPoints();
void calcIndices();

GLfloat* points;
GLuint* indices;
unsigned int gridLength = 20; //set 20 as default for gridLength

int main(int argc, char* argv[]) {
glutInit(&amp;argc, argv); //init glut
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); //set the display mode
glutInitWindowSize(600, 600); //set the window size
glutInitWindowPosition(0, 0); //set the window position
glutCreateWindow("OpenGL Grid Example"); //set the title of the window
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); //leave the main loop when the window is closed

std::cout << "Gridlength: ";
std::cin >> gridLength;

points = new GLfloat[gridLength * gridLength * 3];
indices = new GLuint[(gridLength - 1) * (gridLength - 1) * 4];
calcPoints();
calcIndices();

init(); //init OpenGL

glutDisplayFunc(&amp;displayFunc); //set the display function
glutReshapeFunc(&amp;reshapeFunc); //set the resize function
glutKeyboardFunc(&amp;keyFunc); //set the key function
glutMainLoop(); //entering the glut main loop<

delete[] points;
delete[] indices;
}

void init() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //set the backcolor to black

glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //really nice perspective correction
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //Draw Polygons in wireframe mode

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, points); //set the vertex pointer to points
}

void displayFunc() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the window and the depth buffer
glTranslatef(0.0f, 0.0f, -20.0f); //move 10 units into the screen

glColor3f(0.0f, 1.0f, 0.0f);
//glRotatef(90.0f, 1.0f, 0.0f, 0.0f);

glDrawElements(GL_QUADS, (gridLength - 1) * (gridLength - 1) * 4, GL_UNSIGNED_INT, indices);

glutSwapBuffers();

//checking for errors
GLenum error = glGetError();
while (error != GL_NO_ERROR) {
std::cerr << "OpenGL error: " << error << std::endl;
error = glGetError();
}
}

void reshapeFunc(int w, int h) {
if (h == 0) { //avoid a dividy by zero
h = 1;
}

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);

gluPerspective(45.0f, (static_cast<GLfloat> (w) / static_cast<GLfloat> (h)), 1.0f, 20.0f);

glMatrixMode(GL_MODELVIEW);
}

void keyFunc(unsigned char key, int x, int y) {
if (key == 'q' || key == 'Q') { //exit the main loop if q is pressed
glutLeaveMainLoop();
}
}

GLfloat* accessPoints(unsigned int i, unsigned int j, unsigned int k) {
unsigned int position = (i * 3) + k + (j * gridLength * 3);
return &amp;points[position];
}

void calcPoints() {
for (size_t x = 0; x < gridLength; ++x) {
for (size_t y = 0; y < gridLength; ++y) {
GLfloat x_value = x - static_cast<GLfloat> (gridLength) / 2.0f;
GLfloat y_value = (gridLength - y) - static_cast<GLfloat> (gridLength) / 2.0f;
//GLfloat z_value = std::sin(std::sqrt(x_value * x_value + y_value * y_value)) * 10;
GLfloat z_value = 0;
GLfloat* xComponentVertexPointer = accessPoints(x, y, 0);
GLfloat* yComponentVertexPointer = accessPoints(x, y, 1);
GLfloat* zComponentVertexPointer = accessPoints(x, y, 2);
*xComponentVertexPointer = x_value;
*yComponentVertexPointer = y_value;
*zComponentVertexPointer = z_value;
}
}
}

void calcIndices() {
GLfloat* start = accessPoints(0, 0, 0);
size_t i = 0;
for (size_t x = 0; x < gridLength - 1; ++x) {
for (size_t y = 0; y < gridLength - 1; ++y) {
GLfloat* current = accessPoints(x, y, 0);
indices[i] = current - start;
++i;

current = accessPoints(x, y + 1, 0);
indices[i] = current - start;
++i;

current = accessPoints(x + 1, y + 1, 0);
indices[i] = current - start;
i++;

current = accessPoints(x + 1, y, 0);
indices[i] = current - start;
i++;
}
}
}

I commented out the line with calculation of the z coordinate for testing.(I'm going to rotate everything around 90 degrees, so z point up and down.) As now the code should draw a grid with the dimensions gridLength * gridLength, but it doesn't. If I change the primitive drawing mode from GL_QUADS to GL_POINTS and use for gridLength the value 2, I see that only two points instead four are drawn.

So I hope for your suggestions.