Skip to main content
gamedev.net
🔒 Locked

Performance and update

Started by ErikPeeters 8 replies 1.2k views
Original Post
ErikPeeters
ErikPeeters
Hi, for some time now i am trying to make some kind of a 3D world. I have made a little program based on the NeHe tutorials but I have some questons: In my code I make 1 daffodil on a square and this goes well: I can look and walk around without any problem. But when I loop 360 times and draw the daffodil as many times as I loop there is a major performance hit although I create the 360 daffodills in the methode DrawNarcissus() in a list. Here is my code, can somebody please help me get this to a acceptable speed?

#include <windows.h>		// Header File For Windows
#include <math.h>			// Math Library Header File
#include <stdio.h>			// Header File For Standard Input/Output
#include <gl\gl.h>			// Header File For The OpenGL32 Library
#include <gl\glu.h>			// Header File For The GLu32 Library
#include <gl\glaux.h>			// Header File For The GLu32 Library

#pragma comment( lib, "opengl32.lib" )					// Search For OpenGL32.lib While Linking
#pragma comment( lib, "glu32.lib" )						// Search For GLu32.lib While Linking
#pragma comment( lib, "winmm.lib" )						// Search For WinMM Library While Linking

#define IDT_TIMER1	0x12345

BOOL bDone = FALSE;

LONG WINAPI WndProc(HWND,UINT,WPARAM,LPARAM);//Window procedure
HGLRC SetUpOpenGL(HWND hwnd);//Initialize OpenGL
void DrawOpenGLScene(HWND hWnd);//Actual Drawing code
static LRESULT OnLButtonDown(HWND hWnd, UINT nFlags, POINT point);

//////////////////////////////////////////////////////////////////////////
GLuint texture;
GLfloat xtrans; 
GLfloat ztrans;
GLfloat ytrans;
GLfloat sceneroty;
GLfloat sceneroty_look;
//////////////////////////////////////////////////////////////////////////

BOOL			bLoadBitmaps	= TRUE;
BOOL			keys[256];		// Array Used For The Keyboard Routine.
GLuint			narcissus = 0;
GLsizei			m_glnWidth = 0, m_glnHeight = 0;
GLdouble		m_gldAspect = 0.0f;
static HGLRC	m_hRC; // Note this is STATIC!

const float piover180 = 0.0174532925f;
float heading;
float xpos;
float zpos = 1.6f; // Eigenlijk 10.0f
float ypos = 0.0f;

GLfloat	yrot;				// Y Rotation
GLfloat walkbias = 0;
GLfloat walkbiasangle = 0;
GLfloat lookupdown = 45.0f;
GLfloat	z = 0.0f;				// Depth Into The Screen	

HDC m_hDC;

GLUquadricObj *coronaObj;
GLUquadricObj *stemObj;

void Update(HWND hWnd)
{
	if(!bDone)
	{
		if(keys[VK_ESCAPE])
		{
			SendMessage(hWnd, WM_DESTROY, 0, 0); // Close the app.
		}
		if (keys[VK_PRIOR])
		{
			z-=0.02f;
		}

		if (keys[VK_NEXT])
		{
			z+=0.02f;
		}

		if (keys[VK_UP])
		{
			xpos -= (float)sin(heading*piover180) * 0.05f;
			zpos -= (float)cos(heading*piover180) * 0.05f;
			if (walkbiasangle >= 359.0f)
			{
				walkbiasangle = 0.0f;
			}
			else
			{
				walkbiasangle+= 10;
			}
			walkbias = (float)sin(walkbiasangle * piover180)/20.0f;
		}

		if (keys[VK_DOWN])
		{
			xpos += (float)sin(heading*piover180) * 0.05f;
			zpos += (float)cos(heading*piover180) * 0.05f;
			if (walkbiasangle <= 1.0f)
			{
				walkbiasangle = 359.0f;
			}
			else
			{
				walkbiasangle-= 10;
			}
			walkbias = (float)sin(walkbiasangle * piover180)/20.0f;
		}

		if (keys[VK_RIGHT])
		{
			heading -= 1.0f;
			yrot = heading;
		}

		if (keys[VK_LEFT])
		{
			heading += 1.0f;	
			yrot = heading;
		}

		if (keys[VK_PRIOR])
		{
			lookupdown-= 1.0f;
		}

		if (keys[VK_NEXT])
		{
			lookupdown+= 1.0f;
		}

		if(keys['D'])
		{
			ypos = 0.75f;
		}
		else
		{
			ypos = 0.0f;
		}

		SwapBuffers(m_hDC);
		DrawOpenGLScene(hWnd);

		ReleaseDC(hWnd, m_hDC);
	}
}

