コード例 #1
0
// Map for data access
U8* LLVertexBuffer::mapBuffer(S32 access)
{
    LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
    if (mFinal)
    {
        llwarns << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
    }
    if (!useVBOs() && !mMappedData && !mMappedIndexData)
    {
        llwarns << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
    }

    if (!mLocked && useVBOs())
    {
        setBuffer(0);
        mLocked = TRUE;
        stop_glerror();
        mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
        stop_glerror();
        mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
        stop_glerror();

        if (!mMappedData)
        {
            //--------------------
            //print out more debug info before crash
            llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
            GLint size ;
            glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
            llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
            //--------------------

            GLint buff;
            glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
            if (buff != mGLBuffer)
            {
                llwarns << "Invalid GL vertex buffer bound: " << buff << llendl;
            }


            llwarns << "glMapBuffer returned NULL (no vertex data)" << llendl;
        }

        if (!mMappedIndexData)
        {
            GLint buff;
            glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
            if (buff != mGLIndices)
            {
                llwarns << "Invalid GL index buffer bound: " << buff << llendl;
            }

            llwarns << "glMapBuffer returned NULL (no index data)" << llendl;
        }

        sMappedCount++;
    }

    return mMappedData;
}
コード例 #2
0
U8* LLVertexBuffer::mapIndexBuffer(S32 access)
{
	LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
	if (mFinal)
	{
		llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl;
	}
	if (!useVBOs() && !mMappedData && !mMappedIndexData)
	{
		llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl;
	}

	if (!mIndexLocked && useVBOs())
	{
		{
			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);

			setBuffer(0, TYPE_INDEX);
			mIndexLocked = TRUE;
			stop_glerror();	

			if(sDisableVBOMapping)
			{
				allocateClientIndexBuffer() ;
			}
			else
			{
				mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
			}
			stop_glerror();
		}

		if (!mMappedIndexData)
		{
			log_glerror();

			if(!sDisableVBOMapping)
			{
				GLint buff;
				glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
				if ((GLuint)buff != mGLIndices)
				{
					llerrs << "Invalid GL index buffer bound: " << buff << llendl;
				}

				llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
			}
			else
			{
				llerrs << "memory allocation for Index data failed. " << llendl ;
			}
		}

		sMappedCount++;
	}

	return mMappedIndexData ;
}
コード例 #3
0
void LLVertexBuffer::destroyGLBuffer()
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	if (mGLBuffer)
	{
		if (useVBOs())
		{
			freeClientBuffer() ;

			if (mMappedData || mMappedIndexData)
			{
				llerrs << "Vertex buffer destroyed while mapped!" << llendl;
			}
			releaseBuffer();
		}
		else
		{
			ll_aligned_free_16((void*)mMappedData);
			mMappedData = NULL;
			mEmpty = TRUE;
		}

		sAllocatedBytes -= getSize();
	}
	
	mGLBuffer = 0;
	//unbind();
}
コード例 #4
0
void LLVertexBuffer::createGLBuffer()
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);

	U32 size = getSize();
	if (mGLBuffer)
	{
		destroyGLBuffer();
	}

	if (size == 0)
	{
		return;
	}

	mEmpty = TRUE;

	if (useVBOs())
	{
		mMappedData = NULL;
		genBuffer();
		mResized = TRUE;
	}
	else
	{
		static int gl_buffer_idx = 0;
		mGLBuffer = ++gl_buffer_idx;	
		mMappedData = (U8*) ll_aligned_malloc_16(size);
		if(!sOmitBlank) memset((void*)mMappedData, 0, size);
	}
}
コード例 #5
0
void LLVertexBuffer::destroyGLIndices()
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	if (mGLIndices)
	{
		if (useVBOs())
		{
			freeClientBuffer() ;

			if (mMappedData || mMappedIndexData)
			{
				llerrs << "Vertex buffer destroyed while mapped." << llendl;
			}
			releaseIndices();
		}
		else
		{
			delete [] mMappedIndexData;
			mMappedIndexData = NULL;
			mEmpty = TRUE;
		}

		sAllocatedBytes -= getIndicesSize();
	}

	mGLIndices = 0;
	unbind();
}
コード例 #6
0
	// virtual
	void setupVertexBuffer(U32 data_mask)
	{	
		if (LLGLSLShader::sNoFixedFunction)
		{ //just use default if shaders are in play
			LLVertexBuffer::setupVertexBuffer(data_mask & ~(MAP_TEXCOORD2 | MAP_TEXCOORD3));
			return;
		}

		volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;

		//assume tex coords 2 and 3 are present
		U32 type_mask = mTypeMask | MAP_TEXCOORD2 | MAP_TEXCOORD3;

		if ((data_mask & type_mask) != data_mask)
		{
			llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
		}

		if (data_mask & MAP_NORMAL)
		{
			glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
		}
		if (data_mask & MAP_TEXCOORD3)
		{ //substitute tex coord 1 for tex coord 3
			glClientActiveTextureARB(GL_TEXTURE3_ARB);
			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
			glClientActiveTextureARB(GL_TEXTURE0_ARB);
		}
		if (data_mask & MAP_TEXCOORD2)
		{ //substitute tex coord 0 for tex coord 2
			glClientActiveTextureARB(GL_TEXTURE2_ARB);
			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
			glClientActiveTextureARB(GL_TEXTURE0_ARB);
		}
		if (data_mask & MAP_TEXCOORD1)
		{
			glClientActiveTextureARB(GL_TEXTURE1_ARB);
			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
			glClientActiveTextureARB(GL_TEXTURE0_ARB);
		}
		if (data_mask & MAP_TANGENT)
		{
			glClientActiveTextureARB(GL_TEXTURE2_ARB);
			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TANGENT], (void*)(base + mOffsets[TYPE_TANGENT]));
			glClientActiveTextureARB(GL_TEXTURE0_ARB);
		}
		if (data_mask & MAP_TEXCOORD0)
		{
			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
		}
		if (data_mask & MAP_COLOR)
		{
			glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
		}
		
		if (data_mask & MAP_VERTEX)
		{
			glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
		}
	}
