Jump to content
  • Advertisement
Sign in to follow this  
sanstream

OpenGL rendering problem while suing vertex arrays and glDrawArrays

This topic is 3658 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!