//-----------------------------------------------------------------------------
ParameterPtr Function::resolveInputParameter(Parameter::Semantic semantic,
										int index,
										const Parameter::Content content,
										GpuConstantType type)
{
	ParameterPtr param;

	// Check if desired parameter already defined.
	param = getParameterByContent(mInputParameters, content, type);
	if (param.get() != NULL)
		return param;

	// Case we have to create new parameter.
	if (index == -1)
	{
		index = 0;

		// Find the next available index of the target semantic.
		ShaderParameterIterator it;

		for (it = mInputParameters.begin(); it != mInputParameters.end(); ++it)
		{
			if ((*it)->getSemantic() == semantic)
			{
				index++;
			}
		}
	}
	else
	{
		// Check if desired parameter already defined.
		param = getParameterBySemantic(mInputParameters, semantic, index);
		if (param.get() != NULL && param->getContent() == content)
		{
			if (param->getType() == type)
			{
				return param;
			}
			else 
			{
				OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
					"Can not resolve parameter - semantic: " + StringConverter::toString(semantic) + " - index: " + StringConverter::toString(index) + " due to type mismatch. Function <" + getName() + ">", 			
					"Function::resolveInputParameter" );
			}
		}
	}

	

	// No parameter found -> create new one.
	switch (semantic)
	{
	case Parameter::SPS_POSITION:	
		assert(type == GCT_FLOAT4);
		param = ParameterFactory::createInPosition(index);
		break;
			
	case Parameter::SPS_BLEND_WEIGHTS:			
	case Parameter::SPS_BLEND_INDICES:
		OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
					"Can not resolve parameter - semantic: " + StringConverter::toString(semantic) + " - index: " + StringConverter::toString(index) + " since support in it is not implemented yet. Function <" + getName() + ">", 			
					"Function::resolveInputParameter" );
		break;
			
	case Parameter::SPS_NORMAL:
		assert(type == GCT_FLOAT3);
		param = ParameterFactory::createInNormal(index);
		break;
			
	case Parameter::SPS_COLOR:
		assert(type == GCT_FLOAT4);
		param = ParameterFactory::createInColor(index);
		break;
						
	case Parameter::SPS_TEXTURE_COORDINATES:		
		param = ParameterFactory::createInTexcoord(type, index, content);				
		break;
			
	case Parameter::SPS_BINORMAL:
		assert(type == GCT_FLOAT3);
		param = ParameterFactory::createInBiNormal(index);
		break;
			
	case Parameter::SPS_TANGENT:
		assert(type == GCT_FLOAT3);
		param = ParameterFactory::createInTangent(index);
		break;
	case Parameter::SPS_UNKNOWN:
        break;
	}

	if (param.get() != NULL)
		addInputParameter(param);

	return param;
}
    //---------------------------------------------------------------------
	size_t DeflateStream::read(void* buf, size_t count)
	{
		if (!mIsCompressedValid)
		{
			return mCompressedStream->read(buf, count);
		}
		
		if (getAccessMode() & WRITE)
		{
			return mTmpWriteStream->read(buf, count);
		}
		else 
		{

			size_t restorePoint = mCompressedStream->tell();
			// read from cache first
			size_t cachereads = mReadCache.read(buf, count);
			
			size_t newReadUncompressed = 0;

			if (cachereads < count)
			{
				mZStream->avail_out = count - cachereads;
				mZStream->next_out = (Bytef*)buf + cachereads;
				
				while (mZStream->avail_out)
				{
					// Pull next chunk of compressed data from the underlying stream
					if (!mZStream->avail_in && !mCompressedStream->eof())
					{
						mZStream->avail_in = mCompressedStream->read(mTmp, OGRE_DEFLATE_TMP_SIZE);
						mZStream->next_in = mTmp;
					}
					
					if (mZStream->avail_in)
					{
						int availpre = mZStream->avail_out;
						int status = inflate(mZStream, Z_SYNC_FLUSH);
						size_t readUncompressed = availpre - mZStream->avail_out;
						newReadUncompressed += readUncompressed;
						if (status != Z_OK)
						{
							// End of data, or error
							if (status != Z_STREAM_END)
							{
								mCompressedStream->seek(restorePoint);
								OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 
											"Error in compressed stream",
											"DeflateStrea::read");
							}
							else 
							{
								// back up the stream so that it can be used from the end onwards													
								long unusedCompressed = mZStream->avail_in;
								mCompressedStream->skip(-unusedCompressed);
							}

							break;
						}
					}
				}
			}
			
			// Cache the last bytes read
			mReadCache.cacheData((char*)buf + cachereads, newReadUncompressed);
			
			mCurrentPos += newReadUncompressed + cachereads;
			
			return newReadUncompressed + cachereads;
		}
	}
    //---------------------------------------------------------------------
	void DeflateStream::init()
	{
		mZStream = OGRE_ALLOC_T(z_stream, 1, MEMCATEGORY_GENERAL);
		mZStream->zalloc = OgreZalloc;
		mZStream->zfree = OgreZfree;
		
		if (getAccessMode() == READ)
		{
			mTmp = (unsigned char*)OGRE_MALLOC(OGRE_DEFLATE_TMP_SIZE, MEMCATEGORY_GENERAL);
			size_t restorePoint = mCompressedStream->tell();
			// read early chunk
			mZStream->next_in = mTmp;
			mZStream->avail_in = mCompressedStream->read(mTmp, OGRE_DEFLATE_TMP_SIZE);
			
			if (inflateInit(mZStream) != Z_OK)
			{
				mIsCompressedValid = false;
			}
			else
				mIsCompressedValid = true;
			
			if (mIsCompressedValid)
			{
				// in fact, inflateInit on some implementations doesn't try to read
				// anything. We need to at least read something to test
				Bytef testOut[4];
				size_t savedIn = mZStream->avail_in;
				mZStream->avail_out = 4;
				mZStream->next_out = testOut;
				if (inflate(mZStream, Z_SYNC_FLUSH) != Z_OK)
					mIsCompressedValid = false;
				// restore for reading
				mZStream->avail_in = savedIn;
				mZStream->next_in = mTmp;

				inflateReset(mZStream);
			}

			if (!mIsCompressedValid)
			{
				// Not compressed data!
				// Fail gracefully, fall back on reading the underlying stream direct
				destroy();
				mCompressedStream->seek(restorePoint);
			}				
		}
		else 
		{
            if(mTempFileName.empty())
            {
                // Write to temp file
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
                char* tmpname = _tempnam(".", "ogre");
                if (!tmpname)
                {
                    // Having no file name here will cause various problems later.
                    OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Temporary file name generation failed.", "DeflateStream::init");
                }
                else
                {
                    mTempFileName = tmpname;
                    free(tmpname);
                }
#else
                char tmpname[L_tmpnam];
                tmpnam(tmpname);
                mTempFileName = tmpname;
#endif
            }

			std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)();
			f->open(mTempFileName.c_str(), std::ios::binary | std::ios::out);
			mTmpWriteStream = DataStreamPtr(OGRE_NEW FileStreamDataStream(f));
			
		}

	}
    RenderTexture *HardwarePixelBuffer::getRenderTarget(size_t)
    {
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
				"Not yet implemented for this rendersystem.",
				"HardwarePixelBuffer::getRenderTarget");
    }
Beispiel #5
0
	//-----------------------------------------------------------------------------
	ManualObject::ManualObjectSection* ManualObject::end(void)
	{
		if (!mCurrentSection)
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
				"You cannot call end() until after you call begin()",
				"ManualObject::end");
		}
		if (mTempVertexPending)
		{
			// bake current vertex
			copyTempVertexToBuffer();
		}

		// pointer that will be returned
		ManualObjectSection* result = NULL;

		RenderOperation* rop = mCurrentSection->getRenderOperation();
		// Check for empty content
		if (rop->vertexData->vertexCount == 0 ||
			(rop->useIndexes && rop->indexData->indexCount == 0))
		{
			// You're wasting my time sonny
			if (mCurrentUpdating)
			{
				// Can't just undo / remove since may be in the middle
				// Just allow counts to be 0, will not be issued to renderer

				// return the finished section (though it has zero vertices)
				result = mCurrentSection;
			}
			else
			{
				// First creation, can really undo
				// Has already been added to section list end, so remove
				mSectionList.pop_back();
				OGRE_DELETE mCurrentSection;

			}
		}
		else // not an empty section
		{

			// Bake the real buffers
			HardwareVertexBufferSharedPtr vbuf;
			// Check buffer sizes
			bool vbufNeedsCreating = true;
			bool ibufNeedsCreating = rop->useIndexes;
            // Work out if we require 16 or 32-bit index buffers
            HardwareIndexBuffer::IndexType indexType = mCurrentSection->get32BitIndices()?  
				HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT;
			if (mCurrentUpdating)
			{
				// May be able to reuse buffers, check sizes
				vbuf = rop->vertexData->vertexBufferBinding->getBuffer(0);
				if (vbuf->getNumVertices() >= rop->vertexData->vertexCount)
					vbufNeedsCreating = false;

				if (rop->useIndexes)
				{
					if ((rop->indexData->indexBuffer->getNumIndexes() >= rop->indexData->indexCount) &&
                        (indexType == rop->indexData->indexBuffer->getType()))
						ibufNeedsCreating = false;
				}

			}
			if (vbufNeedsCreating)
			{
				// Make the vertex buffer larger if estimated vertex count higher
				// to allow for user-configured growth area
				size_t vertexCount = std::max(rop->vertexData->vertexCount, 
					mEstVertexCount);
				vbuf =
					HardwareBufferManager::getSingleton().createVertexBuffer(
						mDeclSize,
						vertexCount,
						mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : 
							HardwareBuffer::HBU_STATIC_WRITE_ONLY);
				rop->vertexData->vertexBufferBinding->setBinding(0, vbuf);
			}
			if (ibufNeedsCreating)
			{
				// Make the index buffer larger if estimated index count higher
				// to allow for user-configured growth area
				size_t indexCount = std::max(rop->indexData->indexCount, 
					mEstIndexCount);
				rop->indexData->indexBuffer =
					HardwareBufferManager::getSingleton().createIndexBuffer(
						indexType,
						indexCount,
						mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : 
							HardwareBuffer::HBU_STATIC_WRITE_ONLY);
			}
			// Write vertex data
			vbuf->writeData(
				0, rop->vertexData->vertexCount * vbuf->getVertexSize(), 
				mTempVertexBuffer, true);
			// Write index data
			if(rop->useIndexes)
			{
                if (HardwareIndexBuffer::IT_32BIT == indexType)
                {
                    // direct copy from the mTempIndexBuffer
				    rop->indexData->indexBuffer->writeData(
					    0, 
					    rop->indexData->indexCount 
						    * rop->indexData->indexBuffer->getIndexSize(),
					    mTempIndexBuffer, true);
                }
                else //(HardwareIndexBuffer::IT_16BIT == indexType)
                {
					uint16* pIdx = static_cast<uint16*>(rop->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
					uint32* pSrc = mTempIndexBuffer;
                    for (size_t i = 0; i < rop->indexData->indexCount; i++)
                    {
                        *pIdx++ = static_cast<uint16>(*pSrc++);
                    }
					rop->indexData->indexBuffer->unlock();

                }
			}

			// return the finished section
			result = mCurrentSection;

		} // empty section check

		mCurrentSection = 0;
		resetTempAreas();

		// Tell parent if present
		if (mParentNode)
		{
			mParentNode->needUpdate();
		}

		// will return the finished section or NULL if
		// the section was empty (i.e. zero vertices/indices)
		return result;
	}
 void RenderTarget::getCustomAttribute(const String& name, void* pData)
 {
     OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Attribute not found.", "RenderTarget::getCustomAttribute");
 }
