PDA

View Full Version : render-problem with vertexarrays and glDrawArrays



sanstream
06-17-2008, 02:37 AM
At first I'd like to apologize for the vagueness of my question.

I am working on a 3d map data visualization tool for a research institute.

For this tool I have a special class, called Rx3dspace, which handles all the OpenGL calls. My IDE is microsoft visual studio .NET 2003. in which I am developing the tool using OpenGL in MFC (c++).
Fortunately for the ones that don't know MFC, the class does not use it. So it is pure C++ with some STL.

the definition of my class in Rx3dSpace.h


class Rx3dSpace
{
private:
//The two vertexarrays,allocating about 10 MB of space each.
GLfloat colours[40960];//vertexArraySize];
GLfloat vertices[40960];//vertexArraySize];


class ModelData {
public: // each member corresponds to the arguments of glDrawElements(), part of OpenGL.
GLenum mode;
GLint first;
GLsizei count;
};

class Colour {
public:
float r,g,b;
};

int m_selectedModel;
float yRotation; // for rotating arround the x-axis, up-down
float xRotation; // for rotating arround the y-axis, left-right
RxStdGrid <int> m_rawMapData; //For storing tabular arranged map data in RxStdGrid (typedef of a 2D vector);
std::vector<ModelData> m_models; // stores the data relevant for each model to retrieve it from the vertexArray.

void LoadRawData(const char* filename);

public:
Rx3dSpace(void);
~Rx3dSpace(void);

void InitGL(void);
void DrawGLScene(void);
void LoadModel(int model_index);
// Functions to move the map/model along specified axis to a set amount of degrees
void LowerX(void);
void UpY(void);
void LowerY(void);
void UpX(void);

};

And the definitions in Rx3dSpace.cpp:



Rx3dSpace::Rx3dSpace(void)
{
/****No GL calls should be made here, instead call them in the InitGL method****/
xRotation = 0.0f;//start looking downward at the map at a 10 degree angle.
yRotation = 0.0f;
}

Rx3dSpace::~Rx3dSpace(void)
{
// empty out the vertexarray and possibly other stuff.
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

}

void Rx3dSpace::InitGL(void)
{ glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT,0,this->colours);
glVertexPointer(3, GL_FLOAT,0,this->vertices);

m_rawMapData.clear();
LoadRawData("C:\\Documents and Settings\\bpeters\\My Documents\\testdata_3Dmapviewer\\test_Tshape.asc");
//LoadRawData("C:\\Documents and Settings\\bpeters\\My Documents\\testdata_3Dmapviewer\\tun_crop_map.asc");
// Basic Setup:
//
// Set color to use when clearing the background.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //black background.
glClearDepth(1.0f);
// Turn on backface culling, allows removal of polygons that are visible because they are hidden from view
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
// Turn on depth testing
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
/*
// setting lighting i.e. creating the 'sun'
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// setting point of origin for the light
GLfloat lightPosition[]= { -2.0f, 2.0f, 0.0f, 1.0f };
glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);
// setting the diffuse and ambient light:
GLfloat LightAmbient[]= {1.0f, 1.0f, 1.0f, 1.0f}; // To see something in the shadow
GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; // Maximizing diffuseness
GLfloat LightSpecular[] = {0.0f, 0.0f, 0.0f, 0.0f }; // NO shininess!
glLightfv(GL_LIGHT0,GL_AMBIENT,LightAmbient);
glLightfv(GL_LIGHT0,GL_DIFFUSE,LightDiffuse);
glLightfv(GL_LIGHT0,GL_SPECULAR,LightSpecular);

//Set up Color tracking:
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
//glEnable(GL_COLOR_MATERIAL);
glDisable(GL_LIGHTING);
*/
}

