PDA

View Full Version : Out_of_memory



mcmike
04-09-2014, 04:25 AM
Hi,
I am using windows 8.1. I have run out of memory. It runs out after entering about 1,300,000 triangles. I am using glVertex3d to store the vertices. the video card has several gigabytes of RAM.

Any help gratefully appreciated

mcmike
04-10-2014, 04:14 AM
What other information would you require to give me some clues to solve this problem? 1.3M triangles, from 3.9M vertices the memory used is 15.6Mb. There is 4GB of ram on the video card.

Dark Photon
04-10-2014, 06:07 AM
How do you know you are out of memory?

glVertex3d (old-style immediate mode call) typically doesn't store vertices. It merely registers them into the current batch. The exception is if you are capturing these into a display list. Are you?

Let's see some code or provide more details. If you're doing nothing else with GPU memory, you should have more than enough, even if you were uploading all of these triangles into VBOs on the GPU.

mcmike
04-13-2014, 09:57 AM
Thank you.

Yes I am putting the vertices in a display list.
Some code:


GLvoid CompileTriangles( HWND hwnd)
{
UINT uiI = 0;
COORDINATE cdTrnsfrmd[3] = { 0 };
GLdouble gldVertex1[3] = {0},
gldVertex2[3] = {0},
gldVertex3[3] = {0},
gldNorm[3] = {0},
gldColour3[3] = {0},
gldColorPercent = 0.0;
XYZ dXyz = {0};
GLenum errCode;
char cError80[80] = {0};
const GLubyte *errString;


do{
if( Triangles[uiI].cOK!='n' )
{


cdTrnsfrmd[0].dEast = cdCoords[Triangles[uiI].iCoordNo1].dEast - dMinEast;
cdTrnsfrmd[0].dNorth = cdCoords[Triangles[uiI].iCoordNo1].dNorth - dMinNorth;
cdTrnsfrmd[0].dElev = cdCoords[Triangles[uiI].iCoordNo1].dElev - dMinElev;

cdTrnsfrmd[1].dEast = cdCoords[Triangles[uiI].iCoordNo2].dEast - dMinEast;
cdTrnsfrmd[1].dNorth = cdCoords[Triangles[uiI].iCoordNo2].dNorth - dMinNorth;
cdTrnsfrmd[1].dElev = cdCoords[Triangles[uiI].iCoordNo2].dElev - dMinElev;

cdTrnsfrmd[2].dEast = cdCoords[Triangles[uiI].iCoordNo3].dEast - dMinEast;
cdTrnsfrmd[2].dNorth = cdCoords[Triangles[uiI].iCoordNo3].dNorth - dMinNorth;
cdTrnsfrmd[2].dElev = cdCoords[Triangles[uiI].iCoordNo3].dElev - dMinElev;

GetNormalEquationOfPlane( cdTrnsfrmd, &dXyz );

gldVertex1[0] = (GLdouble)cdTrnsfrmd[0].dEast;
gldVertex1[1] = (GLdouble)cdTrnsfrmd[0].dNorth;
gldVertex1[2] = (GLdouble)cdTrnsfrmd[0].dElev;



gldVertex2[0] = (GLdouble)cdTrnsfrmd[1].dEast;
gldVertex2[1] = (GLdouble)cdTrnsfrmd[1].dNorth;
gldVertex2[2] = (GLdouble) cdTrnsfrmd[1].dElev;

/*gldVertex3[0] = (GLdouble)cdTrnsfrmd[2].dEast;
gldVertex3[1] = (GLdouble)cdTrnsfrmd[2].dNorth;
gldVertex3[2] = (GLdouble)cdTrnsfrmd[2].dElev;*/


normcrossprod(gldVertex1, gldVertex2, gldNorm);
gldColorPercent = (gldNorm[0] * 255.0) / 255.0;//dNorm[0] * dNorm[0] + dNorm[1] * dNorm[1] + dNorm[2] * dNorm[2];



//ok
gldColour3[0] = ( 125.0 - 60.0 * gldColorPercent) / 255.0;
gldColour3[1] = ( 125.0 - 60.0 * gldColorPercent ) / 255.0;
gldColour3[2] = ( 125.0 - 60.0 * gldColorPercent) / 255.0;

glColor3d( gldColour3[0], gldColour3[1], gldColour3[2] );
glNormal3d(gldNorm[0], gldNorm[1], gldNorm[2]);//glNormal3fv(fNorm);

glVertex3d( (GLdouble)cdTrnsfrmd[0].dEast - (GLdouble)((dMaxEast - dMinEast)/ 2.0),
(GLdouble)cdTrnsfrmd[0].dNorth - (GLdouble)((dMaxNorth - dMinNorth) / 2.0 ),
(GLdouble)(cdTrnsfrmd[0].dElev - ( dMaxElev - dMinElev ) / 2.0) );

glVertex3d( (GLdouble)cdTrnsfrmd[1].dEast - (GLdouble)((dMaxEast - dMinEast)/ 2.0),
(GLdouble)cdTrnsfrmd[1].dNorth - (GLdouble)((dMaxNorth - dMinNorth) / 2.0 ),
(GLdouble)(cdTrnsfrmd[1].dElev - ( dMaxElev - dMinElev ) / 2.0 ));


glVertex3d( (GLdouble)cdTrnsfrmd[2].dEast - (GLdouble)((dMaxEast - dMinEast)/ 2.0),
(GLdouble)cdTrnsfrmd[2].dNorth - (GLdouble)((dMaxNorth - dMinNorth) / 2.0 ),
(GLdouble)(cdTrnsfrmd[2].dElev - ( dMaxElev - dMinElev ) / 2.0));



}
uiI++;

while((errCode = glGetError()) != GL_NO_ERROR) {
errString = gluErrorString( errCode );
//fprintf (stderr, "OpenGL Error: %s\n", errString);

switch(errCode) {
case GL_INVALID_OPERATION:
McMessageBoxExcl( hwnd, "OPENGL INVALID_OPERATION",
"App" );
break;
case GL_INVALID_ENUM:
McMessageBoxExcl( hwnd, "OPENGL INVALID_ENUM",
"App" );
break;
case GL_INVALID_VALUE:
McMessageBoxExcl( hwnd, "OPENGL INVALID_VALUE",
"App" );
break;

case GL_OUT_OF_MEMORY:
McMessageBoxExcl( hwnd, "OPENGL OUT_OF_MEMORY",
"App" );
break;

/*case GL_INVALID_FRAMEBUFFER_OPERATION:
McMessageBoxExcl( hwnd, "INVALID_FRAMEBUFFER_OPERATION",
"App" );
break;*/
default:
McMessageBoxExcl( hwnd, "UNKNOWN OPENGL ERROR",
"App" );
break;


}

uiI= uiTriPointer;

}

}while( uiI < uiTriPointer);


}