Beispiel #7
0
    void EGLWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer)
    {
		if ((dst.left < 0) || (dst.right > mWidth) ||
			(dst.top < 0) || (dst.bottom > mHeight) ||
			(dst.front != 0) || (dst.back != 1))
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
				"Invalid box.",
				"Win32Window::copyContentsToMemory" );
		}

		if (buffer == FB_AUTO)
		{
			buffer = mIsFullScreen? FB_FRONT : FB_BACK;
		}

		GLenum format = GLESPixelUtil::getGLOriginFormat(dst.format);
		GLenum type = GLESPixelUtil::getGLOriginDataType(dst.format);

		if ((format == 0) || (type == 0))
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
				"Unsupported format.",
				"GtkEGLWindow::copyContentsToMemory" );
		}


		// Switch context if different from current one
		RenderSystem* rsys = Root::getSingleton().getRenderSystem();
		rsys->_setViewport(this->getViewport(0));

		// Must change the packing to ensure no overruns!
		glPixelStorei(GL_PACK_ALIGNMENT, 1);

		//glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK);
		glReadPixels((GLint)dst.left, (GLint)dst.top,
			(GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(),
			format, type, dst.data);

		// restore default alignment
		glPixelStorei(GL_PACK_ALIGNMENT, 4);

		//vertical flip
		{
			size_t rowSpan = dst.getWidth() * PixelUtil::getNumElemBytes(dst.format);
			size_t height = dst.getHeight();
			uchar *tmpData = new uchar[rowSpan * height];
			uchar *srcRow = (uchar *)dst.data, *tmpRow = tmpData + (height - 1) * rowSpan;

			while (tmpRow >= tmpData)
			{
				memcpy(tmpRow, srcRow, rowSpan);
				srcRow += rowSpan;
				tmpRow -= rowSpan;
			}
			memcpy(dst.data, tmpData, rowSpan * height);

			delete [] tmpData;
		}

    }
Beispiel #8
0
Ogre::DataStreamPtr MTGACodec::code(Ogre::MemoryDataStreamPtr& input, Ogre::Codec::CodecDataPtr& pData) const
{
	OGRE_EXCEPT(Ogre::Exception::ERR_NOT_IMPLEMENTED,
		"MTGA encoding not supported",
		"MTGACodec::code" ) ;
}
Beispiel #9
0
Ogre::Codec::DecodeResult MTGACodec::decode(Ogre::DataStreamPtr& stream) const
{
	// Read 4 character code
	mtga_header_s hdr;
	//uint32 fileType;
	stream->read(&hdr, sizeof(hdr));
	if (LodResource_Bitmap != hdr.magic)
	{
		OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
			"This is not a MTGA file!", "MTGACodec::decode");
	}
	
	mtga_pal_s pal[256];
	assert(stream->size() == sizeof(hdr)+hdr.uncompressedSize + sizeof(pal));

	stream->seek(sizeof(mtga_header_s)+hdr.uncompressedSize);
	stream->read(pal,sizeof(pal));

	bool isTransparent = false;
	mtga_pal_s& clr = pal[0];
	if( (clr.r == 0 && clr.g >250 && clr.b > 250) || (clr.r > 250 && clr.g ==0 && clr.b > 250))
		isTransparent = true;


	Ogre::ImageCodec::ImageData* imgData = OGRE_NEW Ogre::ImageCodec::ImageData();
	imgData->format = PF_BYTE_BGRA;
	imgData->width = hdr.width;
	imgData->height = hdr.height;
	imgData->num_mipmaps = 3;
	imgData->depth = 1;

	imgData->size = Image::calculateSize(imgData->num_mipmaps, 1, 
			imgData->width, imgData->height, imgData->depth, imgData->format);
	
	Ogre::MemoryDataStreamPtr pixelData;
	
	pixelData.bind(OGRE_NEW MemoryDataStream(imgData->size));

	// Now deal with the data
	unsigned char* destPtr = pixelData->getPtr();
	stream->seek(sizeof(mtga_header_s));
	size_t width = hdr.width;
	size_t height = hdr.height;
	for(size_t mip = 0; mip <= imgData->num_mipmaps; ++mip)
	{
			for (size_t y = 0; y < height; y ++)
			{
				for (size_t x = 0; x < width; x ++)
				{
					unsigned char idx;
					stream->read(&idx,1);
					mtga_pal_s& clr = pal[idx];
					assert(destPtr-pixelData->getPtr() < imgData->size);
					
					*destPtr++ = clr.b;
					*destPtr++ = clr.g;
					*destPtr++ = clr.r;
					*destPtr++ = (idx == 0 && isTransparent)?0:255;
				}
			}
			width /=2;
			height /=2;

	}
	


	DecodeResult ret;
	ret.first = pixelData;
	ret.second = CodecDataPtr(imgData);
	return ret;
}
    void* GL3PlusHardwareIndexBuffer::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",
                        "GL3PlusHardwareIndexBuffer::lock");
        }

        void* retPtr = 0;
        GLenum access = 0;
//		GL3PlusHardwareBufferManager* glBufManager = static_cast<GL3PlusHardwareBufferManager*>(HardwareBufferManager::getSingletonPtr());
//
//        // Try to use scratch buffers for smaller buffers
//        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)
//                {
//					// have to read back the data before returning the pointer
//                    readData(offset, length, retPtr);
//                }
//            }
//        }

		if (!retPtr)
		{
            OGRE_CHECK_GL_ERROR(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferId));

			// Use glMapBuffer
			if (mUsage & HBU_WRITE_ONLY)
            {
				access |= GL_MAP_WRITE_BIT;
                access |= GL_MAP_FLUSH_EXPLICIT_BIT;
                if(options == HBL_DISCARD || options == HBL_NO_OVERWRITE)
                {
                    // Discard the buffer
                    access |= GL_MAP_INVALIDATE_RANGE_BIT;
                }
                // We explicitly flush when the buffer is unlocked
                access |= GL_MAP_UNSYNCHRONIZED_BIT;
            }
			else if (options == HBL_READ_ONLY)
				access |= GL_MAP_READ_BIT;
			else
				access |= GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;


            void* pBuffer;
            OGRE_CHECK_GL_ERROR(pBuffer = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length, access));

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

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

			mLockedToScratch = false;
		}
		mIsLocked = true;
        return retPtr;
    }
Beispiel #11
0
//-----------------------------------------------------------------------
void Compositor::createGlobalTextures()
{
    static size_t dummyCounter = 0;
    if (mSupportedTechniques.empty())
        return;

    //To make sure that we are consistent, it is demanded that all composition
    //techniques define the same set of global textures.

    typedef std::set<String> StringSet;
    StringSet globalTextureNames;

    //Initialize global textures from first supported technique
    CompositionTechnique* firstTechnique = mSupportedTechniques[0];

    CompositionTechnique::TextureDefinitionIterator texDefIt =
        firstTechnique->getTextureDefinitionIterator();
    while (texDefIt.hasMoreElements())
    {
        CompositionTechnique::TextureDefinition* def = texDefIt.getNext();
        if (def->scope == CompositionTechnique::TS_GLOBAL)
        {
            //Check that this is a legit global texture
            if (!def->refCompName.empty())
            {
                OGRE_EXCEPT(Exception::ERR_INVALID_STATE,
                            "Global compositor texture definition can not be a reference",
                            "Compositor::createGlobalTextures");
            }
            if (def->width == 0 || def->height == 0)
            {
                OGRE_EXCEPT(Exception::ERR_INVALID_STATE,
                            "Global compositor texture definition must have absolute size",
                            "Compositor::createGlobalTextures");
            }
            if (def->pooled)
            {
                LogManager::getSingleton().logMessage(
                    "Pooling global compositor textures has no effect");
            }
            globalTextureNames.insert(def->name);

            //TODO GSOC : Heavy copy-pasting from CompositorInstance. How to we solve it?

            /// Make the tetxure
            RenderTarget* rendTarget;
            if (def->formatList.size() > 1)
            {
                String MRTbaseName = "c" + StringConverter::toString(dummyCounter++) +
                                     "/" + mName + "/" + def->name;
                MultiRenderTarget* mrt =
                    Root::getSingleton().getRenderSystem()->createMultiRenderTarget(MRTbaseName);
                mGlobalMRTs[def->name] = mrt;

                // create and bind individual surfaces
                size_t atch = 0;
                for (PixelFormatList::iterator p = def->formatList.begin();
                        p != def->formatList.end(); ++p, ++atch)
                {

                    String texname = MRTbaseName + "/" + StringConverter::toString(atch);
                    TexturePtr tex;

                    tex = TextureManager::getSingleton().createManual(
                              texname,
                              ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D,
                              (uint)def->width, (uint)def->height, 0, *p, TU_RENDERTARGET, 0,
                              def->hwGammaWrite && !PixelUtil::isFloatingPoint(*p), def->fsaa);

                    RenderTexture* rt = tex->getBuffer()->getRenderTarget();
                    rt->setAutoUpdated(false);
                    mrt->bindSurface(atch, rt);

                    // Also add to local textures so we can look up
                    String mrtLocalName = getMRTTexLocalName(def->name, atch);
                    mGlobalTextures[mrtLocalName] = tex;

                }

                rendTarget = mrt;
            }
            else
            {
                String texName =  "c" + StringConverter::toString(dummyCounter++) +
                                  "/" + mName + "/" + def->name;

                // space in the name mixup the cegui in the compositor demo
                // this is an auto generated name - so no spaces can't hart us.
                std::replace( texName.begin(), texName.end(), ' ', '_' );

                TexturePtr tex;
                tex = TextureManager::getSingleton().createManual(
                          texName,
                          ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D,
                          (uint)def->width, (uint)def->height, 0, def->formatList[0], TU_RENDERTARGET, 0,
                          def->hwGammaWrite && !PixelUtil::isFloatingPoint(def->formatList[0]), def->fsaa);


                rendTarget = tex->getBuffer()->getRenderTarget();
                mGlobalTextures[def->name] = tex;
            }

            //Set DepthBuffer pool for sharing
            rendTarget->setDepthBufferPool( def->depthBufferId );
        }
    }

    //Validate that all other supported techniques expose the same set of global textures.
    for (size_t i=1; i<mSupportedTechniques.size(); i++)
    {
        CompositionTechnique* technique = mSupportedTechniques[i];
        bool isConsistent = true;
        size_t numGlobals = 0;
        texDefIt = technique->getTextureDefinitionIterator();
        while (texDefIt.hasMoreElements())
        {
            CompositionTechnique::TextureDefinition* texDef = texDefIt.getNext();
            if (texDef->scope == CompositionTechnique::TS_GLOBAL)
            {
                if (globalTextureNames.find(texDef->name) == globalTextureNames.end())
                {
                    isConsistent = false;
                    break;
                }
                numGlobals++;
            }
        }
        if (numGlobals != globalTextureNames.size())
            isConsistent = false;

        if (!isConsistent)
        {
            OGRE_EXCEPT(Exception::ERR_INVALID_STATE,
                        "Different composition techniques define different global textures",
                        "Compositor::createGlobalTextures");
        }

    }

}
	Ogre::RenderToVertexBufferSharedPtr GLES2DefaultHardwareBufferManagerBase::createRenderToVertexBuffer( void )
	{
        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                "Cannot create RenderToVertexBuffer in GLES2DefaultHardwareBufferManagerBase", 
                "GLES2DefaultHardwareBufferManagerBase::createRenderToVertexBuffer");
	}
    //-----------------------------------------------------------------------
    DataStreamPtr FileSystemArchive::open(const String& filename, bool readOnly) const
    {
		String full_path = concatenate_path(mName, filename);

		// Use filesystem to determine size 
		// (quicker than streaming to the end and back)
		struct stat tagStat;
		int ret = stat(full_path.c_str(), &tagStat);
		assert(ret == 0 && "Problem getting file size" );
        (void)ret;  // Silence warning

		// Always open in binary mode
		// Also, always include reading
		std::ios::openmode mode = std::ios::in | std::ios::binary;
		std::istream* baseStream = 0;
		std::ifstream* roStream = 0;
		std::fstream* rwStream = 0;

        if (!readOnly && isReadOnly())
        {
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                        "Cannot open a file in read-write mode in a read-only archive",
                        "FileSystemArchive::open");
        }

		if (!readOnly)
		{
			mode |= std::ios::out;
			rwStream = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)();
			rwStream->open(full_path.c_str(), mode);
			baseStream = rwStream;
		}
		else
		{
			roStream = OGRE_NEW_T(std::ifstream, MEMCATEGORY_GENERAL)();
			roStream->open(full_path.c_str(), mode);
			baseStream = roStream;
		}


		// Should check ensure open succeeded, in case fail for some reason.
		if (baseStream->fail())
		{
			OGRE_DELETE_T(roStream, basic_ifstream, MEMCATEGORY_GENERAL);
			OGRE_DELETE_T(rwStream, basic_fstream, MEMCATEGORY_GENERAL);
			OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND,
				"Cannot open file: " + filename,
				"FileSystemArchive::open");
		}

		/// Construct return stream, tell it to delete on destroy
		FileStreamDataStream* stream = 0;
		if (rwStream)
		{
			// use the writeable stream 
			stream = OGRE_NEW FileStreamDataStream(filename,
				rwStream, (size_t)tagStat.st_size, true);
		}
		else
		{
			// read-only stream
			stream = OGRE_NEW FileStreamDataStream(filename,
				roStream, (size_t)tagStat.st_size, true);
		}
		return DataStreamPtr(stream);
    }
Beispiel #14
0
void TreeLoader2D::addTree(Entity *entity, const Vector3 &position, Degree yaw, Real scale, void* userData)
{
	//First convert the coordinate to PagedGeometry's local system
	#ifdef PAGEDGEOMETRY_ALTERNATE_COORDSYSTEM
	Vector3 pos = geom->_convertToLocal(position);
	#else
	Vector3 pos = position;
	#endif

	//Check that the tree is within bounds (DEBUG)
	#ifdef _DEBUG
	const Real smallVal = 0.01f;
	if (pos.x < actualBounds.left-smallVal || pos.x > actualBounds.right+smallVal || pos.z < actualBounds.top-smallVal || pos.z > actualBounds.bottom+smallVal)
		OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Tree position is out of bounds", "TreeLoader::addTree()");
	if (scale < minimumScale || scale > maximumScale)
		OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Tree scale out of range", "TreeLoader::addTree()");
	#endif

	//If the tree is slightly out of bounds (due to imprecise coordinate conversion), fix it
	if (pos.x < actualBounds.left)
		pos.x = actualBounds.left;
	else if (pos.x > actualBounds.right)
		pos.x = actualBounds.right;

	if (pos.z < actualBounds.top)
		pos.z = actualBounds.top;
	else if (pos.z > actualBounds.bottom)
		pos.z = actualBounds.bottom;

	//Real x = pos.x;
	//Real z = pos.z;

   std::vector<TreeDef> *pageGrid = 0;
	//Find the appropriate page grid for the entity
	PageGridListIterator i = pageGridList.find(entity);
	if (i != pageGridList.end())
		pageGrid = i->second;   // If it exists, get the page grid
   else
   {
		// If it does not exist, create a new page grid
		pageGrid = new std::vector<TreeDef>[pageGridX * pageGridZ];
		// Register the new page grid in the pageGridList for later retrieval
		pageGridList.insert(PageGridListValue(entity, pageGrid));
	}

	//Calculate the gridbounds-relative position of the tree
	Real xrel = pos.x - gridBounds.left;
	Real zrel = pos.z - gridBounds.top;

	//Get the appropriate grid element based on the new tree's position
	int pageX = (int)Math::Floor(xrel / pageSize); // bad perfomance float --> int
	int pageZ = (int)Math::Floor(zrel / pageSize); // bad perfomance float --> int
	std::vector<TreeDef> &treeList = _getGridPage(pageGrid, pageX, pageZ);

	//Create the new tree
	TreeDef tree;
	tree.xPos      = static_cast<uint16>(0xFFFF * (xrel - (pageX * pageSize)) / pageSize);
	tree.zPos      = static_cast<uint16>(0xFFFF * (zrel - (pageZ * pageSize)) / pageSize);
   tree.rotation  = static_cast<uint8>(Ogre::Real(0.708) * yaw.valueDegrees());                       // 0.708 ~= 255 / 360
   tree.scale     = static_cast<uint8>(Ogre::Real(255.) * ((scale - minimumScale) / maximumScale));

#ifdef PAGEDGEOMETRY_USER_DATA
	tree.userData = userData;
#endif

	//Add it to the tree list
	treeList.push_back(tree);

	//Rebuild geometry if necessary
	geom->reloadGeometryPage(Vector3(pos.x, 0, pos.z));
}
Beispiel #15
0
	//Changed the constructor to a member function so that the
	//native constructor would be called first. This member
	//function is then called from the native constructor.
    void EGLPBuffer::initEGLPBuffer()
    {

//	These are now initialized in the native constructors.
//	mGLSupport = glsupport;
//        mGlDisplay = mGLSupport->getGLDisplay();
        mEglDrawable = 0;
        ::EGLConfig glConfig = 0;

        bool isFloat = false;
        int bits = 0;

        switch (mFormat)
        {
            case PCT_BYTE:
                bits = 8;
                break;

            case PCT_SHORT:
            case PCT_FLOAT16:
                bits = 16;
                break;

            case PCT_FLOAT32:
                bits = 32;
                break;

            default:
                break;
        }

        if (mFormat == PCT_FLOAT16 || mFormat == PCT_FLOAT32)
        {
            OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                        "No support for Floating point PBuffers",
                        "EGLRenderTexture::initEGLPBuffer");
        }

        EGLint minAttribs[] = {
            EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
            EGL_DEPTH_SIZE, 16,
            EGL_NONE
        };

        EGLint maxAttribs[] = {
            EGL_RED_SIZE, bits,
            EGL_GREEN_SIZE, bits,
            EGL_BLUE_SIZE, bits,
            EGL_ALPHA_SIZE, bits,
            EGL_STENCIL_SIZE, INT_MAX,
            EGL_NONE
        };

        EGLint pBufferAttribs[] = {
			// First we specify the width of the surface...
            EGL_WIDTH, mWidth,
			// ...then the height of the surface...
            EGL_HEIGHT, mHeight,
			/* ... then we specify the target for the texture
			that will be created when the pbuffer is created...*/
			EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
			/*..then the format of the texture that will be created
			when the pBuffer is bound to a texture...*/
            EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
			// The final thing is EGL_NONE which signifies the end.
            EGL_NONE
        };


        glConfig = mGLSupport->selectGLConfig(minAttribs, maxAttribs);

        EGL_CHECK_ERROR;
        mEglDrawable = eglCreatePbufferSurface(mGlDisplay, glConfig, pBufferAttribs);
        EGL_CHECK_ERROR;

        if (!glConfig || !mEglDrawable)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                        "Unable to create Pbuffer",
                        "EGLPBuffer::EGLPBuffer");
        }
        EGLint glConfigID;
        EGLint iWidth, iHeight;

        eglGetConfigAttrib(mGlDisplay, glConfig, EGL_CONFIG_ID, &glConfigID);
        EGL_CHECK_ERROR;
        eglQuerySurface(mGlDisplay, mEglDrawable, EGL_WIDTH, &iWidth);
        EGL_CHECK_ERROR;
        eglQuerySurface(mGlDisplay, mEglDrawable, EGL_HEIGHT, &iHeight);
        EGL_CHECK_ERROR;

        mWidth = iWidth;
        mHeight = iHeight;
        LogManager::getSingleton().logMessage(LML_NORMAL, "EGLPBuffer::create used final dimensions " + StringConverter::toString(mWidth) + " x " + StringConverter::toString(mHeight));
        LogManager::getSingleton().logMessage("EGLPBuffer::create used FBConfigID " + StringConverter::toString(glConfigID));

    }
//-----------------------------------------------------------------------------
void D3D9HardwarePixelBuffer::bind(IDirect3DDevice9 *dev, IDirect3DSurface9 *surface,
                                   IDirect3DSurface9* fsaaSurface,
                                   bool writeGamma, uint fsaa, const String& srcName,
                                   IDirect3DBaseTexture9 *mipTex)
{
    D3D9_DEVICE_ACCESS_CRITICAL_SECTION

    BufferResources* bufferResources = getBufferResources(dev);
    bool isNewBuffer = false;

    if (bufferResources == NULL)
    {
        bufferResources = createBufferResources();
        mMapDeviceToBufferResources[dev] = bufferResources;
        isNewBuffer = true;
    }

    bufferResources->mipTex = mipTex;
    bufferResources->surface = surface;
    bufferResources->surface->AddRef();
    bufferResources->fSAASurface = fsaaSurface;

    D3DSURFACE_DESC desc;
    if(surface->GetDesc(&desc) != D3D_OK)
        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get surface information",
                    "D3D9HardwarePixelBuffer::D3D9HardwarePixelBuffer");

    mWidth = desc.Width;
    mHeight = desc.Height;
    mDepth = 1;
    mFormat = D3D9Mappings::_getPF(desc.Format);
    // Default
    mRowPitch = mWidth;
    mSlicePitch = mHeight*mWidth;
    mSizeInBytes = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);

    if(mUsage & TU_RENDERTARGET)
        updateRenderTexture(writeGamma, fsaa, srcName);

    if (isNewBuffer && mOwnerTexture->isManuallyLoaded())
    {
        DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin();

        while (it != mMapDeviceToBufferResources.end())
        {
            if (it->second != bufferResources &&
                    it->second->surface != NULL &&
                    it->first->TestCooperativeLevel() == D3D_OK &&
                    dev->TestCooperativeLevel() == D3D_OK)
            {
                Box fullBufferBox(0,0,0,mWidth,mHeight,mDepth);
                PixelBox dstBox(fullBufferBox, mFormat);

                dstBox.data = OGRE_MALLOC (getSizeInBytes(), MEMCATEGORY_RESOURCE);
                blitToMemory(fullBufferBox, dstBox, it->second, it->first);
                blitFromMemory(dstBox, fullBufferBox, bufferResources);
                OGRE_FREE(dstBox.data, MEMCATEGORY_RESOURCE);
                break;
            }
            ++it;
        }
    }
}
    //---------------------------------------------------------------------
    DataStreamPtr PVRTCCodec::encode(MemoryDataStreamPtr& input, Codec::CodecDataPtr& pData) const
    {        
		OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "PVRTC encoding not supported",
                    "PVRTCCodec::encode" ) ;
    }