// WinMain - the main window entry point.
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
	static char szAppName[]	= "OpenGL";
    static char szTitle[]	= "Getting Started With OpenGL";
    WNDCLASS	wc;   // Windows class struct.
    MSG			msg;  // Message struct .
    HWND		hWnd; // Main window handle..

    // Fill in window class structure with parameters that
    // describe the main window.
    wc.style			= CS_HREDRAW | CS_VREDRAW;		// Class style(s).
    wc.lpfnWndProc		= (WNDPROC)WndProc;				// Window Procedure
    wc.cbClsExtra		= 0;							// No per-class extra data.
    wc.cbWndExtra		= 0;							// No per-window extra data.
    wc.hInstance		= hInstance;					// Owner of this class.
    wc.hIcon			= NULL;							// Icon name.
    wc.hCursor			= LoadCursor(NULL, IDC_ARROW);	// Cursor.
    wc.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);		// Default color.
    wc.lpszMenuName		= NULL;							// Menu from .RC.
    wc.lpszClassName	= szAppName;					// Name to register as.

    // Register the window class
    RegisterClass(&wc);
  
    // Create a main window for this application instance.
    hWnd = CreateWindow(
                szAppName,								// App name.
                szTitle,								// Text for window title bar.
                WS_OVERLAPPEDWINDOW						// Window style.
				// NEED THESE for OpenGL calls to work!
                 | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
                0, 0, 1280, (1024 - 30),
                NULL,									// No parent window.
                NULL,									// Use the window class menu.
                hInstance,								// This instance owns this window.
                NULL									// We don't use any extra data.
	        );

    // If window could not be created, return zero.
    if(!hWnd)
	{
		return(0);
	}

    // Make the window visible & update its client area.
    ShowWindow(hWnd, 1);	// Show the window.
    UpdateWindow(hWnd);		// Sends WM_PAINT message.

	SetTimer(hWnd,             // handle to main window 
		IDT_TIMER1,            // timer identifier 
		10,                 // 10-second interval 
		(TIMERPROC) NULL);     // no timer callback 

	// Enter the Windows message loop.
	// Get and dispatch messages until WM_QUIT.
	while(GetMessage(&msg,		// Message structure.
		NULL,		// Handle of window receiving the message.
		0,			// Lowest message id to examine.
		0))		// Highest message id to examine.
	{
		if(msg.message == WM_TIMER)
		{
			Update(hWnd);
		}

		TranslateMessage(&msg);	// Translates messages
		DispatchMessage(&msg);	// then dispatches
	}

    return (int) msg.wParam;
}

GLfloat vdx = 0.0f, vdy = 0.0f;
void DoMouseMotion(int x, int y)
{
	vdx = (GLfloat)x;
	vdy = (GLfloat)y;

	lookupdown = GLfloat((90.0f / m_glnHeight) * vdy)-45.0f; // -45.0f; for looking streight ahead.

	sceneroty_look = GLfloat((180.0f / m_glnWidth) * vdx)-90.0f; // -45.0f to 'look' left under 0 degrees.
}

