⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glcamera.cpp

📁 关于OpenGL的实例教程源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    m_Frustum[1][2] /= t;
    m_Frustum[1][3] /= t;

    /* Extract the BOTTOM plane */
    m_Frustum[2][0] = clip[ 3] + clip[ 1];
    m_Frustum[2][1] = clip[ 7] + clip[ 5];
    m_Frustum[2][2] = clip[11] + clip[ 9];
    m_Frustum[2][3] = clip[15] + clip[13];

    /* Normalize the result */
    t = GLfloat(sqrt( m_Frustum[2][0] * m_Frustum[2][0] + m_Frustum[2][1] * m_Frustum[2][1] + m_Frustum[2][2] * m_Frustum[2][2] ));
    m_Frustum[2][0] /= t;
    m_Frustum[2][1] /= t;
    m_Frustum[2][2] /= t;
    m_Frustum[2][3] /= t;

    /* Extract the TOP plane */
    m_Frustum[3][0] = clip[ 3] - clip[ 1];
    m_Frustum[3][1] = clip[ 7] - clip[ 5];
    m_Frustum[3][2] = clip[11] - clip[ 9];
    m_Frustum[3][3] = clip[15] - clip[13];

    /* Normalize the result */
    t = GLfloat(sqrt( m_Frustum[3][0] * m_Frustum[3][0] + m_Frustum[3][1] * m_Frustum[3][1] + m_Frustum[3][2] * m_Frustum[3][2] ));
    m_Frustum[3][0] /= t;
    m_Frustum[3][1] /= t;
    m_Frustum[3][2] /= t;
    m_Frustum[3][3] /= t;

    /* Extract the FAR plane */
    m_Frustum[4][0] = clip[ 3] - clip[ 2];
    m_Frustum[4][1] = clip[ 7] - clip[ 6];
    m_Frustum[4][2] = clip[11] - clip[10];
    m_Frustum[4][3] = clip[15] - clip[14];

    /* Normalize the result */
    t = GLfloat(sqrt( m_Frustum[4][0] * m_Frustum[4][0] + m_Frustum[4][1] * m_Frustum[4][1] + m_Frustum[4][2] * m_Frustum[4][2] ));
    m_Frustum[4][0] /= t;
    m_Frustum[4][1] /= t;
    m_Frustum[4][2] /= t;
    m_Frustum[4][3] /= t;

    /* Extract the NEAR plane */
    m_Frustum[5][0] = clip[ 3] + clip[ 2];
    m_Frustum[5][1] = clip[ 7] + clip[ 6];
    m_Frustum[5][2] = clip[11] + clip[10];
    m_Frustum[5][3] = clip[15] + clip[14];

    /* Normalize the result */
    t = GLfloat(sqrt( m_Frustum[5][0] * m_Frustum[5][0] + m_Frustum[5][1] * m_Frustum[5][1] + m_Frustum[5][2] * m_Frustum[5][2] ));
    m_Frustum[5][0] /= t;
    m_Frustum[5][1] /= t;
    m_Frustum[5][2] /= t;
    m_Frustum[5][3] /= t;
}