コード例 #7
0
void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
{
	if (start >= (U32) mRequestedNumVerts ||
	    end >= (U32) mRequestedNumVerts)
	{
		llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mRequestedNumVerts << llendl;
	}

	llassert(mRequestedNumIndices >= 0);

	if (indices_offset >= (U32) mRequestedNumIndices ||
	    indices_offset + count > (U32) mRequestedNumIndices)
	{
		llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
	}

	if (gDebugGL && !useVBOs())
	{
		U16* idx = ((U16*) getIndicesPointer())+indices_offset;
		for (U32 i = 0; i < count; ++i)
		{
			if (idx[i] < start || idx[i] > end)
			{
				llerrs << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << llendl;
			}
		}
	}
}
コード例 #8
0
void LLVertexBufferAvatar::setupVertexBuffer(U32 data_mask) const
{
	if (sRenderingSkinned)
	{
		U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;

		glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX], (void*)(base + 0));
		glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
		glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
		
		set_vertex_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT],
						   LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_WEIGHT], (F32*)(base + mOffsets[TYPE_WEIGHT]));

		if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_BUMP)
		{
			set_binormals(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL],
						  LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_BINORMAL], (LLVector3*)(base + mOffsets[TYPE_BINORMAL]));
		}
	
		if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH)
		{
			set_vertex_clothing_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING],
										LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_CLOTHWEIGHT], (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
		}
	}
	else
	{
		LLVertexBuffer::setupVertexBuffer(data_mask);
	}
}
コード例 #9
0
ファイル: llvertexbuffer.cpp プロジェクト: xinyaojiejie/Dale
void LLVertexBuffer::createGLIndices()
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	U32 size = getIndicesSize();

	if (mGLIndices)
	{
		destroyGLIndices();
	}
	
	if (size == 0)
	{
		return;
	}

	mMappedIndexData = new U8[size];
	memset(mMappedIndexData, 0, size);
	mEmpty = TRUE;

	if (useVBOs())
	{
		glGenBuffersARB(1, (GLuint*) &mGLIndices);
		mResized = TRUE;
		sGLCount++;
	}
	else
	{
		static int gl_buffer_idx = 0;
		mGLIndices = ++gl_buffer_idx;
	}
}
コード例 #10
0
void LLVertexBuffer::createGLIndices()
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	U32 size = getIndicesSize();

	if (mGLIndices)
	{
		destroyGLIndices();
	}
	
	if (size == 0)
	{
		return;
	}

	mEmpty = TRUE;

	if (useVBOs())
	{
		mMappedIndexData = NULL;
		genIndices();
		mResized = TRUE;
	}
	else
	{
		mMappedIndexData = new U8[size];
		if(!sOmitBlank) memset((void*)mMappedIndexData, 0, size);
		static int gl_buffer_idx = 0;
		mGLIndices = ++gl_buffer_idx;
	}
}
コード例 #11
0
void LLVertexBuffer::destroyGLBuffer()
{
	LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_BUFFER);
	if (mGLBuffer)
	{
		if (useVBOs())
		{
			freeClientBuffer() ;

			if (mMappedData || mMappedIndexData)
			{
				llerrs << "Vertex buffer destroyed while mapped!" << llendl;
			}
			releaseBuffer();
		}
		else
		{
			delete [] mMappedData;
			mMappedData = NULL;
			mEmpty = TRUE;
		}

		sAllocatedBytes -= getSize();
	}
	
	mGLBuffer = 0;
	unbind();
}
コード例 #12
0
ファイル: llvertexbuffer.cpp プロジェクト: xinyaojiejie/Dale
// Map for data access
U8* LLVertexBuffer::mapBuffer(S32 access)
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	if (sRenderActive)
	{
		llwarns << "Buffer mapped during render frame!" << llendl;
	}
	if (!mGLBuffer && !mGLIndices)
	{
		llerrs << "LLVertexBuffer::mapBuffer() called  before createGLBuffer" << llendl;
	}
	if (mFinal)
	{
		llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
	}
	if (!mMappedData && !mMappedIndexData)
	{
		llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
	}
	
	if (!mLocked && useVBOs())
	{
		mLocked = TRUE;
		sLockedList.push_back(this);
	}
	
	return mMappedData;
}
コード例 #13
0
void LLVertexBuffer::createGLBuffer()
{
	LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_VERTICES);
	
	U32 size = getSize();
	if (mGLBuffer)
	{
		destroyGLBuffer();
	}

	if (size == 0)
	{
		return;
	}

	mEmpty = TRUE;

	if (useVBOs())
	{
		mMappedData = NULL;
		genBuffer();
		mResized = TRUE;
	}
	else
	{
		static int gl_buffer_idx = 0;
		mGLBuffer = ++gl_buffer_idx;
		mMappedData = new U8[size];
		memset(mMappedData, 0, size);
	}
}
コード例 #14
0
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
	llassert(mRequestedNumVerts >= 0);

	if (first >= (U32) mRequestedNumVerts ||
	    first + count > (U32) mRequestedNumVerts)
	{
		llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl;
	}

	if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
	{
		llerrs << "Wrong vertex buffer bound." << llendl;
	}

	if (mode >= LLRender::NUM_MODES)
	{
		llerrs << "Invalid draw mode: " << mode << llendl;
		return;
	}

	stop_glerror();
	glDrawArrays(sGLMode[mode], first, count);
	stop_glerror();
}
    void operator()(ResourceDatabase* db)
    {
      if (stripfy())
        setRemoveDoubles(true);

      std::vector< vl::ref<vl::Geometry> > geom;
      db->get<Geometry>(geom);
      for(unsigned int i=0; i<geom.size(); ++i)
      {
        if (discardOriginalNormals())
          geom[i]->setNormalArray(NULL);

        if (computeNormals() && !geom[i]->normalArray())
          geom[i]->computeNormals();

        if (removeDoubles())
          DoubleVertexRemover().removeDoubles(geom[i].get());

        if (sortVertices())
          geom[i]->sortVertices();

        if (stripfy())
          TriangleStripGenerator().stripfy(geom[i].get(), 22, true, false, true);

        if (convertToDrawArrays())
          geom[i]->convertDrawCallToDrawArrays();

        geom[i]->setDisplayListEnabled(useDisplayLists());
        geom[i]->setVBOEnabled(useVBOs());

        if (transformGeometry())
          geom[i]->transform(transformMatrix(),true);
      }
    }