//WndProc.
LONG WINAPI WndProc(HWND hWnd, UINT msg,
                    WPARAM wParam, LPARAM lParam)
{
	m_hDC = GetDC(hWnd);
    
    PAINTSTRUCT		*ps = new PAINTSTRUCT;
    
    
	POINT			*point = new POINT;

	switch(msg)
	{
		case WM_CREATE:			// Select a pixel format and then
								// create a rendering context from it.
								m_hRC = SetUpOpenGL(hWnd);
								return 0;

		case WM_SIZE:			// Redefine the viewing volume and viewport
								// when the window size changes.
								
								// Make the RC current since we're going to
								// make an OpenGL call here...
								wglMakeCurrent(m_hDC, m_hRC);
								
								// Get the new size of the client window.
								// Note that we size according to the height,
								// not the smaller of the height or width.
								m_glnWidth	= (GLsizei) LOWORD(lParam);
								m_glnHeight	= (GLsizei) HIWORD(lParam);
								m_gldAspect	= (GLdouble)m_glnWidth/(GLdouble)m_glnHeight;
								
								// Set up a projection matrix to fill the
								// client window.
								glMatrixMode(GL_PROJECTION);
								glLoadIdentity();
								// a perspective-view matrix...
								gluPerspective(
									45.0f,		// Field-of-view angle.
									m_gldAspect,	// Aspect ratio of view volume.
									0.1f,		// Distance to near clipping plane.
									100.0f);	// Distance to far clipping plane.
								
								glViewport(0, 0, m_glnWidth, m_glnHeight);
								wglMakeCurrent(NULL, NULL);
						
								SwapBuffers(m_hDC);

								return 0;

		case WM_PAINT:			// Draw the scene.
								// Get a DC, then make the RC current and
								// associate with this DC.
								m_hDC = BeginPaint(hWnd, ps);

								wglMakeCurrent(m_hDC, m_hRC);
																
								EndPaint(hWnd, ps);

								ReleaseDC(hWnd, m_hDC);

								return 0;
								
		case WM_KEYDOWN:		// Is A Key Being Held Down?
								keys[wParam] = TRUE;	// If So, Mark It As TRUE.
								return 0;				// Jump Back.
								
		case WM_KEYUP:			// Has A Key Been Released?
								keys[wParam] = FALSE;	// If So, Mark It As FALSE.
								return 0;				// Jump Back.
		case WM_MOUSEMOVE:		
								point->x = LOWORD(lParam);
								point->y = HIWORD(lParam);
								DoMouseMotion(point->x, point->y);

								return 0;

		case WM_DESTROY:		// Clean up and terminate.
								KillTimer(hWnd, IDT_TIMER1);

								gluDeleteQuadric(coronaObj);			// Delete coronaObj - Free Resources
								gluDeleteQuadric(stemObj);				// Delete stemObj - Free Resources

								wglMakeCurrent(NULL, NULL);
								ReleaseDC(hWnd, m_hDC);
								wglDeleteContext(m_hRC);
								PostQuitMessage(0);
								bDone = TRUE;
								return 0;
	}

	delete ps;
	delete point;
	ps = NULL;
	point = NULL;


	// This function handles any messages that we didn't.
    // (Which is most messages) It belongs to the OS.
    return (long) DefWindowProc(hWnd, msg, wParam, lParam);
}

//////////////////////////////////////////////////////////////////////////
#define TEXTURE_AMOUNT	4
GLuint	texture2[TEXTURE_AMOUNT];			// Storage For One Texture ( NEW )
AUX_RGBImageRec *LoadBMP(char *Filename)				// Loads A Bitmap Image
{
	FILE *File=NULL;									// File Handle

	if (!Filename)										// Make Sure A Filename Was Given
	{
		return NULL;									// If Not Return NULL
	}

	File=fopen(Filename,"r");							// Check To See If The File Exists

	if (File)											// Does The File Exist?
	{
		fclose(File);									// Close The Handle
		return auxDIBImageLoad(Filename);				// Load The Bitmap And Return A Pointer
	}

	return NULL;										// If Load Failed Return NULL
}