// This is the much faster version of the above member 
// function, however the speed increase is not gained 
// without a cost. If you rotate or translate the projection
// matrix then this member will not work correctly. That is acceptable
// in my book considering I very rarely do such a thing.
// This function has far fewer operations in it and I 
// shaved off 2 square root functions by passing in the
// near and far values. This member has:
// 38 muliplications, 28 additions, 24 divisions, and
// 12 subtractions for a total of 102 operations. Still hurts
// but at least it is decent now. In practice this will 
// run about 2 times faster than the above function.
void glCamera::UpdateFrustumFaster()
{
	GLfloat   clip[16];
	GLfloat   proj[16];
	GLfloat   modl[16];
	GLfloat   t;

	/* Get the current PROJECTION matrix from OpenGL */
	glGetFloatv( GL_PROJECTION_MATRIX, proj );

	/* Get the current MODELVIEW matrix from OpenGL */
	glGetFloatv( GL_MODELVIEW_MATRIX, modl );

	/* Combine the two matrices (multiply projection by modelview) 
	   but keep in mind this function will only work if you do NOT
	   rotate or translate your projection matrix                  */
	clip[ 0] = modl[ 0] * proj[ 0];
    clip[ 1] = modl[ 1] * proj[ 5];
    clip[ 2] = modl[ 2] * proj[10] + modl[ 3] * proj[14];
    clip[ 3] = modl[ 2] * proj[11];

    clip[ 4] = modl[ 4] * proj[ 0];
    clip[ 5] = modl[ 5] * proj[ 5];
    clip[ 6] = modl[ 6] * proj[10] + modl[ 7] * proj[14];
    clip[ 7] = modl[ 6] * proj[11];

    clip[ 8] = modl[ 8] * proj[ 0];
    clip[ 9] = modl[ 9] * proj[ 5];
    clip[10] = modl[10] * proj[10] + modl[11] * proj[14];
    clip[11] = modl[10] * proj[11];

    clip[12] = modl[12] * proj[ 0];
    clip[13] = modl[13] * proj[ 5];
    clip[14] = modl[14] * proj[10] + modl[15] * proj[14];
    clip[15] = modl[14] * proj[11];

	/* Extract the numbers for the RIGHT plane */
	m_Frustum[0][0] = clip[ 3] - clip[ 0];
	m_Frustum[0][1] = clip[ 7] - clip[ 4];
	m_Frustum[0][2] = clip[11] - clip[ 8];
	m_Frustum[0][3] = clip[15] - clip[12];

	/* Normalize the result */
	t = GLfloat(sqrt( m_Frustum[0][0] * m_Frustum[0][0] + m_Frustum[0][1] * m_Frustum[0][1] + m_Frustum[0][2] * m_Frustum[0][2] ));
	m_Frustum[0][0] /= t;
	m_Frustum[0][1] /= t;
	m_Frustum[0][2] /= t;
	m_Frustum[0][3] /= t;

    /* Extract the numbers for the LEFT plane */
    m_Frustum[1][0] = clip[ 3] + clip[ 0];
    m_Frustum[1][1] = clip[ 7] + clip[ 4];
    m_Frustum[1][2] = clip[11] + clip[ 8];
    m_Frustum[1][3] = clip[15] + clip[12];

    /* Normalize the result */
    t = GLfloat(sqrt( m_Frustum[1][0] * m_Frustum[1][0] + m_Frustum[1][1] * m_Frustum[1][1] + m_Frustum[1][2] * m_Frustum[1][2] ));
    m_Frustum[1][0] /= t;
    m_Frustum[1][1] /= t;
    m_Frustum[1][2] /= t;
    m_Frustum[1][3] /= t;

	/* Extract the BOTTOM plane */
    m_Frustum[2][0] = clip[ 3] + clip[ 1];
    m_Frustum[2][1] = clip[ 7] + clip[ 5];
    m_Frustum[2][2] = clip[11] + clip[ 9];
    m_Frustum[2][3] = clip[15] + clip[13];

    /* Normalize the result */
    t = GLfloat(sqrt( m_Frustum[2][0] * m_Frustum[2][0] + m_Frustum[2][1] * m_Frustum[2][1] + m_Frustum[2][2] * m_Frustum[2][2] ));
    m_Frustum[2][0] /= t;
    m_Frustum[2][1] /= t;
    m_Frustum[2][2] /= t;
    m_Frustum[2][3] /= t;

    /* Extract the TOP plane */
    m_Frustum[3][0] = clip[ 3] - clip[ 1];
    m_Frustum[3][1] = clip[ 7] - clip[ 5];
    m_Frustum[3][2] = clip[11] - clip[ 9];
    m_Frustum[3][3] = clip[15] - clip[13];

    /* Normalize the result */
    t = GLfloat(sqrt( m_Frustum[3][0] * m_Frustum[3][0] + m_Frustum[3][1] * m_Frustum[3][1] + m_Frustum[3][2] * m_Frustum[3][2] ));
    m_Frustum[3][0] /= t;
    m_Frustum[3][1] /= t;
    m_Frustum[3][2] /= t;
    m_Frustum[3][3] /= t;

    /* Extract the FAR plane */
    m_Frustum[4][0] = clip[ 3] - clip[ 2];
    m_Frustum[4][1] = clip[ 7] - clip[ 6];
    m_Frustum[4][2] = clip[11] - clip[10];
    m_Frustum[4][3] = clip[15] - clip[14];

    /* Normalize the result */
    t = GLfloat(sqrt( m_Frustum[4][0] * m_Frustum[4][0] + m_Frustum[4][1] * m_Frustum[4][1] + m_Frustum[4][2] * m_Frustum[4][2] ));
    m_Frustum[4][0] /= t;
    m_Frustum[4][1] /= t;
    m_Frustum[4][2] /= t;
    m_Frustum[4][3] /= t;

    /* Extract the NEAR plane */
    m_Frustum[5][0] = clip[ 3] + clip[ 2];
    m_Frustum[5][1] = clip[ 7] + clip[ 6];
    m_Frustum[5][2] = clip[11] + clip[10];
    m_Frustum[5][3] = clip[15] + clip[14];

    /* Normalize the result */
    t = GLfloat(sqrt( m_Frustum[5][0] * m_Frustum[5][0] + m_Frustum[5][1] * m_Frustum[5][1] + m_Frustum[5][2] * m_Frustum[5][2] ));
    m_Frustum[5][0] /= t;
    m_Frustum[5][1] /= t;
    m_Frustum[5][2] /= t;
    m_Frustum[5][3] /= t;
}