コード例 #16
0
ファイル: llvertexbuffer.cpp プロジェクト: xinyaojiejie/Dale
void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count)
{
	if (useVBOs() && !mFilthy)
	{
		if (!mDirtyRegions.empty())
		{
			DirtyRegion& region = *(mDirtyRegions.rbegin());
			
			if (region.mIndex+region.mCount > vert_index)
			{
				//this buffer has received multiple updates since the last copy, mark it filthy
				mFilthy = TRUE;
				mDirtyRegions.clear();
				return;
			}
			
			if (region.mIndex + region.mCount == vert_index &&
				region.mIndicesIndex + region.mIndicesCount == indices_index)
			{
				region.mCount += vert_count;
				region.mIndicesCount += indices_count;
				return;
			}
		}

		mDirtyRegions.push_back(DirtyRegion(vert_index,vert_count,indices_index,indices_count));
	}
}
コード例 #17
0
//----------------------------------------------------------------------------
void LLVertexBuffer::freeClientBuffer()
{
	if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData))
	{
		delete[] mMappedData ;
		delete[] mMappedIndexData ;
		mMappedData = NULL ;
		mMappedIndexData = NULL ;
	}
}
コード例 #18
0
//----------------------------------------------------------------------------
void LLVertexBuffer::freeClientBuffer()
{
	if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData))
	{
		ll_aligned_free_16((void*)mMappedData) ;
		ll_aligned_free_16((void*)mMappedIndexData) ;
		mMappedData = NULL ;
		mMappedIndexData = NULL ;
	}
}
コード例 #19
0
ファイル: llvertexbuffer.cpp プロジェクト: xinyaojiejie/Dale
// virtual (default)
void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	stop_glerror();
	U8* base = useVBOs() ? NULL : mMappedData;
	S32 stride = mStride;

	if ((data_mask & mTypeMask) != data_mask)
	{
		llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
	}

	if (data_mask & MAP_VERTEX)
	{
		glVertexPointer(3,GL_FLOAT, stride, (void*)(base + 0));
	}
	if (data_mask & MAP_NORMAL)
	{
		glNormalPointer(GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_NORMAL]));
	}
	if (data_mask & MAP_TEXCOORD2)
	{
		glClientActiveTextureARB(GL_TEXTURE1_ARB);
		glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD2]));
	}
	if (data_mask & MAP_TEXCOORD)
	{
		glClientActiveTextureARB(GL_TEXTURE0_ARB);
		glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD]));
	}
	if (data_mask & MAP_COLOR)
	{
		glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)(base + mOffsets[TYPE_COLOR]));
	}
	if (data_mask & MAP_BINORMAL)
	{
		glVertexAttribPointerARB(6, 3, GL_FLOAT, FALSE,  stride, (void*)(base + mOffsets[TYPE_BINORMAL]));
	}
	if (data_mask & MAP_WEIGHT)
	{
		glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT]));
	}
	if (data_mask & MAP_CLOTHWEIGHT)
	{
		glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE,  stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
	}

	llglassertok();
}
コード例 #20
0
ファイル: llvertexbuffer.cpp プロジェクト: xinyaojiejie/Dale
void LLVertexBuffer::makeStatic()
{
	if (!sEnableVBOs)
	{
		return;
	}
	
	if (sRenderActive)
	{
		llerrs << "Make static called during render." << llendl;
	}
	
	if (mUsage != GL_STATIC_DRAW_ARB)
	{
		if (useVBOs())
		{
			if (mGLBuffer)
			{
				sDeleteList.push_back(mGLBuffer);
			}
			if (mGLIndices)
			{
				sDeleteList.push_back(mGLIndices);
			}
		}
	
		if (mGLBuffer)
		{
			sGLCount++;
			glGenBuffersARB(1, (GLuint*) &mGLBuffer);
		}
		if (mGLIndices)
		{
			sGLCount++;
			glGenBuffersARB(1, (GLuint*) &mGLIndices);
		}
			
		mUsage = GL_STATIC_DRAW_ARB;
		mResized = TRUE;

		if (!mLocked)
		{
			mLocked = TRUE;
			sLockedList.push_back(this);
		}
	}
}
コード例 #21
0
ファイル: llvertexbuffer.cpp プロジェクト: xinyaojiejie/Dale
void LLVertexBuffer::destroyGLIndices()
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	if (mGLIndices)
	{
		if (useVBOs())
		{
			sDeleteList.push_back(mGLIndices);
		}
		
		delete [] mMappedIndexData;
		mMappedIndexData = NULL;
		mEmpty = TRUE;
		sAllocatedBytes -= getIndicesSize();
	}

	mGLIndices = 0;
}
コード例 #22
0
void LLVertexBuffer::unmapBuffer()
{
    LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
    if (mMappedData || mMappedIndexData)
    {
        if (useVBOs() && mLocked)
        {
            stop_glerror();
            glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
            stop_glerror();
            glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
            stop_glerror();

            /*if (!sMapped)
            {
            	llwarns << "Redundantly unmapped VBO!" << llendl;
            }
            sMapped = FALSE;*/
            sMappedCount--;

            if (mUsage == GL_STATIC_DRAW_ARB)
            {   //static draw buffers can only be mapped a single time
                //throw out client data (we won't be using it again)
                mEmpty = TRUE;
                mFinal = TRUE;
            }
            else
            {
                mEmpty = FALSE;
            }

            mMappedIndexData = NULL;
            mMappedData = NULL;

            mLocked = FALSE;
        }
    }
}
コード例 #23
0
void LLVertexBuffer::createGLIndices()
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	U32 size = getIndicesSize();

	if (mGLIndices)
	{
		destroyGLIndices();
	}
	
	if (size == 0)
	{
		return;
	}

	mEmpty = TRUE;

	//pad by 16 bytes for aligned copies
	size += 16;

	if (useVBOs())
	{
		//pad by another 16 bytes for VBO pointer adjustment
		size += 16;
		mMappedIndexData = NULL;
		genIndices();
		mResized = TRUE;
	}
	else
	{
		mMappedIndexData = (U8*) ll_aligned_malloc_16(size);
		if(!sOmitBlank) memset((void*)mMappedIndexData, 0, size);
		static int gl_buffer_idx = 0;
		mGLIndices = ++gl_buffer_idx;
	}
}
コード例 #24
0
ファイル: llvertexbuffer.cpp プロジェクト: xinyaojiejie/Dale
// Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask)
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	//set up pointers if the data mask is different ...
	BOOL setup = (sLastMask != data_mask);

	if (useVBOs())
	{
		if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))
		{
			glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
			sVBOActive = TRUE;
			setup = TRUE; // ... or the bound buffer changed
		}
		if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))
		{
			glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
			sIBOActive = TRUE;
		}
		
		unmapBuffer();
	}
	else
	{		
		if (mGLBuffer)
		{
			if (sEnableVBOs && sVBOActive)
			{
				glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
				sVBOActive = FALSE;
				setup = TRUE; // ... or a VBO is deactivated
			}
			if (sGLRenderBuffer != mGLBuffer)
			{
				setup = TRUE; // ... or a client memory pointer changed
			}
		}
		if (sEnableVBOs && mGLIndices && sIBOActive)
		{
			glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
			sIBOActive = FALSE;
		}
	}
	
	if (mGLIndices)
	{
		sGLRenderIndices = mGLIndices;
	}
	if (mGLBuffer)
	{
		sGLRenderBuffer = mGLBuffer;
		if (data_mask && setup)
		{
			if (!sRenderActive)
			{
				llwarns << "Vertex buffer set for rendering outside of render frame." << llendl;
			}
			setupVertexBuffer(data_mask); // subclass specific setup (virtual function)
			sLastMask = data_mask;
		}
	}
}
コード例 #25
0
ファイル: llvertexbuffer.cpp プロジェクト: xinyaojiejie/Dale
void LLVertexBuffer::unmapBuffer()
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	if (mMappedData || mMappedIndexData)
	{
		if (useVBOs() && mLocked)
		{
			if (mGLBuffer)
			{
				if (mResized)
				{
					glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), mMappedData, mUsage);
				}
				else
				{
					if (mEmpty || mDirtyRegions.empty())
					{
						glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
					}
					else
					{
						for (std::vector<DirtyRegion>::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i)
						{
							DirtyRegion& region = *i;
							glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, region.mIndex*mStride, region.mCount*mStride, mMappedData + region.mIndex*mStride);
						}
					}
				}
			}
			
			if (mGLIndices)
			{
				if (mResized)
				{
					glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), mMappedIndexData, mUsage);
				}
				else
				{
					if (mEmpty || mDirtyRegions.empty())
					{
						glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
					}
					else
					{
						for (std::vector<DirtyRegion>::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i)
						{
							DirtyRegion& region = *i;
							glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, region.mIndicesIndex*sizeof(U32), 
								region.mIndicesCount*sizeof(U32), mMappedIndexData + region.mIndicesIndex*sizeof(U32));
						}
					}
				}
			}

			mDirtyRegions.clear();
			mFilthy = FALSE;
			mResized = FALSE;

			if (mUsage == GL_STATIC_DRAW_ARB)
			{ //static draw buffers can only be mapped a single time
				//throw out client data (we won't be using it again)
				delete [] mMappedData;
				delete [] mMappedIndexData;
				mMappedIndexData = NULL;
				mMappedData = NULL;
				mEmpty = TRUE;
				mFinal = TRUE;
			}
			else
			{
				mEmpty = FALSE;
			}
			
			mLocked = FALSE;
			
			glFlush();
		}
	}
}
コード例 #26
0
// Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	//set up pointers if the data mask is different ...
	BOOL setup = (sLastMask != data_mask);

	if (useVBOs())
	{
		if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))
		{
			/*if (sMapped)
			{
				llerrs << "VBO bound while another VBO mapped!" << llendl;
			}*/
			stop_glerror();
			glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
			stop_glerror();
			sBindCount++;
			sVBOActive = TRUE;
			setup = TRUE; // ... or the bound buffer changed
		}
		if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))
		{
			/*if (sMapped)
			{
				llerrs << "VBO bound while another VBO mapped!" << llendl;
			}*/
			stop_glerror();
			glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
			stop_glerror();
			sBindCount++;
			sIBOActive = TRUE;
		}
		
		BOOL error = FALSE;
		if (gDebugGL)
		{
			GLint buff;
			glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
			if ((GLuint)buff != mGLBuffer)
			{
				llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
			}

			if (mGLIndices)
			{
				glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
				if ((GLuint)buff != mGLIndices)
				{
					llerrs << "Invalid GL index buffer bound: " << buff << llendl;
				}
			}
		}

		if (mResized)
		{
			if (gDebugGL)
			{
				GLint buff;
				glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
				if ((GLuint)buff != mGLBuffer)
				{
					llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
				}

				if (mGLIndices != 0)
				{
					glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
					if ((GLuint)buff != mGLIndices)
					{
						llerrs << "Invalid GL index buffer bound: " << buff << llendl;
					}
				}
			}

			if (mGLBuffer)
			{
				stop_glerror();
				glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage);
				stop_glerror();
			}
			if (mGLIndices)
			{
				stop_glerror();
				glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage);
				stop_glerror();
			}

			mEmpty = TRUE;
			mResized = FALSE;

			if (data_mask != 0)
			{
				llerrs << "Buffer set for rendering before being filled after resize." << llendl;
			}
		}

		if (error)
		{
			llerrs << "LLVertexBuffer::mapBuffer failed" << llendl;
		}
		unmapBuffer(type);
	}
	else
	{		
		if (mGLBuffer)
		{
			if (sVBOActive)
			{
				glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
				sBindCount++;
				sVBOActive = FALSE;
				setup = TRUE; // ... or a VBO is deactivated
			}
			if (sGLRenderBuffer != mGLBuffer)
			{
				setup = TRUE; // ... or a client memory pointer changed
			}
		}
		if (mGLIndices && sIBOActive)
		{
			/*if (sMapped)
			{
				llerrs << "VBO unbound while potentially mapped!" << llendl;
			}*/
			glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
			sBindCount++;
			sIBOActive = FALSE;
		}
	}

	setupClientArrays(data_mask);
	
	if (mGLIndices)
	{
		sGLRenderIndices = mGLIndices;
	}
	if (mGLBuffer)
	{
		sGLRenderBuffer = mGLBuffer;
		if (data_mask && setup)
		{
			setupVertexBuffer(data_mask); // subclass specific setup (virtual function)
			sSetCount++;
		}
	}
}
コード例 #27
0
void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
{
	mRequestedNumVerts = newnverts;
	mRequestedNumIndices = newnindices;

	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	mDynamicSize = TRUE;
	if (mUsage == GL_STATIC_DRAW_ARB)
	{ //always delete/allocate static buffers on resize
		destroyGLBuffer();
		destroyGLIndices();
		allocateBuffer(newnverts, newnindices, TRUE);
		mFinal = FALSE;
	}
	else if (newnverts > mNumVerts || newnindices > mNumIndices ||
			 newnverts < mNumVerts/2 || newnindices < mNumIndices/2)
	{
		sAllocatedBytes -= getSize() + getIndicesSize();
		
		S32 oldsize = getSize();
		S32 old_index_size = getIndicesSize();

		updateNumVerts(newnverts);		
		updateNumIndices(newnindices);
		
		S32 newsize = getSize();
		S32 new_index_size = getIndicesSize();

		sAllocatedBytes += newsize + new_index_size;

		if (newsize)
		{
			if (!mGLBuffer)
			{ //no buffer exists, create a new one
				createGLBuffer();
			}
			else
			{
				//delete old buffer, keep GL buffer for now
				if (!useVBOs())
				{
					volatile U8* old = mMappedData;
					mMappedData = new U8[newsize];
					if (old)
					{	
						memcpy((void*)mMappedData, (void*)old, llmin(newsize, oldsize));
						if ((newsize > oldsize) && !sOmitBlank)
						{
							memset((void*)(mMappedData+oldsize), 0, newsize-oldsize);
						}

						delete [] old;
					}
					else
					{
						if (!sOmitBlank) memset((void*)mMappedData, 0, newsize);
						mEmpty = TRUE;
					}
				}
				mResized = TRUE;
			}
		}
		else if (mGLBuffer)
		{
			destroyGLBuffer();
		}
		
		if (new_index_size)
		{
			if (!mGLIndices)
			{
				createGLIndices();
			}
			else
			{
				if (!useVBOs())
				{
					//delete old buffer, keep GL buffer for now
					volatile U8* old = mMappedIndexData;
					mMappedIndexData = new U8[new_index_size];
					
					if (old)
					{	
						memcpy((void*)mMappedIndexData, (void*)old, llmin(new_index_size, old_index_size));
						if ((new_index_size > old_index_size) && !sOmitBlank)
						{
							memset((void*)(mMappedIndexData+old_index_size), 0, new_index_size - old_index_size);
						}
						delete [] old;
					}
					else
					{
						if (!sOmitBlank) memset((void*)mMappedIndexData, 0, new_index_size);
						mEmpty = TRUE;
					}
				}
				mResized = TRUE;
			}
		}
		else if (mGLIndices)
		{
			destroyGLIndices();
		}
	}

	if (mResized && useVBOs())
	{
		freeClientBuffer() ;
		setBuffer(0);
	}
}
コード例 #28
0
void LLVertexBuffer::unmapBuffer(S32 type)
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	if (!useVBOs())
	{
		return ; //nothing to unmap
	}

	bool updated_all = false ;
	if (mMappedData && mVertexLocked && type != TYPE_INDEX)
	{
		updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating

		if(sDisableVBOMapping)
		{
			stop_glerror();
			glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (void*)mMappedData);
			stop_glerror();
		}
		else
		{
			stop_glerror();
			glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
			stop_glerror();

			mMappedData = NULL;
		}

		mVertexLocked = FALSE ;
		sMappedCount--;
	}

	if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX))
	{
		if(sDisableVBOMapping)
		{
			stop_glerror();
			glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (void*)mMappedIndexData);
			stop_glerror();
		}
		else
		{
			stop_glerror();
			glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
			stop_glerror();

			mMappedIndexData = NULL ;
		}

		mIndexLocked = FALSE ;
		sMappedCount--;
	}

	if(updated_all)
	{
		if(mUsage == GL_STATIC_DRAW_ARB)
		{
			//static draw buffers can only be mapped a single time
			//throw out client data (we won't be using it again)
			mEmpty = TRUE;
			mFinal = TRUE;

			if(sDisableVBOMapping)
			{
				freeClientBuffer() ;
			}
		}
		else
		{
			mEmpty = FALSE;
		}
	}
}
コード例 #29
0
// virtual (default)
void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	stop_glerror();
	volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;

	if ((data_mask & mTypeMask) != data_mask)
	{
		llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask. Missing: ";

		static const char* mask_names[] = {"VERTEX","NORMAL","TEXCOORD0","TEXCOORD1","TEXCOORD2","TEXCOORD3","COLOR","BINORMAL","WEIGHT","WEIGHT4","CLOTH_WEIGHT"};
		for(int i = 0; i < 32; ++i)
		{
			if((data_mask & (1<<i)) && !(mTypeMask & (1<<i)))
			{
				if(i < (sizeof(mask_names)/sizeof(mask_names[0])))
					llcont << "MAP_" << mask_names[i] << ", ";
				else
					llcont << "MAP_UNKNOWN (1<<" << i << "), ";
			}
		}
		llcont << "\n Has: ";
		for(int i = 0; i < 32; ++i)
		{
			if(mTypeMask & (1<<i))
			{
				if(i < (sizeof(mask_names)/sizeof(mask_names[0])))
					llcont << "MASK_" << mask_names[i] << ", ";
				else
					llcont << "MAP_UNKNOWN (1<<" << i << "), ";
			}
		}
		llcont << llendl;
	}

	if (data_mask & MAP_NORMAL)
	{
		glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL]));
	}
	if (data_mask & MAP_TEXCOORD3)
	{
		glClientActiveTextureARB(GL_TEXTURE3_ARB);
		glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD3), (void*)(base + mOffsets[TYPE_TEXCOORD3]));
		glClientActiveTextureARB(GL_TEXTURE0_ARB);
	}
	if (data_mask & MAP_TEXCOORD2)
	{
		glClientActiveTextureARB(GL_TEXTURE2_ARB);
		glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD2), (void*)(base + mOffsets[TYPE_TEXCOORD2]));
		glClientActiveTextureARB(GL_TEXTURE0_ARB);
	}
	if (data_mask & MAP_TEXCOORD1)
	{
		glClientActiveTextureARB(GL_TEXTURE1_ARB);
		glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD1), (void*)(base + mOffsets[TYPE_TEXCOORD1]));
		glClientActiveTextureARB(GL_TEXTURE0_ARB);
	}
	if (data_mask & MAP_BINORMAL)
	{
		glClientActiveTextureARB(GL_TEXTURE2_ARB);
		glTexCoordPointer(3,GL_FLOAT, getStride(TYPE_BINORMAL), (void*)(base + mOffsets[TYPE_BINORMAL]));
		glClientActiveTextureARB(GL_TEXTURE0_ARB);
	}
	if (data_mask & MAP_TEXCOORD0)
	{
		glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0]));
	}
	if (data_mask & MAP_COLOR)
	{
		glColorPointer(4, GL_UNSIGNED_BYTE, getStride(TYPE_COLOR), (void*)(base + mOffsets[TYPE_COLOR]));
	}
	
	if (data_mask & MAP_WEIGHT)
	{
		glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT), (void*)(base + mOffsets[TYPE_WEIGHT]));
	}

	if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1)
	{
		glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT4), (void*)(base+mOffsets[TYPE_WEIGHT4]));
	}

	if (data_mask & MAP_CLOTHWEIGHT)
	{
		glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE,  getStride(TYPE_CLOTHWEIGHT), (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
	}
	if (data_mask & MAP_VERTEX)
	{
		glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0));
	}

	llglassertok();
}
コード例 #30
0
// Map for data access
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
{
	LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
	if (mFinal)
	{
		llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl;
	}
	if (!useVBOs() && !mMappedData && !mMappedIndexData)
	{
		llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl;
	}
		
	if (!mVertexLocked && useVBOs())
	{
		{
			setBuffer(0, type);
			mVertexLocked = TRUE;
			stop_glerror();	

			if(sDisableVBOMapping)
			{
				allocateClientVertexBuffer() ;
			}
			else
			{
				mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
			}
			stop_glerror();
		}
		
		if (!mMappedData)
		{
			if(!sDisableVBOMapping)
			{
				//--------------------
				//print out more debug info before crash
				llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
				GLint size ;
				glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
				llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
				//--------------------

				GLint buff;
				glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
				if ((GLuint)buff != mGLBuffer)
				{
					llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
				}

				
				llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
			}
			else
			{
				llerrs << "memory allocation for vertex data failed." << llendl ;
			}
		}
		sMappedCount++;
	}
	
	return mMappedData;
}