int LoadGLTextures()									// Load Bitmaps And Convert To Textures
{
	int Status=FALSE;									// Status Indicator
	GLint nLoop = 0;

	AUX_RGBImageRec *TextureImage[TEXTURE_AMOUNT];					// Create Storage Space For The Texture

	memset(TextureImage,0,sizeof(void *)*TEXTURE_AMOUNT);           	// Set The Pointer To NULL

	// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
	if((TextureImage[0]=LoadBMP("Data/NeHe.bmp")) &&
	   (TextureImage[1]=LoadBMP("Data/NeHeMask.bmp")) &&
	   (TextureImage[2]=LoadBMP("Data/grass.bmp")) &&
	   (TextureImage[3]=LoadBMP("Data/petal.bmp")))
	{
		Status=TRUE;									// Set The Status To TRUE

		glGenTextures(TEXTURE_AMOUNT, &texture2[0]);					// Create The Texture

		for(nLoop = 0; nLoop < TEXTURE_AMOUNT; nLoop++)
		{
			// Typical Texture Generation Using Data From The Bitmap
			glBindTexture(GL_TEXTURE_2D, texture2[nLoop]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[nLoop]->sizeX, TextureImage[nLoop]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[nLoop]->data);
		}		
	}

	for(nLoop = 0; nLoop < TEXTURE_AMOUNT; nLoop++)
	{
		if (TextureImage[nLoop])									// If Texture Exists
		{
			if (TextureImage[nLoop]->data)							// If Texture Image Exists
			{
				free(TextureImage[nLoop]->data);					// Free The Texture Image Memory
			}

			free(TextureImage[nLoop]);								// Free The Image Structure
		}
	}

	return Status;										// Return The Status
}

/////////////////////////////////////////////////////////
//  SetUpOpenGL sets the pixel format and a rendering
//  context then returns the RC.
/////////////////////////////////////////////////////////
HGLRC SetUpOpenGL(HWND hWnd)
{
    static PIXELFORMATDESCRIPTOR pfd = {
				sizeof (PIXELFORMATDESCRIPTOR),	// Struct size.
				1,                              // Version number.
				PFD_DRAW_TO_WINDOW |			// Flags, draw to a window,
				PFD_SUPPORT_OPENGL |
				PFD_DOUBLEBUFFER,				// use OpenGL
				PFD_TYPE_RGBA,					// RGBA pixel values
				24,								// 24-bit color
				0, 0, 0,						// RGB bits & shift sizes.
				0, 0, 0,						// Don't care about them
				0, 0,							// No alpha buffer info
				0, 0, 0, 0, 0,					// No accumulation buffer
				32,								// 32-bit depth buffer
				0,								// No stencil buffer
				0,								// No auxiliary buffers
				PFD_MAIN_PLANE,					// Layer type
				0,								// Reserved (must be 0)
				0,								// No layer mask
				0,								// No visible mask
				0								// No damage mask
			};

    int		nMyPixelFormatID;
    HDC		hDC;
    HGLRC	hRC;

    hDC = GetDC(hWnd);
    nMyPixelFormatID = ChoosePixelFormat(hDC, &pfd);

    // Catch errors here.
    // If nMyPixelFormat is zero, then there's
    // something wrong... most likely the window's
    // style bits are incorrect (in CreateWindow() )
    // or OpenGl isn't installed on this machine.

    SetPixelFormat(hDC, nMyPixelFormatID, &pfd);

    hRC = wglCreateContext(hDC);
	ReleaseDC(hWnd, hDC);

    return hRC;
}