// This member function checks to see if a sphere is in
// the viewing volume.  
BOOL glCamera::SphereInFrustum(glPoint p, GLfloat Radius)
{
	int i;

	// The idea here is the same as the PointInFrustum function.

	for(i = 0; i < 6; i++)
	{
		// If the point is outside of the plane then its not in the viewing volume.
		if(m_Frustum[i][0] * p.x + m_Frustum[i][1] * p.y + m_Frustum[i][2] * p.z + m_Frustum[i][3] <= -Radius)
		{
			return(FALSE);
		}
	}
	
	return(TRUE);
}

// This member fuction checks to see if a point is in
// the viewing volume.
BOOL glCamera::PointInFrustum(glPoint p)
{
	int i;

	// The idea behind this algorithum is that if the point
	// is inside all 6 clipping planes then it is inside our
	// viewing volume so we can return true.

	for(i = 0; i < 6; i++)
	{
		if(m_Frustum[i][0] * p.x + m_Frustum[i][1] * p.y + m_Frustum[i][2] * p.z + m_Frustum[i][3] <= 0)
		{
			return(FALSE);
		}
	}

    return(TRUE);
}

// This member function checks to see if a sphere is in
// the viewing volume.  
BOOL glCamera::SphereInFrustum(GLfloat x, GLfloat y, GLfloat z, GLfloat Radius)
{
	int i;

	// The idea here is the same as the PointInFrustum function.
		
	for(i = 0; i < 6; i++)
	{
		// If the point is outside of the plane then its not in the viewing volume.
		if(m_Frustum[i][0] * x + m_Frustum[i][1] * y + m_Frustum[i][2] * z + m_Frustum[i][3] <= -Radius)
		{
			return(FALSE);
		}
	}
	
	return(TRUE);
}

// This member fuction checks to see if a point is in
// the viewing volume.
BOOL glCamera::PointInFrustum(GLfloat x, GLfloat y, GLfloat z)
{
	int i;
	
	// The idea behind this algorithum is that if the point
	// is inside all 6 clipping planes then it is inside our
	// viewing volume so we can return true.

	for(i = 0; i < 6; i++)	// Loop through all our clipping planes
	{
		// If the point is outside of the plane then its not in the viewing volume.
		if(m_Frustum[i][0] * x + m_Frustum[i][1] * y + m_Frustum[i][2] * z + m_Frustum[i][3] <= 0)
		{
			return(FALSE);
		}
	}

    return(TRUE);
}

bool glCamera::IsOccluded(glPoint p)
{
  GLint viewport[4];											//space for viewport data
  GLdouble mvmatrix[16], projmatrix[16];  //space for transform matricex
	GLdouble winx, winy, winz;							//space for returned projected coords
	GLdouble flareZ;												//here we will store the transformed flare Z
	GLfloat bufferZ;												//here we will store the read Z from the buffer

	// Now we will ask OGL to project some geometry for us using the gluProject function.
	// Practically we ask OGL to guess where a point in space will be projected in our current viewport,
	// using arbitrary viewport and transform matrices we pass to the function.
	// If we pass to the function the current matrices  (retrievede with the glGet funcs)
	// we will have the real position on screen where the dot will be drawn.
	// The interesting part is that we also get a Z value back, this means that 
	// reading the REAL buffer for Z values we can discover if the flare is in front or
	// if it's occluded by some objects.


	glGetIntegerv (GL_VIEWPORT, viewport);						//get actual viewport
  glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);			//get actual model view matrix
  glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);	//get actual projiection matrix

	// this asks OGL to guess the 2d position of a 3d point inside the viewport
	gluProject(p.x, p.y, p.z, mvmatrix, projmatrix, viewport, &winx, &winy, &winz);
	flareZ = winz;

	// we read back one pixel from th depth buffer (exactly where our flare should be drawn)
	glReadPixels(winx, winy,1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &bufferZ);

	// if the buffer Z is lower than our flare guessed Z then don't draw 
	// this means there is something in front of our flare
	if (bufferZ < flareZ)
		return true;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -