void* GLES2HardwareVertexBuffer::lockImpl(size_t offset,
                                           size_t length,
                                           LockOptions options)
    {
        if (mIsLocked)
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
                        "Invalid attempt to lock an index buffer that has already been locked",
                        "GLES2HardwareVertexBuffer::lock");
        }

        GLenum access = 0;

        // Use glMapBuffer
        static_cast<GLES2HardwareBufferManagerBase*>(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ARRAY_BUFFER, mBufferId);

        void* pBuffer;
#if OGRE_NO_GLES3_SUPPORT == 0 || defined(GL_EXT_map_buffer_range)
        if (mUsage & HBU_WRITE_ONLY)
        {
            access = GL_MAP_WRITE_BIT_EXT;
            access |= GL_MAP_FLUSH_EXPLICIT_BIT_EXT;
            if(options == HBL_DISCARD || options == HBL_NO_OVERWRITE)
            {
                // Discard the buffer
                access |= GL_MAP_INVALIDATE_RANGE_BIT_EXT;
            }
            access |= GL_MAP_UNSYNCHRONIZED_BIT_EXT;
        }
        else if (options == HBL_READ_ONLY)
            access = GL_MAP_READ_BIT_EXT;
        else
            access = GL_MAP_READ_BIT_EXT | GL_MAP_WRITE_BIT_EXT;

        OGRE_CHECK_GL_ERROR(pBuffer = glMapBufferRangeEXT(GL_ARRAY_BUFFER, offset, length, access));
#else
        if(options == HBL_DISCARD || options == HBL_NO_OVERWRITE)
        {
            // Discard the buffer
            OGRE_CHECK_GL_ERROR(glBufferData(GL_ARRAY_BUFFER, mSizeInBytes, NULL,
                                             GLES2HardwareBufferManager::getGLUsage(mUsage)));
        }
        if (mUsage & HBU_WRITE_ONLY)
            access = GL_WRITE_ONLY_OES;

        OGRE_CHECK_GL_ERROR(pBuffer = glMapBufferOES(GL_ARRAY_BUFFER, access));
#endif

        if(pBuffer == 0)
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
                        "Vertex Buffer: Out of memory", "GLES2HardwareVertexBuffer::lock");
        }

        // return offsetted
        void* retPtr = static_cast<void*>(
                                    static_cast<unsigned char*>(pBuffer) + offset);

		mIsLocked = true;
        return retPtr;
    }
    void* GLESHardwareVertexBuffer::lockImpl(size_t offset,
                                           size_t length,
                                           LockOptions options)
    {
        GLenum access = 0;

        if (mIsLocked)
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
                        "Invalid attempt to lock an index buffer that has already been locked",
                        "GLESHardwareVertexBuffer::lock");
        }

        void* retPtr = 0;

		GLESHardwareBufferManager* glBufManager = static_cast<GLESHardwareBufferManager*>(HardwareBufferManager::getSingletonPtr());

		// Try to use scratch buffers for smaller buffers
        if (length < glBufManager->getGLMapBufferThreshold())
        {
			// if this fails, we fall back on mapping
            retPtr = glBufManager->allocateScratch((uint32)length);

            if (retPtr)
            {
                mLockedToScratch = true;
                mScratchOffset = offset;
                mScratchSize = length;
                mScratchPtr = retPtr;
                mScratchUploadOnUnlock = (options != HBL_READ_ONLY);

                if (options != HBL_DISCARD)
                {
					// have to read back the data before returning the pointer
                    readData(offset, length, retPtr);
                }
            }
        }
        else
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
                        "Invalid Buffer lockSize",
                        "GLESHardwareVertexBuffer::lock");
        }