void Narcissus()
{
	// First Patal triangle.
	glBegin(GL_TRIANGLES);
		glColor3f(1.0, 1.0, 0.0);
		glTexCoord2f(0.0f,	0.0f); glVertex3f(-0.1,-0.5, 1.0);
		glTexCoord2f(1.0f,	0.0f); glVertex3f( 0.1,-0.5, 1.0);
		glTexCoord2f(1.0f,	1.0f); glVertex3f( 0.0,-0.65, 1.0);
	glEnd();

	// Second petal triangle.
	glBegin(GL_TRIANGLES);
		glColor3f(1.0, 1.0, 0.0);
		glTexCoord2f(0.0f,	0.0f); glVertex3f( 0.1,-0.6, 1.0);
		glTexCoord2f(1.0f,	0.0f); glVertex3f(-0.1,-0.6, 1.0);
		glTexCoord2f(1.0f,	1.0f); glVertex3f( 0.0,-0.45, 1.0);
	glEnd();

	// Leafs.
	glBegin(GL_TRIANGLES);
		glColor3f(0.0f, 0.6f, 0.0f);
		glTexCoord2f(0.0f,	0.0f); glVertex3f( 0.01,-1.0, 0.995);
		glTexCoord2f(1.0f,	0.0f); glVertex3f( 0.02, -0.6, 0.95);
		glTexCoord2f(1.0f,	1.0f); glVertex3f(-0.01,-1.0, 0.995);
	glEnd();

	glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
	glTranslatef(-1.0f, 0.0f, -1.0f);
	glBegin(GL_TRIANGLES);
		glTexCoord2f(0.0f,	0.0f); glVertex3f( 0.01,-1.0, 0.995);
		glTexCoord2f(1.0f,	0.0f); glVertex3f( 0.02, -0.7, 0.95);
		glTexCoord2f(1.0f,	1.0f); glVertex3f(-0.01,-1.0, 0.995);
	glEnd();
	glTranslatef(1.0f, 0.0f, 1.0f);
	glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);

	// Corona.
	glColor3f(0.85, 0.85, 0.0);		// Yellow color for the corona.
	coronaObj = gluNewQuadric();
	gluQuadricDrawStyle(coronaObj, GLU_FILL);
	gluQuadricNormals(coronaObj, GLU_SMOOTH);
	gluQuadricTexture(coronaObj, GL_TRUE);	// Texture use on.
	glTranslatef(0.0f,-0.55f, 1.0f);
	gluCylinder(coronaObj, 0.015, 0.025, 0.05, 32, 32);
	glTranslatef(0.0f, 0.55f,-1.0f);

	// Stem.
	glColor3f(0.0, 0.5, 0.0);		// Green color for the stem.
	stemObj = gluNewQuadric();
	gluQuadricDrawStyle(stemObj, GLU_FILL);
	gluQuadricNormals(stemObj, GLU_SMOOTH);
	gluQuadricTexture(stemObj, GL_TRUE);	// Texture use on.
	glTranslatef(0.0f,-1.0f, 1.0f);
	glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
	gluCylinder(stemObj, 0.01, 0.005, 0.4, 32, 32);
	glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
	glTranslatef(0.0f, 1.0f,-1.0f);
}

void DrawNarcissus()
{
	glBindTexture(GL_TEXTURE_2D, texture2[2]);
	glEnable( GL_TEXTURE_2D );

	// Square.
	glBegin(GL_QUADS);
		glColor3f(1.0, 1.0, 1.0);			// All bright colors for the texture display.
		glTexCoord2f(0.0f,	0.0f); glVertex3f(-0.5f, -1.0f, 0.0f);	// Top Right Of The Texture and Quad
		glTexCoord2f(1.0f,	0.0f); glVertex3f( 0.5f, -1.0f, 0.0f);	// Top Left Of The Texture and Quad
		glTexCoord2f(1.0f,	1.0f); glVertex3f( 0.5f, -1.0f, 1.0f);	// Bottom Left Of The Texture and Quad
		glTexCoord2f(0.0f,	1.0f); glVertex3f(-0.5f, -1.0f, 1.0f);	// Bottom Right Of The Texture and Quad
	glEnd();

	glBindTexture(GL_TEXTURE_2D, texture2[3]);

	glRotatef(270.0f, 0.0f, 1.0f, 0.0f);
	glTranslatef(0.25f,0.0f,-0.75f);
	Narcissus();
	glTranslatef(-0.25f, 0.0f,0.75f);
	glRotatef(-270.0f, 0.0f, 1.0f, 0.0f);

	glDisable(GL_TEXTURE_2D);
}