Beispiel #18
0
 //---------------------------------------------------------------------
 void ZipArchive::remove(const String& filename)
 {
     OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 
         "Modification of zipped archives is not supported", 
         "ZipArchive::remove");
 }
    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;

        if (length < OGRE_GL_MAP_BUFFER_THRESHOLD)
        {
            retPtr = static_cast<GLESHardwareBufferManager*>(
                HardwareBufferManager::getSingletonPtr())->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",
                        "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;
    }
	void Win32PBuffer::createPBuffer() 
	{

        // Process format
        int bits=0;
        bool isFloat=false;
#if 0
		bool hasAlpha=true;
#endif
        switch(mFormat)
        {
            case PCT_BYTE:
                bits=8; isFloat=false;
                break;
            case PCT_SHORT:
                bits=16; isFloat=false;
                break;
            case PCT_FLOAT16:
                bits=16; isFloat=true;
                break;
            case PCT_FLOAT32:
                bits=32; isFloat=true;
                break;
            default: break;
        };
		LogManager::getSingleton().logMessage(
			" Win32PBuffer::Creating PBuffer of format bits="+
			StringConverter::toString(bits)+
			" float="+StringConverter::toString(isFloat)
	    );


		HDC old_hdc = wglGetCurrentDC();
		HGLRC old_context = wglGetCurrentContext();

		// Bind to RGB or RGBA texture
		int bttype = 0;
#if 0
		if(mUseBind)
		{
			// Only provide bind type when actually binding
			bttype = PixelUtil::hasAlpha(mInternalFormat)?
				WGL_BIND_TO_TEXTURE_RGBA_ARB : WGL_BIND_TO_TEXTURE_RGB_ARB;
		}
		int texformat = hasAlpha?
			WGL_TEXTURE_RGBA_ARB : WGL_TEXTURE_RGB_ARB;
#endif
		// Make a float buffer?
        int pixeltype = isFloat?
			WGL_TYPE_RGBA_FLOAT_ARB: WGL_TYPE_RGBA_ARB;
		
		int attrib[] = {
			WGL_RED_BITS_ARB,bits,
			WGL_GREEN_BITS_ARB,bits,
			WGL_BLUE_BITS_ARB,bits,
			WGL_ALPHA_BITS_ARB,bits,
			WGL_STENCIL_BITS_ARB,1,
			WGL_DEPTH_BITS_ARB,15,
			WGL_DRAW_TO_PBUFFER_ARB,true,
			WGL_SUPPORT_OPENGL_ARB,true,
			WGL_PIXEL_TYPE_ARB,pixeltype,
			//WGL_DOUBLE_BUFFER_ARB,true,
			//WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB, // Make sure it is accelerated
			bttype,true, // must be last, as bttype can be zero
			0
		};
		int pattrib_default[] = { 
			0
		};
#if 0
		int pattrib_bind[] = { 
			WGL_TEXTURE_FORMAT_ARB, texformat, 
			WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB,
			WGL_PBUFFER_LARGEST_ARB, true,
			0 
		};
#endif
		int format;
		unsigned int count;

		// Choose suitable pixel format
		wglChoosePixelFormatARB(old_hdc,attrib,NULL,1,&format,&count);
		if(count == 0)
			OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglChoosePixelFormatARB() failed", " Win32PBuffer::createPBuffer");

		// Analyse pixel format
		const int piAttributes[]={
				WGL_RED_BITS_ARB,WGL_GREEN_BITS_ARB,WGL_BLUE_BITS_ARB,WGL_ALPHA_BITS_ARB,
				WGL_DEPTH_BITS_ARB,WGL_STENCIL_BITS_ARB
		};
		int piValues[sizeof(piAttributes)/sizeof(const int)];
		wglGetPixelFormatAttribivARB(old_hdc,format,0,sizeof(piAttributes)/sizeof(const int),piAttributes,piValues);

        LogManager::getSingleton().stream()
			<< " Win32PBuffer::PBuffer -- Chosen pixel format rgba="
            << piValues[0] << ","  
            << piValues[1] << ","  
            << piValues[2] << ","  
            << piValues[3] 
            << " depth=" << piValues[4]
            << " stencil=" << piValues[5];

		mPBuffer = wglCreatePbufferARB(old_hdc,format,mWidth,mHeight,pattrib_default);
		if(!mPBuffer)
			OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglCreatePbufferARB() failed", " Win32PBuffer::createPBuffer");

		mHDC = wglGetPbufferDCARB(mPBuffer);
		if(!mHDC) {
			wglDestroyPbufferARB(mPBuffer);
			OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglGetPbufferDCARB() failed", " Win32PBuffer::createPBuffer");
		}
			
		mGlrc = wglCreateContext(mHDC);
		if(!mGlrc) {
			wglReleasePbufferDCARB(mPBuffer,mHDC);
			wglDestroyPbufferARB(mPBuffer);
			OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglCreateContext() failed", " Win32PBuffer::createPBuffer");
		}

		if(!wglShareLists(old_context,mGlrc)) {
			wglDeleteContext(mGlrc);
			wglReleasePbufferDCARB(mPBuffer,mHDC);
			wglDestroyPbufferARB(mPBuffer);
			OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglShareLists() failed", " Win32PBuffer::createPBuffer");
		}
				
		// Query real width and height
		int iWidth, iHeight;
		wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_WIDTH_ARB, &iWidth);
		wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_HEIGHT_ARB, &iHeight);
		mWidth = iWidth;  
		mHeight = iHeight;
		LogManager::getSingleton().stream()
			<< "Win32RenderTexture::PBuffer created -- Real dimensions "
            << mWidth << "x" << mHeight;
	}
    void Win32EGLWindow::create(const String& name, uint width, uint height,
                                bool fullScreen, const NameValuePairList *miscParams)
    {
        String title = name;
        uint samples = 0;
        int gamma;
        short frequency = 0;
        bool vsync = false;
        ::EGLContext eglContext = 0;
		int left = 0;
		int top  = 0;

		getLeftAndTopFromNativeWindow(left, top, width, height);

        mIsFullScreen = fullScreen;

        if (miscParams)
        {
            NameValuePairList::const_iterator opt;
            NameValuePairList::const_iterator end = miscParams->end();

            if ((opt = miscParams->find("currentGLContext")) != end &&
                StringConverter::parseBool(opt->second))
            {
                eglContext = eglGetCurrentContext();
                if (eglContext)
                {
                    OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                                "currentGLContext was specified with no current GL context",
                                "EGLWindow::create");
                }

                eglContext = eglGetCurrentContext();
                mEglSurface = eglGetCurrentSurface(EGL_DRAW);
            }

            // Note: Some platforms support AA inside ordinary windows
            if ((opt = miscParams->find("FSAA")) != end)
            {
                samples = StringConverter::parseUnsignedInt(opt->second);
            }

            if ((opt = miscParams->find("displayFrequency")) != end)
            {
                frequency = (short)StringConverter::parseInt(opt->second);
            }

            if ((opt = miscParams->find("vsync")) != end)
            {
                vsync = StringConverter::parseBool(opt->second);
            }

            if ((opt = miscParams->find("gamma")) != end)
            {
                gamma = StringConverter::parseBool(opt->second);
            }

            if ((opt = miscParams->find("left")) != end)
            {
                left = StringConverter::parseInt(opt->second);
            }

            if ((opt = miscParams->find("top")) != end)
            {
                top = StringConverter::parseInt(opt->second);
            }

            if ((opt = miscParams->find("title")) != end)
            {
                title = opt->second;
            }

            if ((opt = miscParams->find("externalGLControl")) != end)
            {
                mIsExternalGLControl = StringConverter::parseBool(opt->second);
            }
		}

		initNativeCreatedWindow(miscParams);

        if (mEglSurface)
        {
            mEglConfig = mGLSupport->getGLConfigFromDrawable (mEglSurface, &width, &height);
        }

        if (!mEglConfig && eglContext)
        {
            mEglConfig = mGLSupport->getGLConfigFromContext(eglContext);

            if (!mEglConfig)
            {
                // This should never happen.
                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                            "Unexpected failure to determine a EGLFBConfig",
                            "EGLWindow::create");
            }
        }

        mIsExternal = (mEglSurface != 0);



        if (!mEglConfig)
        {
            int minAttribs[] = {
                EGL_LEVEL, 0,
                EGL_DEPTH_SIZE, 16,
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_NONE
            };

            int maxAttribs[] = {
                EGL_SAMPLES, samples,
                EGL_STENCIL_SIZE, INT_MAX,
                EGL_NONE
            };

            mEglConfig = mGLSupport->selectGLConfig(minAttribs, maxAttribs);
            mHwGamma = false;
        }

        if (!mIsTopLevel)
        {
            mIsFullScreen = false;
            left = top = 0;
        }

        if (mIsFullScreen)
        {
            mGLSupport->switchMode (width, height, frequency);
        }

		if (!mIsExternal)
        {
			createNativeWindow(left, top, width, height, title);
		}

		mContext = createEGLContext();

        ::EGLSurface oldDrawableDraw = eglGetCurrentSurface(EGL_DRAW);
        ::EGLSurface oldDrawableRead = eglGetCurrentSurface(EGL_READ);
        ::EGLContext oldContext  = eglGetCurrentContext();

        int glConfigID;

        mGLSupport->getGLConfigAttrib(mEglConfig, EGL_CONFIG_ID, &glConfigID);
        LogManager::getSingleton().logMessage("EGLWindow::create used FBConfigID = " + StringConverter::toString(glConfigID));

        mName = name;
        mWidth = width;
        mHeight = height;
        mLeft = left;
        mTop = top;
        mActive = true;
		mVisible = true;

        mClosed = false;
	}
    void GLFrameBufferObject::initialise()
    {
		// Release depth and stencil, if they were bound
        mManager->releaseRenderBuffer(mDepth);
        mManager->releaseRenderBuffer(mStencil);
		mManager->releaseRenderBuffer(mMultisampleColourBuffer);
        // First buffer must be bound
        if(!mColour[0].buffer)
        {
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
            "Attachment 0 must have surface attached",
		 	"GLFrameBufferObject::initialise");
        }

		// If we're doing multisampling, then we need another FBO which contains a
		// renderbuffer which is set up to multisample, and we'll blit it to the final 
		// FBO afterwards to perform the multisample resolve. In that case, the 
		// mMultisampleFB is bound during rendering and is the one with a depth/stencil

        // Store basic stats
        size_t width = mColour[0].buffer->getWidth();
        size_t height = mColour[0].buffer->getHeight();
        GLuint format = mColour[0].buffer->getGLFormat();
        ushort maxSupportedMRTs = Root::getSingleton().getRenderSystem()->getCapabilities()->getNumMultiRenderTargets();

		// Bind simple buffer to add colour attachments
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFB);

        // Bind all attachment points to frame buffer
        for(size_t x=0; x<maxSupportedMRTs; ++x)
        {
            if(mColour[x].buffer)
            {
                if(mColour[x].buffer->getWidth() != width || mColour[x].buffer->getHeight() != height)
                {
                    StringStream ss;
                    ss << "Attachment " << x << " has incompatible size ";
                    ss << mColour[x].buffer->getWidth() << "x" << mColour[x].buffer->getHeight();
                    ss << ". It must be of the same as the size of surface 0, ";
                    ss << width << "x" << height;
                    ss << ".";
                    OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GLFrameBufferObject::initialise");
                }
                if(mColour[x].buffer->getGLFormat() != format)
                {
                    StringStream ss;
                    ss << "Attachment " << x << " has incompatible format.";
                    OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GLFrameBufferObject::initialise");
                }
	            mColour[x].buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_EXT+x, mColour[x].zoffset);
            }
            else
            {
                // Detach
                glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+x,
                    GL_RENDERBUFFER_EXT, 0);
            }
        }

		// Now deal with depth / stencil
		if (mMultisampleFB)
		{
			// Bind multisample buffer
			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mMultisampleFB);

			// Create AA render buffer (colour)
			// note, this can be shared too because we blit it to the final FBO
			// right after the render is finished
			mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples);

			// Attach it, because we won't be attaching below and non-multisample has
			// actually been attached to other FBO
			mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_EXT, 
				mMultisampleColourBuffer.zoffset);

			// depth & stencil will be dealt with below

		}

        // Depth buffer is not handled here anymore.
		// See GLFrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor()

		// Do glDrawBuffer calls
		GLenum bufs[OGRE_MAX_MULTIPLE_RENDER_TARGETS];
		GLsizei n=0;
		for(size_t x=0; x<OGRE_MAX_MULTIPLE_RENDER_TARGETS; ++x)
		{
			// Fill attached colour buffers
			if(mColour[x].buffer)
			{
				bufs[x] = GL_COLOR_ATTACHMENT0_EXT + x;
				// Keep highest used buffer + 1
				n = x+1;
			}
			else
			{
				bufs[x] = GL_NONE;
			}
		}
		if(glDrawBuffers)
		{
			// Drawbuffer extension supported, use it
			glDrawBuffers(n, bufs);
		}
		else
		{
			// In this case, the capabilities will not show more than 1 simultaneaous render target.
			glDrawBuffer(bufs[0]);
		}
		if (mMultisampleFB)
		{
			// we need a read buffer because we'll be blitting to mFB
			glReadBuffer(bufs[0]);
		}
		else
		{
			// No read buffer, by default, if we want to read anyway we must not forget to set this.
			glReadBuffer(GL_NONE);
		}
        
        // Check status
        GLuint status;
        status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
        
        // Bind main buffer
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
        
        switch(status)
        {
        case GL_FRAMEBUFFER_COMPLETE_EXT:
            // All is good
            break;
        case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
            "All framebuffer formats with this texture internal format unsupported",
		 	"GLFrameBufferObject::initialise");
        default:
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
            "Framebuffer incomplete or other FBO status error",
		 	"GLFrameBufferObject::initialise");
        }
        
    }
 //-----------------------------------------------------------------------------    
 /// Internal implementation of lock()
 void* HardwarePixelBuffer::lockImpl(size_t offset, size_t length, LockOptions options)
 {
     OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "lockImpl(offset,length) is not valid for PixelBuffers and should never be called",
         "HardwarePixelBuffer::lockImpl");
 }