#if GL_OES_mapbuffer
        if (!retPtr)
		{
			// Use glMapBuffer
			glBindBuffer( GL_ARRAY_BUFFER, mBufferId );
			// Use glMapBuffer
			if(options == HBL_DISCARD)
			{
				// Discard the buffer
				glBufferData(GL_ARRAY_BUFFER, mSizeInBytes, NULL, 
                                GLESHardwareBufferManager::getGLUsage(mUsage));
                
			}
			if (mUsage & HBU_WRITE_ONLY)
				access = GL_WRITE_ONLY_OES;
            
			void* pBuffer = glMapBufferOES( GL_ARRAY_BUFFER, access);
            
			if(pBuffer == 0)
			{
				OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
                            "Vertex Buffer: Out of memory", "GLESHardwareVertexBuffer::lock");
			}
            
			// return offsetted
			retPtr = static_cast<void*>(
				static_cast<unsigned char*>(pBuffer) + offset);
            
			mLockedToScratch = false;
		}
#endif
		mIsLocked = true;
        return retPtr;
    }
Exemple #3
0
bool AppCore::render()
{	
#if !DISCARD_SKYBOX
	// Try to load textures if not already completed
	if (_staticTextureCompleteCount <= 6) loadStaticTextureIfAvailable();
#endif

	APIFactory::GetInstance().lock(OPENGL_LOCK);
	
	double timestamp = APIFactory::GetInstance().getTimeInMS();
	
#if !(RENDER_OCTREE_DEBUG_VOXELS || USE_STATIC_POINT_CLOUD)
	if		(   !(_currentCameraParameterRequest & 1) && 
				 (timestamp - _lastCameraParameterChangeTimestamp > WVS_RELOAD_DELAY[0]))
	{
		// Request 1/4 of screen resolution from WVS
		requestPointCloudForCurrentView(4);
		_currentCameraParameterRequest |= 1;
	}
	else if	(   !(_currentCameraParameterRequest & 2) && 
				 (timestamp - _lastCameraParameterChangeTimestamp > WVS_RELOAD_DELAY[1]))
	{
		// Request full screen resolution from WVS
		requestPointCloudForCurrentView(1);
		_currentCameraParameterRequest |= 3;
	}
#endif

	if (_isUserInputMode) _renderingRequired = true;
	if (_renderQuality < 1.0f) _renderingRequired = true;

#if !(RENDER_OCTREE_DEBUG_VOXELS || USE_STATIC_POINT_CLOUD)
	if (_isNewDataAvialable)
	{
		_renderingRequired = true;
		_isNewDataAvialable = false;
	}
#endif

	if (!_renderingRequired)
	{
		APIFactory::GetInstance().unlock(OPENGL_LOCK);
		APIFactory::GetInstance().processUserInterfaceEvents();
		return false;
	}
	_renderingRequired = false;
	
	// Updates the view frustum that is used for culling etc. based on the current
	// camera parameters
	_viewFrustum->updateCameraViewParameterCache();
	
	// Clear context
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
#if !DISCARD_SKYBOX
	// Render Skybox and ground plane
	if (_staticTextureCompleteCount > 0)
	{
		glUseProgram(_textureShaderProgram.handle);

		glUniformMatrix4fv(	_textureShaderProgram.uniforms[SHADER_UNIFORM_VIEW_PROJECTION_MATRIX],
							1, GL_FALSE, _viewFrustum->getViewProjectionMatrixCachePtr()->f);
							
		MATRIX model;
		MatrixTranslation(model,	_viewFrustum->getCameraPostionCachePtr()->x,
									_viewFrustum->getCameraPostionCachePtr()->y,
									_viewFrustum->getCameraPostionCachePtr()->z);
		glUniformMatrix4fv(	_textureShaderProgram.uniforms[SHADER_UNIFORM_MODEL_MATRIX],
							1, GL_FALSE, model.f);
		
		_skybox->render();
	}
#endif

	// Render points
    glUseProgram(_pointShaderProgram.handle);

	glUniform3fv(	_pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_REGION_ORIGIN],
					OCTREE_LEAF_LEVEL + 1, _octree->getRegionOrginArray());
	
	glUniform1fv(	_pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_VOXEL_INCIRCLE_DIAMETER],
					OCTREE_LEAF_LEVEL + 1,
					_octree->getVoxelIncircleDiameterArray());

	glUniform1fv(	_pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_NODE_INCIRCLE_DIAMETER],
					OCTREE_LEAF_LEVEL + 1,
					_octree->getNodeIncircleDiameterArray());
					
	glUniform1fv(	_pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_VOXEL_SCREENSIZE_CIRCUMCIRCLE_RADIUS],
					OCTREE_LEAF_LEVEL + 1,
					_voxelScreensizeCircumcircleRadius);
						
	// Set camera position (necessary for backface culling)
	glUniform3fv(	_pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_CAMERA_POSITION],
					1, (GLfloat*)(_viewFrustum->getCameraPostionCachePtr()));
					
	glUniformMatrix4fv(	_pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_PROJECTION_MATRIX],
						1, GL_FALSE, _viewFrustum->getProjectionMatrixCachePtr()->f);
						
	glUniformMatrix4fv(	_pointShaderProgram.uniforms[POINT_SHADER_UNIFORM_VIEW_MATRIX],
						1, GL_FALSE, _viewFrustum->getViewMatrixCachePtr()->f);
												