void Rx3dSpace::DrawGLScene(void)
{
// Start OpenGL Drawing !!!
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
//glScaled(0.3f,0.3f,0.3f);
glRotatef(xRotation,1.0f,0.0f,0.0f);
glRotatef(yRotation,0.0f,1.0f,0.0f);
glTranslatef(-0.3f,0.0f,0.3f); // re-centers to the center of the object,TODO: the x and z coor have to beautimatically determined
glTranslatef(0.0f,-0.5f,0.0f);
glBegin(GL_LINES); // line showing the angle of the light source
glVertex3f(-2.0f, 2.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glEnd();
//drawQuads(7,7, g_MountDoom);
LoadModel(1);
}


// Public movement methods
/************************************************** ************************
In order for these functions to work a preTranslateMessage needs to be
called form the main window. From this these messages need to be transfered
to the class which handles the WM_KEYDOWN messages for the OpenGL control.
************************************************** *************************/
void Rx3dSpace::LowerY(void)
{
yRotation -=1.0f;
}

void Rx3dSpace::LowerX(void)
{
xRotation -= 1.0f;
}

void Rx3dSpace::UpY(void)
{
yRotation += 1.0f;
}

void Rx3dSpace::UpX(void)
{
xRotation += 1.0f;
}
/************************************************** ***********************
This method loads in raw map data from a file (Idrisi or ArcAscii format).
The data is subsequently stored in the m_rawMapData, which is an object of
the RxStdGrid class from geonamicalib.
************************************************** ***********************/
void Rx3dSpace::LoadRawData(const char * filename)
{
if( ReadIdrisiOrArcAsciiFile(filename,m_rawMapData) )
{
//Enable VertexArrays --> Done in constructor.
//iterate over Grid:
int nCols = m_rawMapData.NCols();
int nRows = m_rawMapData.NRows();
int nVertices = (nRows)*(nCols)* 4;// 3 coordinates for each of the 4 corners of a square
//declaring vertexarrays:
//for colour:
int countVertices = 0;

Colour colour;

for(int col= 0; col < nCols; col++ )
{
for(int row = 0; row < nRows; row++ )
{
int cellValue = m_rawMapData.Get(row,col);

if( cellValue == -9999 ) // No data value, making it blue
{
colour.r=0.0f;
colour.g=0.0f;
colour.b=1.0f;
}
else // Some other data value, making it green
{
colour.r=0.0f;
colour.g=1.0f;
colour.b=0.0f;
}
colours[countVertices] = colour.r; //R
colours[countVertices+1] = colour.g; //G
colours[countVertices+2] = colour.b; //B
vertices[countVertices] = (float)(row/10.0f); //X
vertices[countVertices+1] = 0.0f; //Y
vertices[countVertices+2] = (float)(-col/10.0f); //Z
countVertices+=3;// move over to next vextex triplet

colours[countVertices] = colour.r; //R
colours[countVertices+1] = colour.g; //G
colours[countVertices+2] = colour.b; //B
vertices[countVertices] = (float)((row+1)/10.0f); //X
vertices[countVertices+1] = 0.0f; //Y
vertices[countVertices+2] = (float)(-col/10.0f); //Z
countVertices+=3;// move over to next vextex triplet

colours[countVertices] = colour.r; //R
colours[countVertices+1] = colour.g; //G
colours[countVertices+2] = colour.b; //B
vertices[countVertices] = (float)((row+1)/10.0f); //X
vertices[countVertices+1] = 0.0f; //Y
vertices[countVertices+2] = (float)((-col+1)/10.0f);//Z
countVertices+=3;// move over to next vextex triplet

colours[countVertices] = colour.r; //R
colours[countVertices+1] = colour.g; //G
colours[countVertices+2] = colour.b; //B
vertices[countVertices] = (float)(row/10.0f); //X
vertices[countVertices+1] = 0.0f; //Y
vertices[countVertices+2] = (float)((-col+1)/10.0f);//Z
countVertices+=3;// move over to next vextex triplet
}
}
/*
get height map data
get additional map data
Get colourscheme
combine map datasets --> height data becomes y coordinate of the center of a square polygon
and the additional data is used for colouring.
----------------------------------*/
//Storing model data in a list of models, so it can be rendered using glDrawArrays():
ModelData data;
data.mode = GL_QUADS;
data.first = 0; // hard coded for now
data.count = nVertices;
m_models.push_back(data);
}
}


void Rx3dSpace::LoadModel(int model_index)
{
glDrawArrays(GL_QUADS, m_models[model_index].first,m_models[model_index].count);
}


When OpenGl is to be initialized InitGL is called. In this method a file is read containing map data (e.g. height or population density).

After that when a scene has to be drawn DrawGLScene is called.
For the rendering of the 3d map I have chosen to use vertex arrays(see InitGL and the class definition)for vertex data storage and to draw the vertices with glDrawArrays (called in the LoadModel method). But somehow the map is not rendered.
i am completely mystified how this is possible..

Can someone point out my silly mistake?

-NiCo-
06-17-2008, 03:00 AM
Are you sure the data is located within your view frustum? Where do you set GL_PROJECTION?