Beispiel #24
0
int _tmain(int argc, _TCHAR* argv[])
{
	// ------------------------- Check for command line argument -------------------------------------------

	if (! argv[1])
	{
		printf("\n");
		printf("Missing argument.\nExample: \"Converter.exe job1.cfg\"");		
		return 0;	
	}

	// ------------------------- Basic Ogre Engine initialization -------------------------------------------

	Ogre::Root* root = new Ogre::Root;	
	Ogre::RenderSystem* rendersys = root->getRenderSystemByName("Direct3D9 Rendering Subsystem");
	
	rendersys->setConfigOption("Full Screen", "No");
	rendersys->setConfigOption("Video Mode", "800 x 600 @ 32-bit colour");
	
	root->setRenderSystem(rendersys);		
	
	Ogre::ResourceGroupManager::getSingleton().addResourceLocation("resource", "FileSystem", "General");
	Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

	root->initialise(false);

	Ogre::RenderWindow* window = root->createRenderWindow("RAW2OGT", 800, 600, false);		
	Ogre::SceneManager* scenemgr = root->createSceneManager(Ogre::SceneType::ST_GENERIC);
	Ogre::Camera* camera = scenemgr->createCamera("camera");
	Ogre::Viewport* viewport = window->addViewport(camera);
	/*Ogre::Vector3 lightdir(0, -0.3, 0.75);
	lightdir.normalise();

	Ogre::Light* l = scenemgr->createLight("tstLight");
	l->setType(Ogre::Light::LT_DIRECTIONAL);
	l->setDirection(lightdir);
	l->setDiffuseColour(Ogre::ColourValue(1.0, 1.0, 1.0));
	l->setSpecularColour(Ogre::ColourValue(0.4, 0.4, 0.4));*/

	scenemgr->setAmbientLight(Ogre::ColourValue(0.7, 0.7, 0.7));
	
	// --------------------------------- Start convert ----------------------------------------------------

	// Load job config
	Ogre::ConfigFile* terrainconfig = OGRE_NEW Ogre::ConfigFile();
	terrainconfig->loadDirect(argv[1]);
		
	// Load info from [general] block
	Ogre::String heightmapfile = terrainconfig->getSetting("heightmap", "general");
	Ogre::Real heightmapscale = Ogre::StringConverter::parseReal(terrainconfig->getSetting("heightmapscale", "general"));
	Ogre::Real heightmapoffset = Ogre::StringConverter::parseReal(terrainconfig->getSetting("heightmapoffset", "general"));
	Ogre::uint16 terrainsize = Ogre::StringConverter::parseUnsignedInt(terrainconfig->getSetting("terrainsize", "general"));
	Ogre::Real worldsize = Ogre::StringConverter::parseReal(terrainconfig->getSetting("worldsize", "general"));
	Ogre::uint16 layercount = Ogre::StringConverter::parseUnsignedInt(terrainconfig->getSetting("layercount", "general"));

	// initialise stream to heightmapfile
	Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(heightmapfile, "General");
	size_t size = stream.get()->size();
		
	// verify size
	if(size != terrainsize * terrainsize * 4)
		OGRE_EXCEPT( Ogre::Exception::ERR_INTERNAL_ERROR, "Size of stream does not match terrainsize!", "TerrainPage" );
					
	// load to buffer
	float* buffer = OGRE_ALLOC_T(float, size, Ogre::MEMCATEGORY_GENERAL);
	stream->read(buffer, size);

	// apply scale and offset 
	for(int i=0;i<terrainsize*terrainsize;i++)
	{
		buffer[i]  = (buffer[i] + heightmapoffset) * heightmapscale;
	}

	// Terrain initialization
	Ogre::TerrainGlobalOptions* terrainglobals = OGRE_NEW Ogre::TerrainGlobalOptions();
	terrainglobals->setMaxPixelError(1);
	//terrainglobals->setCompositeMapDistance(30000);
	//terrainglobals->setLightMapDirection(lightdir);
    //terrainglobals->setCompositeMapAmbient(scenemgr->getAmbientLight());
    //terrainglobals->setCompositeMapDiffuse(l->getDiffuseColour());
	
	Ogre::TerrainMaterialGeneratorA::SM2Profile* pMatProfile = 
      static_cast<Ogre::TerrainMaterialGeneratorA::SM2Profile*>(terrainglobals->getDefaultMaterialGenerator()->getActiveProfile());
	
	pMatProfile->setLightmapEnabled(false);
	pMatProfile->setCompositeMapEnabled(false);
	
	Ogre::TerrainGroup* terraingroup = OGRE_NEW Ogre::TerrainGroup(scenemgr, Ogre::Terrain::ALIGN_X_Z, terrainsize, worldsize);
    terraingroup->setFilenameConvention(Ogre::String("terrain"), Ogre::String("ogt"));
    terraingroup->setOrigin(Ogre::Vector3::ZERO);
		
	Ogre::Terrain* terrain = OGRE_NEW Ogre::Terrain(scenemgr);

	// terrainsettings							
	Ogre::Terrain::ImportData& imp = terraingroup->getDefaultImportSettings();	
	imp.terrainSize = terrainsize;
	imp.worldSize = worldsize;
	imp.minBatchSize = 33;
	imp.maxBatchSize = 65;

	// use float RAW heightmap as input
	imp.inputFloat = buffer;
	
	// process texture layers
	imp.layerList.resize(layercount);
	Ogre::StringVector blendmaps(layercount);
	for(int i=0;i<layercount;i++)
	{
		// load layer info
		Ogre::String sectionStr = Ogre::StringConverter::toString(i);
		Ogre::Real layerworldsize = Ogre::StringConverter::parseReal(terrainconfig->getSetting("worldsize", sectionStr));
		
		if (i==0)
		{			
			// no blendmap at layer 0 (baselayer)
			Ogre::String specular = terrainconfig->getSetting("specular", sectionStr);
			Ogre::String normal = terrainconfig->getSetting("normal", sectionStr);

			// add layer		
			imp.layerList[i].textureNames.push_back(specular);
			imp.layerList[i].textureNames.push_back(normal);
			imp.layerList[i].worldSize = layerworldsize;			
		}
		else
		{
			Ogre::String specular = terrainconfig->getSetting("specular", sectionStr);
			Ogre::String normal = terrainconfig->getSetting("normal", sectionStr);
			Ogre::String blend = terrainconfig->getSetting("blend", sectionStr);
		
			// add layer		
			imp.layerList[i].textureNames.push_back(specular);
			imp.layerList[i].textureNames.push_back(normal);	
			imp.layerList[i].worldSize = layerworldsize;

			blendmaps[i] = blend; 
		}
	}

	// load the terrain
	terrain->prepare(imp);
	terrain->load();	
	
	// load those blendmaps into the layers
	for(int j = 1;j < terrain->getLayerCount();j++)
	{
		Ogre::TerrainLayerBlendMap *blendmap = terrain->getLayerBlendMap(j);
		Ogre::Image img;
		img.load(blendmaps[j],"General");
		int blendmapsize = terrain->getLayerBlendMapSize();
		if(img.getWidth() != blendmapsize)
			img.resize(blendmapsize, blendmapsize);

		float *ptr = blendmap->getBlendPointer();
		Ogre::uint8 *data = static_cast<Ogre::uint8*>(img.getPixelBox().data);

		for(int bp = 0;bp < blendmapsize * blendmapsize;bp++)
			ptr[bp] = static_cast<float>(data[bp]) / 255.0f;

		blendmap->dirty();
		blendmap->update();
	}

	// create filename for writing
	int pos = heightmapfile.find_last_of('.');
	if (pos < 0)	
		heightmapfile = heightmapfile + ".ogt";
	else	
		heightmapfile = heightmapfile.substr(0, pos) + ".ogt";
			
	// save as Ogre .OGT
	terrain->save(heightmapfile);	
	Ogre::LogManager::getSingletonPtr()->logMessage(Ogre::LogMessageLevel::LML_NORMAL, heightmapfile + " successfully written.");
	
	// debug viewing (exit with CTRL+C)
	camera->setPosition(-terrainsize, 7000, -terrainsize);
	camera->lookAt(terrainsize/2,0,terrainsize/2);	
	root->startRendering();

	return 0;
}
 MultiRenderTarget* GLRTTManager::createMultiRenderTarget(const String & name)
 {
 	OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "MultiRenderTarget can only be used with GL_EXT_framebuffer_object extension", "GLRTTManager::createMultiRenderTarget");
 }
	//-----------------------------------------------------------------------
	D3D11_INPUT_ELEMENT_DESC * D3D11VertexDeclaration::getD3DVertexDeclaration(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding)
	{
		// Create D3D elements
		size_t iNumElements = boundVertexProgram->getNumInputs();

		if (mD3delems.find(boundVertexProgram) == mD3delems.end())
		{
			D3D11_INPUT_ELEMENT_DESC*  D3delems = new D3D11_INPUT_ELEMENT_DESC[iNumElements];
            ZeroMemory(D3delems, sizeof(D3D11_INPUT_ELEMENT_DESC) * iNumElements);

			unsigned int idx;
       		for (idx = 0; idx < iNumElements; ++idx)
			{
                D3D11_SIGNATURE_PARAMETER_DESC inputDesc = boundVertexProgram->getInputParamDesc(idx);
       			VertexElementList::const_iterator i, iend;
			    iend = mElementList.end();
                bool found = false;
		        for (i = mElementList.begin(); i != iend; ++i)
                {
                    LPCSTR semanticName			= D3D11Mappings::get(i->getSemantic());
                    UINT semanticIndex			= i->getIndex();
                    if(
                        strcmp(semanticName, inputDesc.SemanticName) == 0
                        && semanticIndex == inputDesc.SemanticIndex
                      )
                    {
                        found = true;
                        break;
                    }
                }

                if(!found)
                {
                    // find by pos
                    i = mElementList.begin();
                    for (unsigned int count = 0; count < idx && i != iend; count++, ++i)
                    {
                    }
                    if (i != iend)
                    {
                        found = true;
                    }
                }

                if(!found)
                {
                    OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D11 vertex declaration" , 
                        						"D3D11VertexDeclaration::getILayoutByShader");
                }

				D3delems[idx].SemanticName			= inputDesc.SemanticName;
				D3delems[idx].SemanticIndex			= inputDesc.SemanticIndex;
				D3delems[idx].Format				= D3D11Mappings::get(i->getType());
				D3delems[idx].InputSlot				= i->getSource();
				D3delems[idx].AlignedByteOffset		= static_cast<WORD>(i->getOffset());
				D3delems[idx].InputSlotClass		= D3D11_INPUT_PER_VERTEX_DATA;
				D3delems[idx].InstanceDataStepRate	= 0;

				VertexBufferBinding::VertexBufferBindingMap::const_iterator foundIter;
				foundIter = binding->getBindings().find(i->getSource());
				if ( foundIter != binding->getBindings().end() )
				{
					HardwareVertexBufferSharedPtr bufAtSlot = foundIter->second;
					if ( bufAtSlot->isInstanceData() )
					{
						D3delems[idx].InputSlotClass		= D3D11_INPUT_PER_INSTANCE_DATA;
						D3delems[idx].InstanceDataStepRate	= bufAtSlot->getInstanceDataStepRate();
					}
				}
				else
				{
					OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, 
						"Unable to found a bound vertex for a slot that is used in the vertex declaration." , 
						"D3D11VertexDeclaration::getD3DVertexDeclaration");

				}				
			}

			mD3delems[boundVertexProgram] = D3delems;

		}

		return mD3delems[boundVertexProgram];
	}
    //---------------------------------------------------------------------
	void DeflateStream::compressFinal()
	{
		// Close temp stream
		mTmpWriteStream->close();
		
		// Copy & compress
		// We do this rather than compress directly because some code seeks
		// around while writing (e.g. to update size blocks) which is not
		// possible when compressing on the fly
		
		int ret, flush;
		char in[OGRE_DEFLATE_TMP_SIZE];
		char out[OGRE_DEFLATE_TMP_SIZE];
		
		if (deflateInit(mZStream, Z_DEFAULT_COMPRESSION) != Z_OK)
		{
			destroy();
			OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 
						"Error initialising deflate compressed stream!",
						"DeflateStream::init");
		}
		
		std::ifstream inFile;
		inFile.open(mTempFileName.c_str(), std::ios::in | std::ios::binary);
		
		do 
		{
			inFile.read(in, OGRE_DEFLATE_TMP_SIZE);
			mZStream->avail_in = (uInt)inFile.gcount();
			if (inFile.bad()) 
			{
				deflateEnd(mZStream);
				OGRE_EXCEPT(Exception::ERR_INVALID_STATE, 
							"Error reading temp uncompressed stream!",
							"DeflateStream::init");
			}
			flush = inFile.eof() ? Z_FINISH : Z_NO_FLUSH;
			mZStream->next_in = (Bytef*)in;
			
			/* run deflate() on input until output buffer not full, finish
			 compression if all of source has been read in */
			do 
			{
				mZStream->avail_out = OGRE_DEFLATE_TMP_SIZE;
				mZStream->next_out = (Bytef*)out;
				ret = deflate(mZStream, flush);    /* no bad return value */
				assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
				size_t compressed = OGRE_DEFLATE_TMP_SIZE - mZStream->avail_out;
				mCompressedStream->write(out, compressed);
			} while (mZStream->avail_out == 0);
			assert(mZStream->avail_in == 0);     /* all input will be used */
			
			/* done when last data in file processed */
		} while (flush != Z_FINISH);
		assert(ret == Z_STREAM_END);        /* stream will be complete */
		
		deflateEnd(mZStream);

        inFile.close();
		remove(mTempFileName.c_str());
						
	}