#if COMPACT_NODE_REGION_ENCODING
	const uint32_t regionVoxelFactor = 1;
	const uint8_t regionLevelStride = 4;
	const uint32_t regionLevelDataType = GL_UNSIGNED_BYTE;
#else
	const uint32_t regionVoxelFactor = 2;
	const uint8_t regionLevelStride = 8;
	const uint32_t regionLevelDataType = GL_UNSIGNED_SHORT;
#endif

#if DIRECT_VBO
	#if DIRECT_VBO_DOUBLE_BUFFERED	
	if (bufferID == 0) bufferID = 1; else bufferID = 0;
	#endif

	glBindBuffer(GL_ARRAY_BUFFER, _dataVBO[bufferID]);
	uint32_t* const gpuBuffer = (uint32_t*)glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);

	uint32_t* const regionLevelBuffer = gpuBuffer;
	uint32_t* const voxelBuffer = gpuBuffer + GPU_MAX_POINTS * regionVoxelFactor;
	
	glVertexAttribPointer(	POINT_SHADER_ATTRIBUTE_DATA1,
							4,
							GL_UNSIGNED_BYTE,
							GL_FALSE,
							0,
							(void *)(GPU_MAX_POINTS * regionLevelStride));
							
	glVertexAttribPointer(	POINT_SHADER_ATTRIBUTE_DATA2,
							4,
							regionLevelDataType,
							GL_FALSE,
							0,
							0);	

	glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1);	
	glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2);

	// Traverse octree, copy points into buffer and call rendering callback 
	_octree->copyPointsToBuffer(
		_renderQuality,
		!_isInteractiveMode,
		regionLevelBuffer,
		voxelBuffer,
		&_pointsToRenderCount,
		&_renderingRequired);
	
	glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1);
	glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2);
	
	glUnmapBufferOES(GL_ARRAY_BUFFER);
		
#elif NO_VBO
	uint32_t* const regionLevelBuffer = _gpuBuffer;
	uint32_t* const voxelBuffer = _gpuBuffer + GPU_MAX_POINTS * regionVoxelFactor;
	
	glVertexAttribPointer(	POINT_SHADER_ATTRIBUTE_DATA1, 
							4,
							GL_UNSIGNED_BYTE,
							GL_FALSE,
							4,
							voxelBuffer);
							
	glVertexAttribPointer(	POINT_SHADER_ATTRIBUTE_DATA2,
							4,
							regionLevelDataType,
							GL_FALSE,
							regionLevelStride,
							regionLevelBuffer);	

	glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1);	
	glEnableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2);
	
	// Traverse octree, copy points into buffer and call rendering callback 	
	_octree->copyPointsToBuffer(
		_renderQuality,
		!_isInteractiveMode,
		regionLevelBuffer,
		voxelBuffer,
		&_pointsToRenderCount,
		&_renderingRequired);	

	glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA1);
	glDisableVertexAttribArray(POINT_SHADER_ATTRIBUTE_DATA2);	
	