GLvoid createObjects( HWND hwnd )
{
GLUquadricObj *quadObj;




glNewList( //create or replace a display list
MMGLTRIANGLE, //Specifies the display-list name
GL_COMPILE); //Commands are merely compiled OR GL_COMPILE_AND_EXECUTE Commands are executed as they are compiled into the display list.

quadObj = gluNewQuadric (); //creates and returns a pointer to a new quadrics object
gluQuadricDrawStyle (quadObj, GLU_FILL);// GLU_SILHOUETTE );//GLU_LINE); //specify the draw style desired for quadrics
glBegin(GL_TRIANGLES);
CompileTriangles( hwnd );
glEnd();
glEndList();






}




GLvoid initializeGL(HWND hwnd, GLsizei width, GLsizei height)
{
GLfloat fmaxObjectSize, faspect;
GLdouble dnear_plane, dfar_plane;

GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);

glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

/* glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);*/



glClearIndex( (GLfloat)BLACK_INDEX); //specify the clear value for the color index buffers BLACK_INDEX = black back ground
glClearDepth( 1.0 ); //clears the depth buffer

//glutInitDisplayMode (GLUT_DEPTH);//depth buffer gives hidden surface removal

glEnable(GL_DEPTH_TEST); //enable or disable server-side GL capabilities, GL_DEPTH_TEST = do depth comparisons and update the depth buffer

glMatrixMode( GL_PROJECTION ); //sets the current matrix mode. GL_PROJECTION Applies subsequent matrix operations to the projection matrix stack.


faspect = (GLfloat) width / height;
gluPerspective( //set up a perspective projection matrix
(GLdouble)45.0, //45 Specifies the field of view angle, in degrees, in the y direction
(GLdouble)faspect, //Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
(GLdouble)1.0, //10 Specifies the distance from the viewer to the near clipping plane (always positive).
(GLdouble)(4.0 * mf_3d)//700.0 //Specifies the distance from the viewer to the far clipping plane (always positive).
);

glMatrixMode( GL_MODELVIEW ); //specify which matrix is the current matrix. GL_MODELVIEW Applies subsequent matrix operations to the modelview matrix stack.

dnear_plane = 5.0;
dfar_plane = 2.0 * mf_3d;//700.0;
fmaxObjectSize = (float)mf_3d;//mf_d;//100.0F;//3.0F;
radius = mf_3d * 1.5;//mf_d * 1.5;///200;//radius = near_plane + maxObjectSize/2.0;

flatitude = 0.0F;
flongitude = 0.0F;
flatinc = 6.0F;
flonginc = 2.5F;

glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );//part of zoom initialisation OpenGL p 357
createObjects( hwnd );
}









void oncreateOpenGL( HWND hwnd )
{
LONG lRet = 1;
// PAINTSTRUCT ps;
RECT rect;
BOOL bError = 0;

ghDC = GetDC( hwnd);
if (!bSetupPixelFormat(ghDC))
PostQuitMessage (0);

ghRC = wglCreateContext(ghDC);
bError = wglMakeCurrent(ghDC, ghRC);
GetClientRect(hwnd, &rect);
initializeGL(hwnd, rect.right, rect.bottom);

}

Dark Photon
04-14-2014, 06:52 AM
First, please put code between
... or ... tags so that it formats properly and is more readable.

Second, calling glGetError() is invalid inside a display list.

Third, the GPU is just going to down-convert your doubles to floats internally anyway, so you can save space by just registering them as floats from the start (e.g. glVertex3f, glColor3f, glNormal3f, etc.).

If the number of tris is as you list above (1.3 million), the total space consumption for all your verts as doubles is 267.8 MB. Drop to floats and you're at 133.9MB.

Try busting up your display list into batches of 30,000 or so triangles apiece (that is, do multiple glBegins/glEnds). Prefer inserting triangles into batches that are adjacent to each other. Even better, make the vertex sharing explicit by registering indexed triangles (e.g. glDrawElements).

Keep in mind that display lists are old and somewhat deprecated. If I were you and I couldn't figure out how to "make the driver happy" with my vertex data fairly quickly, I'd just load it up into a VBO using indexed triangles and issue the batch draws directly. Doing so will also likely give you insight into what the driver isn't liking about how you are trying to feed display lists now.

mcmike
04-14-2014, 08:57 AM
thanks. I will try this