Beispiel #28
0
	//-------------------------------------------------------------------------------------------------//
	void GLXWindow::create(const String& name, uint width, uint height,
			   bool fullScreen, const NameValuePairList *miscParams)
	{
		Display *xDisplay = mGLSupport->getXDisplay();
		String title = name;
		uint samples = 0;
		short frequency = 0;
		bool vsync = false;
		unsigned int vsyncInterval = 1;
		int gamma = 0;
		::GLXContext glxContext = 0;
		::GLXDrawable glxDrawable = 0;
		Window externalWindow = 0;
		Window parentWindow = DefaultRootWindow(xDisplay);
		int left = DisplayWidth(xDisplay, DefaultScreen(xDisplay))/2 - width/2;
		int top  = DisplayHeight(xDisplay, DefaultScreen(xDisplay))/2 - height/2;
		
		mIsFullScreen = fullScreen;
		
		if(miscParams)
		{
			NameValuePairList::const_iterator opt;
			NameValuePairList::const_iterator end = miscParams->end();
			
			// NB: Do not try to implement the externalGLContext option.
			//
			//	 Accepting a non-current context would expose us to the 
			//	 risk of segfaults when we made it current. Since the
			//	 application programmers would be responsible for these
			//	 segfaults, they are better discovering them in their code.
		
			if ((opt = miscParams->find("currentGLContext")) != end &&
				StringConverter::parseBool(opt->second))
			{
				if (! glXGetCurrentContext())
				{
					OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "currentGLContext was specified with no current GL context", "GLXWindow::create");
				}
				
				glxContext = glXGetCurrentContext();
				glxDrawable = glXGetCurrentDrawable();
			}
			
			// Note: Some platforms support AA inside ordinary windows
			if((opt = miscParams->find("FSAA")) != end) 
				samples = StringConverter::parseUnsignedInt(opt->second);
			
			if((opt = miscParams->find("displayFrequency")) != end) 
				frequency = (short)StringConverter::parseInt(opt->second);
			
			if((opt = miscParams->find("vsync")) != end) 
				vsync = StringConverter::parseBool(opt->second);

			if((opt = miscParams->find("vsyncInterval")) != end) 
				vsyncInterval = StringConverter::parseUnsignedInt(opt->second);

			if ((opt = miscParams->find("gamma")) != end)
				gamma = StringConverter::parseBool(opt->second);

			if((opt = miscParams->find("left")) != end) 
				left = StringConverter::parseInt(opt->second);
			
			if((opt = miscParams->find("top")) != end) 
				top = StringConverter::parseInt(opt->second);
			
			if((opt = miscParams->find("title")) != end) 
				title = opt->second;
			
			if ((opt = miscParams->find("externalGLControl")) != end)
				mIsExternalGLControl = StringConverter::parseBool(opt->second);
			
			if((opt = miscParams->find("parentWindowHandle")) != end) 
			{
				vector<String>::type tokens = StringUtil::split(opt->second, " :");
				
				if (tokens.size() == 3)
				{
					// deprecated display:screen:xid format
					parentWindow = StringConverter::parseUnsignedLong(tokens[2]);
				}
				else
				{
					// xid format
					parentWindow = StringConverter::parseUnsignedLong(tokens[0]);
				}
			}
			else if((opt = miscParams->find("externalWindowHandle")) != end) 
			{
				vector<String>::type tokens = StringUtil::split(opt->second, " :");
				
				LogManager::getSingleton().logMessage(
													  "GLXWindow::create: The externalWindowHandle parameter is deprecated.\n"
													  "Use the parentWindowHandle or currentGLContext parameter instead.");
				
				if (tokens.size() == 3)
				{
					// Old display:screen:xid format
					// The old GLX code always created a "parent" window in this case:
					parentWindow = StringConverter::parseUnsignedLong(tokens[2]);
				}
				else if (tokens.size() == 4)
				{
					// Old display:screen:xid:visualinfo format
					externalWindow = StringConverter::parseUnsignedLong(tokens[2]);
				}
				else
				{
					// xid format
					externalWindow = StringConverter::parseUnsignedLong(tokens[0]);
				}
			}
		}
		
		// Ignore fatal XErrorEvents during parameter validation:
		oldXErrorHandler = XSetErrorHandler(safeXErrorHandler);
		// Validate parentWindowHandle
		
		if (parentWindow != DefaultRootWindow(xDisplay))
		{
			XWindowAttributes windowAttrib;
			
			if (! XGetWindowAttributes(xDisplay, parentWindow, &windowAttrib) ||
				windowAttrib.root != DefaultRootWindow(xDisplay))
			{
				OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid parentWindowHandle (wrong server or screen)", "GLXWindow::create");
			}
		}
		
		// Validate externalWindowHandle
		
		if (externalWindow != 0)
		{
			XWindowAttributes windowAttrib;
			
			if (! XGetWindowAttributes(xDisplay, externalWindow, &windowAttrib) ||
				windowAttrib.root != DefaultRootWindow(xDisplay))
			{
				OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid externalWindowHandle (wrong server or screen)", "GLXWindow::create");
			}
			glxDrawable = externalWindow;
		}

		// Derive fbConfig
		
		::GLXFBConfig fbConfig = 0;
		
		if (glxDrawable)
		{
			fbConfig = mGLSupport->getFBConfigFromDrawable (glxDrawable, &width, &height);
		}

		if (! fbConfig && glxContext)
		{
			fbConfig = mGLSupport->getFBConfigFromContext (glxContext);
		}
			
		mIsExternal = (glxDrawable != 0);
		
		XSetErrorHandler(oldXErrorHandler);
		
		if (! fbConfig)
		{
			int minAttribs[] = {
				GLX_DRAWABLE_TYPE,  GLX_WINDOW_BIT,
				GLX_RENDER_TYPE,	GLX_RGBA_BIT,
				GLX_RED_SIZE,	   1,
				GLX_BLUE_SIZE,	  1,
				GLX_GREEN_SIZE,	 1,
				None
			};
			
			int maxAttribs[] = {
				GLX_SAMPLES,		samples,
				GLX_DOUBLEBUFFER,   1,
				GLX_STENCIL_SIZE,   INT_MAX,
				GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, 1,
				None
			};

			fbConfig = mGLSupport->selectFBConfig(minAttribs, maxAttribs);

			if (gamma != 0)
			{
				mGLSupport->getFBConfigAttrib(fbConfig, GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &gamma);
			}

			mHwGamma = (gamma != 0);
		}
		
    if (! fbConfig)
    {
      // This should never happen.
      OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unexpected failure to determine a GLXFBConfig","GLXWindow::create");
    }
		
		mIsTopLevel = (! mIsExternal && parentWindow == DefaultRootWindow(xDisplay));
		
		if (! mIsTopLevel)
		{
			mIsFullScreen = false;
			left = top = 0;
		}
		
		if (mIsFullScreen) 
		{
			mGLSupport->switchMode (width, height, frequency);
		}
		
		if (! mIsExternal)
		{
			XSetWindowAttributes attr;
			ulong mask;
			XVisualInfo *visualInfo = mGLSupport->getVisualFromFBConfig (fbConfig);
			
			attr.background_pixel = 0;
			attr.border_pixel = 0;
			attr.colormap = XCreateColormap(xDisplay, DefaultRootWindow(xDisplay), visualInfo->visual, AllocNone);
			attr.event_mask = StructureNotifyMask | VisibilityChangeMask | FocusChangeMask;
			mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
			
			if(mIsFullScreen && mGLSupport->mAtomFullScreen == None) 
			{
				LogManager::getSingleton().logMessage("GLXWindow::switchFullScreen: Your WM has no fullscreen support");
				
				// A second best approach for outdated window managers
				attr.backing_store = NotUseful;
				attr.save_under = False;
				attr.override_redirect = True;
				mask |= CWSaveUnder | CWBackingStore | CWOverrideRedirect;
				left = top = 0;
			} 
			
			// Create window on server
			mWindow = XCreateWindow(xDisplay, parentWindow, left, top, width, height, 0, visualInfo->depth, InputOutput, visualInfo->visual, mask, &attr);
			
			XFree(visualInfo);
			
			if(!mWindow) 
			{
				OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create an X Window", "GLXWindow::create");
			}
			
			if (mIsTopLevel)
			{
				XWMHints *wmHints;
				XSizeHints *sizeHints;
				
				if ((wmHints = XAllocWMHints()) != NULL) 
				{
					wmHints->initial_state = NormalState;
					wmHints->input = True;
					wmHints->flags = StateHint | InputHint;
					
					int depth = DisplayPlanes(xDisplay, DefaultScreen(xDisplay));
					
					// Check if we can give it an icon
					if(depth == 24 || depth == 32) 
					{
						if(mGLSupport->loadIcon("GLX_icon.png", &wmHints->icon_pixmap, &wmHints->icon_mask))
						{
							wmHints->flags |= IconPixmapHint | IconMaskHint;
						}
					}
				}
				
				// Is this really necessary ? Which broken WM might need it?
				if ((sizeHints = XAllocSizeHints()) != NULL)
				{
					sizeHints->flags = USPosition;
				}
				
				XTextProperty titleprop;
				char *lst = (char*)title.c_str();
				XStringListToTextProperty((char **)&lst, 1, &titleprop);
				XSetWMProperties(xDisplay, mWindow, &titleprop, NULL, NULL, 0, sizeHints, wmHints, NULL);
				
				XFree(titleprop.value);
				XFree(wmHints);
				XFree(sizeHints);
				
				XSetWMProtocols(xDisplay, mWindow, &mGLSupport->mAtomDeleteWindow, 1);
				
				XWindowAttributes windowAttrib;
				
				XGetWindowAttributes(xDisplay, mWindow, &windowAttrib);
				
				left = windowAttrib.x;
				top = windowAttrib.y;
				width = windowAttrib.width;
				height = windowAttrib.height;
			}
			
			glxDrawable = mWindow;
			
			XMapWindow(xDisplay, mWindow);
			
			if (mIsFullScreen)
			{
				switchFullScreen (true);
			}
			XFlush(xDisplay);
			
			WindowEventUtilities::_addRenderWindow(this);
		}
		
    mContext = new GLXContext(mGLSupport, fbConfig, glxDrawable, glxContext);
		
		::GLXDrawable oldDrawable = glXGetCurrentDrawable();
		::GLXContext  oldContext  = glXGetCurrentContext();
		
		mContext->setCurrent();
		
		if (! mIsExternalGLControl && GLXEW_SGI_swap_control)
		{
			glXSwapIntervalSGI (vsync ? vsyncInterval : 0);
		}
		
		mContext->endCurrent();
		
		glXMakeCurrent (mGLSupport->getGLDisplay(), oldDrawable, oldContext);
		
		int fbConfigID;
		
		mGLSupport->getFBConfigAttrib(fbConfig, GLX_FBCONFIG_ID, &fbConfigID);
		
		LogManager::getSingleton().logMessage("GLXWindow::create used FBConfigID = " + StringConverter::toString(fbConfigID));
		
		mName = name;
		mWidth = width;
		mHeight = height;
		mLeft = left;
		mTop = top;
		mActive = true;
		mClosed = false;
	}