#endif
		
#ifdef OPENGL_ES
	const GLenum discard_attachments[] = { GL_DEPTH_ATTACHMENT };
	glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discard_attachments);
#endif

	if (_renderingRequired & Octree::OCTREE_RENDERING_CANCELED)
	{
		APIFactory::GetInstance().unlock(OPENGL_LOCK);
		
		//TODO: In case we overestimate the render quality by far this becomes a stupid loop
		_octree->estimateInteractiveRenderQuality(&_renderQuality, OCTREE_INTERACTIVE_RENDERING_POINT_THRESHOLD);
		return false;
	}

#if BENCHMARK_1_MILLION
	if (_pointsToRenderCount >= 1000000)
	{
		_renderingRequired = true;
		double time = APIFactory::GetInstance().getTimeInMS();
		printf("%f\n", time - _lastFrame);
		_lastFrame = time;
	}
#endif

	if (_isUserInputMode || ((timestamp - _lastCameraParameterChangeTimestamp) < 500))
	{
		// Within 500ms we consider any input as movement
		double_t renderingTimeInMS = APIFactory::GetInstance().getTimeInMS() - timestamp;
		if (renderingTimeInMS > (1000.0 / MINIMUM_FRAMERATE))
		{
			// Time to render last frame took longer than target framerate.
			// Lower render quality to speed up framerate.
			_renderQuality -= RENDER_QUALITY_FINE_ADJUSTMENT;
			_nodeRestoreQuota = 0;
		}
		else if (renderingTimeInMS < (1000.0 / MAXIMUM_FRAMERATE))
		{
			_renderQuality += RENDER_QUALITY_FINE_ADJUSTMENT;
			_nodeRestoreQuota = 32;
		}
		
		_renderingRequired = true;
	}
	else
	{
		// No movement with in the last 500ms. Increase render quality
		_renderQuality += RENDER_QUALITY_COARSE_ADJUSTMENT;
		_isInteractiveMode = false;
	}

	// Check range of render quality
	if (_renderQuality > 1.0f) _renderQuality = 1.0f;
	else if (_renderQuality < RENDER_QUALITY_FINE_ADJUSTMENT)
		_renderQuality = RENDER_QUALITY_FINE_ADJUSTMENT;
	
	APIFactory::GetInstance().unlock(OPENGL_LOCK);
	
	return true;
}
void* GLESHardwareIndexBuffer::lockImpl(size_t offset,
                                        size_t length,
                                        LockOptions options)
{
    if(mIsLocked)
    {
        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
                    "Invalid attempt to lock an index buffer that has already been locked",
                    "GLESHardwareIndexBuffer::lock");
    }

    void* retPtr = 0;
    GLenum access = 0;
    GLESHardwareBufferManager* glBufManager = static_cast<GLESHardwareBufferManager*>(HardwareBufferManager::getSingletonPtr());

    if(length < glBufManager->getGLMapBufferThreshold())
    {
        retPtr = glBufManager->allocateScratch((uint32)length);
        if (retPtr)
        {
            mLockedToScratch = true;
            mScratchOffset = offset;
            mScratchSize = length;
            mScratchPtr = retPtr;
            mScratchUploadOnUnlock = (options != HBL_READ_ONLY);

            if (options != HBL_DISCARD)
            {
                readData(offset, length, retPtr);
            }
        }
    }
    else
    {
        OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
                    "Invalid Buffer lockSize",
                    "GLESHardwareIndexBuffer::lock");
    }