void BuildNarcissus()
{
	narcissus = glGenLists(1);				// Build one list.
	glNewList(narcissus, GL_COMPILE);		// New compiled narcissus display list.
	
	glLoadName(33);
	DrawNarcissus();

	glEndList();							// Done building the narcissus list.
}
//////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////// 
//  DrawScene uses OpenGL commands to draw a triangle.
//  This is where the OpenGL drawing commands live.
////////////////////////////////////////////////////////// 
void DrawOpenGLScene(HWND hWnd)
{
	ReleaseDC(hWnd, m_hDC);

	if(bLoadBitmaps)
	{
		bLoadBitmaps = FALSE;
		
		LoadGLTextures();
		BuildNarcissus();


		glEnable(GL_TEXTURE_2D);								// Enable Texture Mapping ( NEW )
		glShadeModel(GL_SMOOTH);								// Enable Smooth Shading
		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);					// Black Background
		glClearDepth(1.0f);										// Depth Buffer Setup
		glEnable(GL_DEPTH_TEST);								// Enables Depth Testing
		glDepthFunc(GL_LEQUAL);									// The Type Of Depth Testing To Do
		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);		// Really Nice Perspective Calculations
	}

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Define the modelview transformation.
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

	xtrans = -xpos;
	ztrans = -zpos;
	ytrans = -walkbias-0.25f + ypos;
	sceneroty = 360.0f - yrot;

	glRotatef(lookupdown, 1.0f, 0.0f, 0.0f);
	glRotatef(sceneroty_look,  0.0f, 1.0f, 0.0f);
	glRotatef(sceneroty,  0.0f, 1.0f, 0.0f);

	glTranslatef(xtrans, ytrans, ztrans);

	glCallList(narcissus);										// Draw the narcissus

	ReleaseDC(hWnd, m_hDC);	
}

Thank you!
ErikPeeters
ErikPeeters
Thanks for your reaction!

I do not loop the DrawNarcissus() methode 360 times but within this methode I loop the code section

glRotatef(270.0f, 0.0f, 1.0f, 0.0f);glTranslatef(0.25f,0.0f,-0.75f);Narcissus();glTranslatef(-0.25f, 0.0f,0.75f);glRotatef(-270.0f, 0.0f, 1.0f, 0.0f);


360 times (with each loop counter being the amount of rotating-degrees), so I don't switch textures at all...

Is there maybe some other explanation why this performance hit is occuring?

Thanks in advance...
Palidine
Palidine
Define "major performance hit"

[EDIT: also you call glBegin/glEnd way too many times. You should pre-build your narcissus geometry one single time at startup and just render it in different places by pushing on translation/rotation matrices.]

-me
ErikPeeters
ErikPeeters
The performance hit is that the CPU is going up from 02 to 99 and the graphics become very very slow.

I can decrease the amount of glBegin/glEnd's but don't I have to glEnd before a glRotatef or glTranslatef?

I pre-build it only once at the beginning of DrawOpenGLScene().

Can you please give me an example of the "rendering in different places by pushing on translation/rotation matrices."?
That would help me very much..


Thanks for your time.
Palidine
Palidine
well. in a fullscreen app the CPU should always be around 100%. To gauge performance you need to implement a FPS(frames per second) counter. Otherwise you're just dealing with subjectivity.

Basically I mean this:

at level start:
create a narcissus model (list of vertices, and their draw order). Your flowers are the same every single time you draw them so it's wasteful to recalculate where each vertex is. you'll just have to implement non-opengl functions that do the same thing as the glQuadricXXX functions.

each update cycle:

for each narcissus{    glPushMatrix();    glTranslatef( the narcissus instance position );    glRotatef( the narcissus instance rotation );    //render the narcissus vertices that you've already calculated    //don't remember the syntax but something like this    glVertexList( myNarcissusVertices, numVertices );    glIndexList( myNarcissusIndices, numIndices );   //these are indexes into the vertex list  i.e. draw vertex 1,2,3 then 3,4,5 or whatever    glPopMatrix();}


-me
Stani R
Stani R
Rather than building one large display list for all 360 loops, as you're doing now, try one small list for one loop, then draw that list 360 times, because there is a performance hit when using large lists. Whether that is the reason for your troubles, I'm not sure of. Your list may not be large enough to qualify for that problem.

So as a first suggestion for what to try:
for( int i = 0; i < 360; i++ ) {    glTranslatef(1.0f, 0.0f, 0.0f);    drawNarcissusList();}
haphazardlynamed
haphazardlynamed
Wait, youre looping on the narcissus() function 360 times per render?

Inside narcissus() I see two calls to gluNewQuadric() This is Bad. Most likely a major slowdown. Allocate the quadrics Once, outside the rendering loop; then reuse them. Do Not re-allocate them for every flower in the 360 interation loop.
On top of that it contains a few unecesarry glBeing/glEnds that could be combined. but I'm guessing the quadrics are the major factor here.
ErikPeeters
ErikPeeters
Tank you all for your replies and suggestions...

I will use them adn post my findings.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.