Beispiel #29
0
	//-----------------------------------------------------------------------
	String CgProgram::resolveCgIncludes(const String& inSource, Resource* resourceBeingLoaded, const String& fileName)
	{
		String outSource;
		// output will be at least this big
		outSource.reserve(inSource.length());

		size_t startMarker = 0;
		size_t i = inSource.find("#include");
		while (i != String::npos)
		{
			size_t includePos = i;
			size_t afterIncludePos = includePos + 8;
			size_t newLineBefore = inSource.rfind("\n", includePos);

			// check we're not in a comment
			size_t lineCommentIt = inSource.rfind("//", includePos);
			if (lineCommentIt != String::npos)
			{
				if (newLineBefore == String::npos || lineCommentIt > newLineBefore)
				{
					// commented
					i = inSource.find("#include", afterIncludePos);
					continue;
				}

			}
			size_t blockCommentIt = inSource.rfind("/*", includePos);
			if (blockCommentIt != String::npos)
			{
				size_t closeCommentIt = inSource.rfind("*/", includePos);
				if (closeCommentIt == String::npos || closeCommentIt < blockCommentIt)
				{
					// commented
					i = inSource.find("#include", afterIncludePos);
					continue;
				}

			}

			// find following newline (or EOF)
			size_t newLineAfter = inSource.find("\n", afterIncludePos);
			// find include file string container
			String endDelimeter = "\"";
			size_t startIt = inSource.find("\"", afterIncludePos);
			if (startIt == String::npos || startIt > newLineAfter)
			{
				// try <>
				startIt = inSource.find("<", afterIncludePos);
				if (startIt == String::npos || startIt > newLineAfter)
				{
					OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
						"Badly formed #include directive (expected \" or <) in file "
						+ fileName + ": " + inSource.substr(includePos, newLineAfter-includePos),
						"CgProgram::preprocessor");
				}
				else
				{
					endDelimeter = ">";
				}
			}
			size_t endIt = inSource.find(endDelimeter, startIt+1);
			if (endIt == String::npos || endIt <= startIt)
			{
				OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
					"Badly formed #include directive (expected " + endDelimeter + ") in file "
					+ fileName + ": " + inSource.substr(includePos, newLineAfter-includePos),
					"CgProgram::preprocessor");
			}

			// extract filename
			String filename(inSource.substr(startIt+1, endIt-startIt-1));

			// open included file
			DataStreamPtr resource = ResourceGroupManager::getSingleton().
				openResource(filename, resourceBeingLoaded->getGroup(), resourceBeingLoaded);

			// replace entire include directive line
			// copy up to just before include
			if (newLineBefore != String::npos && newLineBefore >= startMarker)
				outSource.append(inSource.substr(startMarker, newLineBefore-startMarker+1));

			size_t lineCount = 0;
			size_t lineCountPos = 0;
			
			// Count the line number of #include statement
			lineCountPos = outSource.find('\n');
			while(lineCountPos != String::npos)
			{
				lineCountPos = outSource.find('\n', lineCountPos+1);
				lineCount++;
			}

			// Add #line to the start of the included file to correct the line count
			outSource.append("#line 1 \"" + filename + "\"\n");

			outSource.append(resource->getAsString());

			// Add #line to the end of the included file to correct the line count
			outSource.append("\n#line " + Ogre::StringConverter::toString(lineCount) + 
				"\"" + fileName + "\"\n");

			startMarker = newLineAfter;

			if (startMarker != String::npos)
				i = inSource.find("#include", startMarker);
			else
				i = String::npos;

		}
		// copy any remaining characters
		outSource.append(inSource.substr(startMarker));

		return outSource;
	}
    void AndroidEGLWindow::create(const String& name, uint width, uint height,
                               bool fullScreen, const NameValuePairList *miscParams)
    {
        mName = name;
        mWidth = width;
        mHeight = height;
        mLeft = 0;
        mTop = 0;
        mIsFullScreen = fullScreen;
        void* eglContext = NULL;
        AConfiguration* config = NULL;
        
        if (miscParams)
        {
            NameValuePairList::const_iterator opt;
            NameValuePairList::const_iterator end = miscParams->end();
            
            if ((opt = miscParams->find("currentGLContext")) != end &&
                StringConverter::parseBool(opt->second))
            {
                eglContext = eglGetCurrentContext();
                if (eglContext)
                {
                    OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                                "currentGLContext was specified with no current GL context",
                                "EGLWindow::create");
                }
                
                eglContext = eglGetCurrentContext();
                mEglSurface = eglGetCurrentSurface(EGL_DRAW);
            }
            
            
            if((opt = miscParams->find("externalWindowHandle")) != end)
            {
                mWindow = (ANativeWindow*)(Ogre::StringConverter::parseSizeT(opt->second));
            }
            
            if((opt = miscParams->find("androidConfig")) != end)
            {
                config = (AConfiguration*)(Ogre::StringConverter::parseSizeT(opt->second));
            }
            
            int ctxHandle = -1;
            if((miscParams->find("externalGLContext")) != end)
            {
                mIsExternalGLControl = true;
                ctxHandle = Ogre::StringConverter::parseInt(opt->second);
            }
            
            if((opt = miscParams->find("maxColourBufferSize")) != end)
            {
                mMaxBufferSize = Ogre::StringConverter::parseInt(opt->second);
            }
            
            if((opt = miscParams->find("maxDepthBufferSize")) != end)
            {
                mMaxDepthSize = Ogre::StringConverter::parseInt(opt->second);
            }
            
            if((opt = miscParams->find("maxStencilBufferSize")) != end)
            {
                mMaxStencilSize = Ogre::StringConverter::parseInt(opt->second);
            }
        }
        
        initNativeCreatedWindow(miscParams);
        
        if (mEglSurface)
        {
            mEglConfig = mGLSupport->getGLConfigFromDrawable (mEglSurface, &width, &height);
        }
        
        if (!mEglConfig && eglContext)
        {
            mEglConfig = mGLSupport->getGLConfigFromContext(eglContext);
            
            if (!mEglConfig)
            {
                // This should never happen.
                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                            "Unexpected failure to determine a EGLFBConfig",
                            "EGLWindow::create");
            }
        }
        
        mIsExternal = (mEglSurface != 0);
        
        if (!mEglConfig)
        {

            _createInternalResources(mWindow, config);
            mHwGamma = false;
        }
        
        mContext = createEGLContext();
        
        mActive = true;
        mVisible = true;
        mClosed = false;
    }