#if defined(GL_GLEXT_PROTOTYPES)
    if (!retPtr)
    {
        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mBufferId );
        // Use glMapBuffer
        if(options == HBL_DISCARD)
        {
            // Discard the buffer
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, mSizeInBytes, NULL,
                         GLESHardwareBufferManager::getGLUsage(mUsage));
        }
        if (mUsage & HBU_WRITE_ONLY)
            access = GL_WRITE_ONLY_OES;

        void* pBuffer = glMapBufferOES( GL_ELEMENT_ARRAY_BUFFER, access );

        if(pBuffer == 0)
        {
            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
                        "Index Buffer: Out of memory",
                        "GLESHardwareIndexBuffer::lock");
        }

        // return offsetted
        retPtr = static_cast<void*>(static_cast<unsigned char*>(pBuffer) + offset);

        mLockedToScratch = false;
    }
    mIsLocked = true;
#endif

    return retPtr;
}
Exemple #5
0
void* AEVAMap(AEVA* va, unsigned int elementCount, int writereadmode){
	unsigned int writereadmodeOGL = 0;
	switch (writereadmode) {
		case AEVAMapFlagWritable:
			#ifdef AEiOS
			writereadmodeOGL=GL_WRITE_ONLY_OES;
			#else
			writereadmodeOGL=GL_WRITE_ONLY;
			#endif
			break;
		case AEVAMapFlagReadable:
			#ifdef AEiOS
			return NULL;
			#else
			writereadmodeOGL=GL_READ_ONLY;
			#endif
			break;
		default:
			#ifdef AEiOS
			return NULL;
			#else
			writereadmodeOGL=GL_READ_WRITE;
			#endif
			break;
	}
	#ifdef AEiOS
	if(va->format.indexType==AEVAFormatIndexType32Bit) va->format.indexType=AEVAFormatIndexType16Bit;
	#endif
	unsigned int arrayType=va->format.indexType?GL_ELEMENT_ARRAY_BUFFER:GL_ARRAY_BUFFER;
	//if(sizeof(GLfloat) not_eq sizeof(char[4]) and sizeof(GLuint)!=sizeof(char[4])) AEError("A GLfloat or GLuint is not equal to 4 bytes on your system!  This is very, very, bad.");
	if(va->elementCount and va->elementCount not_eq elementCount) return NULL;
	//if(sizeof(AEVec3) not_eq 3*sizeof(float)) AEError("AEVec3 is padded, this is bad!");
	if(va->elementCount==0){
		va->elementCount=elementCount;
		#ifdef AEiOS
		if(va->format.storageType==AEVAFormatStorageTypeStream) va->format.storageType=0;
		#endif
		if(va->format.storageType){
			glGenBuffers(1, &va->data.vbo);
			//glBindBuffer(GL_ARRAY_BUFFER, va->data.vbo);
			
			unsigned int vbotype=0;

			switch(va->format.storageType){
				#ifndef AEiOS
				case AEVAFormatStorageTypeStream:
					vbotype=GL_STREAM_DRAW;
					break;
				#endif
				case AEVAFormatStorageTypeDynamic:
					vbotype=GL_DYNAMIC_DRAW;
					break;
				case AEVAFormatStorageTypeStatic:
					vbotype=GL_STATIC_DRAW;
					break;
			}
			glBindBuffer(arrayType, va->data.vbo);
			glBufferData(arrayType, elementCount * AEVAFormatByteSize(& va->format), NULL,vbotype);
			#ifdef AEiOS
			void* data = glMapBufferOES(arrayType, writereadmodeOGL);
			#else
			void* data = glMapBuffer(arrayType, writereadmodeOGL);
			#endif
			return data;
		}
		else va->data.pointer=malloc(elementCount * AEVAFormatByteSize(& va->format));
	}
	if(va->format.storageType){
		glBindBuffer(arrayType, va->data.vbo);
		#ifdef AEiOS
		return glMapBufferOES(arrayType, writereadmodeOGL);
		#else
		return glMapBuffer(arrayType, writereadmodeOGL);
		#endif
	}
	return va->data.pointer;
}