亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? ogl.cpp

?? 一個開源的嵌入式flash播放器的源代碼
?? CPP
字號:
// ogl.cpp	-- by Thatcher Ulrich <tu@tulrich.com>

// This source code has been donated to the Public Domain.  Do
// whatever you want with it.

// Some OpenGL helpers; mainly to generically deal with extensions.


#include <SDL.h>
#include "base/ogl.h"
#include "base/utility.h"
#include <stdlib.h>
#include <string.h>


namespace ogl {

	bool	is_open = false;

	// Pointers to extension functions.
	typedef void * (APIENTRY * PFNWGLALLOCATEMEMORYNVPROC) (int size, float readfreq, float writefreq, float priority);
	typedef void (APIENTRY * PFNWGLFREEMEMORYNVPROC) (void *pointer);
	typedef void (APIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (int size, void* buffer);
	typedef void (APIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fence_array);
	typedef void (APIENTRY * PFNGLSETFENCENVPROC) (GLuint fence_id, GLenum condition);
	typedef void (APIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence_id);

	typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
	typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
	typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
	typedef void (APIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);

	PFNWGLALLOCATEMEMORYNVPROC	wglAllocateMemoryNV = 0;
	PFNWGLFREEMEMORYNVPROC	wglFreeMemoryNV = 0;
	PFNGLVERTEXARRAYRANGENVPROC	glVertexArrayRangeNV = 0;
	PFNGLGENFENCESNVPROC glGenFencesNV = 0;
	PFNGLSETFENCENVPROC glSetFenceNV = 0;
	PFNGLFINISHFENCENVPROC glFinishFenceNV = 0;

	PFNGLACTIVETEXTUREARBPROC	glActiveTextureARB = 0;
	PFNGLCLIENTACTIVETEXTUREARBPROC	glClientActiveTextureARB = 0;
	PFNGLMULTITEXCOORD2FARBPROC	glMultiTexCoord2fARB = 0;
	PFNGLMULTITEXCOORD2FVARBPROC	glMultiTexCoord2fvARB = 0;


	// GL_CLAMP or GL_CLAMP_TO_EDGE, depending on which is available.
	int	s_clamp_to_edge = GL_CLAMP;

	// Big, fast vertex-memory buffer.
	const int	VERTEX_BUFFER_SIZE = 4 << 20;
	void*	vertex_memory_buffer = 0;
	int	vertex_memory_top = 0;
	bool	vertex_memory_from_malloc = false;	// tells us whether to wglFreeMemoryNV() or free() the buffer when we're done.


	const int	STREAM_SUB_BUFFER_COUNT = 2;

	class vertex_stream
	{
	// Class to facilitate streaming verts to the video card.  Takes
	// care of fencing, and buffer bookkeeping.
	public:
		vertex_stream(int buffer_size);
		~vertex_stream();
	
		void*	reserve_memory(int size);
		void	flush_combiners();
	
	private:
		int	m_sub_buffer_size;
		int	m_buffer_top;
		void*	m_buffer;
		int	m_extra_bytes;	// extra bytes after last block; used to pad up to write-combiner alignment
	
		unsigned int	m_fence[4];
	};


	vertex_stream*	s_stream = NULL;


	void	open()
	// Scan for extensions.
	{
		wglAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC) SDL_GL_GetProcAddress( PROC_NAME_PREFIX "AllocateMemoryNV" );
		wglFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC) SDL_GL_GetProcAddress( PROC_NAME_PREFIX "FreeMemoryNV" );
		glVertexArrayRangeNV = (PFNGLVERTEXARRAYRANGENVPROC) SDL_GL_GetProcAddress( "glVertexArrayRangeNV" );

		glGenFencesNV = (PFNGLGENFENCESNVPROC) SDL_GL_GetProcAddress( "glGenFencesNV" );
		glSetFenceNV = (PFNGLSETFENCENVPROC) SDL_GL_GetProcAddress( "glSetFenceNV" );
		glFinishFenceNV = (PFNGLFINISHFENCENVPROC) SDL_GL_GetProcAddress( "glFinishFenceNV" );

		glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB");
		glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glClientActiveTextureARB");
		glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord2fARB");
		glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC) SDL_GL_GetProcAddress("glMultiTexCoord2fvARB");

		if (check_extension("GL_SGIS_texture_edge_clamp")
		    || check_extension("GL_EXT_texture_edge_clamp"))
		{
			// Use CLAMP_TO_EDGE, since it's available.
			s_clamp_to_edge = GL_CLAMP_TO_EDGE;
		}
	}


	void	close()
	// Release anything we need to.
	{
		// @@ free that mongo vertex buffer.
	}


	int	get_clamp_mode()
	// Return a constant to pass to glTexParameteri(GL_TEXTURE_2D,
	// GL_TEXTURE_WRAP_x, ...), which is either GL_CLAMP or
	// GL_CLAMP_TO_EDGE, depending on whether GL_CLAMP_TO_EDGE is
	// available.
	{
		return s_clamp_to_edge;
	}


	bool	check_extension(const char* extension)
	// Some extension checking code snipped from glut.
	{
		static const char*	extensions = NULL;
		const char*	start;
		char*	where;
		char*	terminator;
		bool	supported;
	
		// Extension names should not have spaces
		where = strchr(extension, ' ');
		if (where || *extension == '\0') return false;
	
		// Grab extensions (but only once)
		if (!extensions) extensions = (const char*)glGetString(GL_EXTENSIONS);
	
		// Look for extension
		start = extensions;
		supported = false;
		while (!supported)
		{
			// Does extension SEEM to be supported?
			where = strstr((const char*)start, extension);
			if (!where) break;

			// Ok, extension SEEMS to be supported
			supported = true;

			// Check for space before extension
			supported &= (where == start) || (where[-1] == ' ');

			// Check for space after extension
			terminator = where + strlen(extension);
			supported &= (*terminator == '\0') || (*terminator == ' ');

			// Next search starts at current terminator
			start = terminator;
		}

		return supported;
	}


	void*	allocate_vertex_memory( int size )
	// Allocate a block of memory for storing vertex data.  Using this
	// allocator will hopefully give you faster glDrawElements(), if
	// you do vertex_array_range on it before rendering.
	{
		// For best results, we must allocate one big ol' chunk of
		// vertex memory on the first call to this function, via
		// wglAllocateMemoryNV, and then allocate sub-chunks out of
		// it.

		if ( vertex_memory_buffer == 0 ) {
			// Need to allocate the big chunk.
			
			// If we have NV's allocator, then use it.
			if ( wglAllocateMemoryNV ) {
				vertex_memory_buffer = wglAllocateMemoryNV( VERTEX_BUFFER_SIZE, 0.f, 0.f, 0.5f );	// @@ this gets us AGP memory.
//				wglAllocateMemoryNV( size, 0.f, 0.f, 1.0f );	// @@ this gets us video memory.
				vertex_memory_from_malloc = false;
				vertex_memory_top = 0;

				if ( vertex_memory_buffer && glVertexArrayRangeNV ) {
					glVertexArrayRangeNV( VERTEX_BUFFER_SIZE, vertex_memory_buffer );
				}

				glEnableClientState(GL_VERTEX_ARRAY_RANGE_NV);	// GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV
			}
			// else we'll fall back on malloc() for vb allocations.
		}

		// Carve a chunk out of our big buffer, or out of malloc if
		// the buffer is dry.

		if ( vertex_memory_buffer && vertex_memory_top + size <= VERTEX_BUFFER_SIZE ) {
			// Just allocate from the end of the big buffer and increment the top.
			unsigned char*	buffer = (unsigned char*) vertex_memory_buffer + vertex_memory_top;
			vertex_memory_top += size;

			return (void*) buffer;

		} else {
			// Fall back to malloc.
			printf( "avm: warning, falling back to malloc!\n" );
			return malloc( size );
		}
	}


	void	free_vertex_memory(void* buffer)
	// Frees a buffer previously allocated via allocate_vertex_memory().
	{
		// this function is not ready for prime-time.
		assert( 0 );
	}


	void	gen_fences(int count, unsigned int* fence_array)
	// Wrapper for glGenFencesNV.
	{
		if (glGenFencesNV) {
			glGenFencesNV(count, (GLuint*)fence_array);
		}
		else
		{
			// set all fences to 0.
			for (int i = 0; i < count; i++) {
				fence_array[i] = 0;
			}
		}
	}

	
	void	set_fence(unsigned int fence_id)
	// Use this to declare all previous glDrawElements() calls as
	// belonging to the specified fence.  A subsequent
	// finish_fence(id) will block until those drawing calls have
	// completed.
	{
		if (glSetFenceNV)
		{
			glSetFenceNV(fence_id, GL_ALL_COMPLETED_NV);
		}
		// else no-op.
	}


	void	finish_fence(unsigned int fence_id)
	// Block until all gl drawing calls, associated with the specified
	// fence, have completed.
	{
		if (glFinishFenceNV)
		{
			glFinishFenceNV(fence_id);
		}
		// else no-op.
	}


	void*	stream_get_vertex_memory(int size)
	// Return a buffer to contain size bytes of vertex memory.
	// Put your vertex data in it, then call
	// stream_flush_combiners(), then call glDrawElements() to
	// draw the primitives.
	{
		if (s_stream == NULL) {
			s_stream = new vertex_stream(VERTEX_BUFFER_SIZE);
		}

		return s_stream->reserve_memory(size);
	}


	void	stream_flush_combiners()
	// Make sure to flush all data written to the most recently
	// requested vertex buffer (requested by the last call to
	// stream_get_vertex_memory()).  Ensure that the data doesn't
	// get hung up in a processor write-combiner.
	{
		assert(s_stream);
		if (s_stream == NULL) return;

		s_stream->flush_combiners();
	}


	static const int	WRITE_COMBINER_ALIGNMENT = 64;	// line-size (in bytes) of the write-combiners, must be power of 2


	int	wc_align_up(int size)
	// Return given size, rounded up to the next nearest write combiner
	// alignment boundary.
	{
		assert((WRITE_COMBINER_ALIGNMENT & (WRITE_COMBINER_ALIGNMENT - 1)) == 0);	// make sure it's a power of 2

		return (size + WRITE_COMBINER_ALIGNMENT - 1) & ~(WRITE_COMBINER_ALIGNMENT - 1);
	}


	//
	// vertex_stream
	//

	vertex_stream::vertex_stream(int buffer_size)
	// Construct a streaming buffer, with vertex RAM of the specified size.
	{
		assert(buffer_size >= STREAM_SUB_BUFFER_COUNT);
	
		m_sub_buffer_size = buffer_size / STREAM_SUB_BUFFER_COUNT;
		m_buffer = ogl::allocate_vertex_memory(buffer_size);
		m_buffer_top = 0;
		m_extra_bytes = 0;
	
		// set up fences.
		ogl::gen_fences(4, &m_fence[0]);

		// Set (dummy) fences which will be finished as we reach them.
		ogl::set_fence(m_fence[1]);
		ogl::set_fence(m_fence[2]);
		ogl::set_fence(m_fence[3]);
	}

	vertex_stream::~vertex_stream()
	{
//		ogl::free_vertex_memory(m_buffer);
	}

	void*	vertex_stream::reserve_memory(int size)
	// Clients should call this to get a temporary chunk of fast
	// vertex memory.  Fill it with vertex info and call
	// glVertexPointer()/glDrawElements().  The memory won't get
	// stomped until the drawing is finished, provided you use the
	// returned buffer in a glDrawElements call before you call
	// reserve_memory() to get the next chunk.
	{
		assert(size <= m_sub_buffer_size);

		int	aligned_size = wc_align_up(size);
		m_extra_bytes = aligned_size - size;
	
		for (int sub_buffer = 1; sub_buffer <= STREAM_SUB_BUFFER_COUNT; sub_buffer++)
		{
			int	border = m_sub_buffer_size * sub_buffer;

			if (m_buffer_top <= border
			    && m_buffer_top + aligned_size > border)
			{
				// Crossing into the next sub-buffer.

				int	prev_buffer = sub_buffer - 1;
				int	next_buffer = sub_buffer % STREAM_SUB_BUFFER_COUNT;

				// Protect the previous sub-buffer.
				ogl::set_fence(m_fence[prev_buffer]);

				// Don't overwrite the next sub-buffer while it's still active.
				ogl::finish_fence(m_fence[next_buffer]);
	
				// Start the next quarter-buffer.
				m_buffer_top = m_sub_buffer_size * next_buffer;
			}
		}
	
		void*	buf = ((char*) m_buffer) + m_buffer_top;
		m_buffer_top += aligned_size;
	
		return buf;
	}
	
	
	void	vertex_stream::flush_combiners()
	// Make sure the tail of the block returned by the last call
	// to reserve_memory() gets written to the system RAM.  If the
	// block doesn't end on a write-combiner line boundary, the
	// last bit of data may still be waiting to be flushed.
	//
	// That's my theory anyway -- farfetched but I'm not sure how
	// else to explain certain bug reports of spurious triangles
	// being rendered.
	{
		if (m_extra_bytes) {
			// Fill up the rest of the last write-combiner line.
			memset(((char*) m_buffer) + m_buffer_top - m_extra_bytes, 0, m_extra_bytes);
		}
	}


	// Wrappers for multitexture extensions; no-op if the extension doesn't exist.

	void	active_texture(int stage)
	// Set the currently active texture stage; use GL_TEXTUREx_ARB.
	{
		if (glActiveTextureARB)
		{
			glActiveTextureARB(stage);
		}
	}

	void	client_active_texture(int stage)
	// Set the currently active texture stage for vertex array
	// setup; use GL_TEXTUREx_ARB.
	{
		if (glClientActiveTextureARB)
		{
			glClientActiveTextureARB(stage);
		}
	}

	void	multi_tex_coord_2f(int stage, float s, float t)
	// Texture coords for the current vertex, in the specified
	// stage.
	{
		if (glMultiTexCoord2fARB)
		{
			glMultiTexCoord2fARB(stage, s, t);
		}
	}

	void	multi_tex_coord_2fv(int stage, float* st)
	// Texture coords for the current vertex, in the specified
	// stage.
	{
		if (glMultiTexCoord2fvARB)
		{
			glMultiTexCoord2fvARB(stage, st);
		}
	}
};


// Local Variables:
// mode: C++
// c-basic-offset: 8 
// tab-width: 8

// indent-tabs-mode: t
// End:

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲人成伊人成综合网小说| 91亚洲精品久久久蜜桃| 午夜视频一区在线观看| 亚洲天堂成人在线观看| 国产精品天天看| 国产午夜精品福利| 中文一区在线播放| 国产精品久久三区| 亚洲欧洲美洲综合色网| 亚洲视频中文字幕| 亚洲黄色片在线观看| 一区二区三区在线观看视频 | 成人免费毛片嘿嘿连载视频| 韩国av一区二区三区四区| 国产一区二区在线观看免费| 国产成人亚洲综合色影视| 成人午夜短视频| 一本色道久久综合精品竹菊| 欧美在线你懂的| 日韩精品一区二区三区在线观看 | 综合久久久久综合| 亚洲一区二区综合| 天天亚洲美女在线视频| 日韩av一区二区在线影视| 蜜桃在线一区二区三区| 极品尤物av久久免费看| 99精品欧美一区二区三区小说| 91激情五月电影| 日韩视频123| 国产精品网站在线播放| 亚洲777理论| 国产伦精品一区二区三区免费| 成人福利视频在线| 91麻豆精品国产91久久久资源速度 | 日本免费在线视频不卡一不卡二| 麻豆精品一区二区三区| 成人午夜视频在线观看| 欧美精品久久一区| 国产精品久久午夜夜伦鲁鲁| 青青青爽久久午夜综合久久午夜| 国产成人日日夜夜| 欧美男人的天堂一二区| 中文字幕的久久| 美女网站视频久久| 色天使色偷偷av一区二区| 久久人人超碰精品| 日韩在线一区二区三区| 97超碰欧美中文字幕| 精品国产sm最大网站免费看| 亚洲一二三四区| 成人手机电影网| 日韩视频在线你懂得| 亚洲免费观看高清完整版在线观看 | 精品在线播放午夜| 91成人在线免费观看| 国产欧美精品一区aⅴ影院| 青娱乐精品视频| 欧美日韩国产天堂| 亚洲最大成人网4388xx| www.性欧美| 国产三级精品三级| 精品综合久久久久久8888| 欧美日韩成人综合在线一区二区| 亚洲欧美日韩久久精品| 成人动漫在线一区| 欧美国产日韩精品免费观看| 黄页网站大全一区二区| 69堂亚洲精品首页| 午夜影院在线观看欧美| 欧美亚洲国产一区在线观看网站| 亚洲欧美日韩在线| 色综合天天综合网天天看片| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆| 久久不见久久见免费视频1| 91麻豆精品国产| 日本女人一区二区三区| 日韩欧美激情在线| 久久精品国产免费| 久久综合中文字幕| 国产在线不卡一卡二卡三卡四卡| 日韩欧美一级精品久久| 看电影不卡的网站| 欧美α欧美αv大片| 狠狠色狠狠色综合| 国产午夜精品在线观看| 成人动漫视频在线| 悠悠色在线精品| 欧美人妇做爰xxxⅹ性高电影| 天天色天天爱天天射综合| 日韩午夜激情电影| 国产激情偷乱视频一区二区三区| 欧美激情艳妇裸体舞| 99久久久精品| 天使萌一区二区三区免费观看| 69堂精品视频| 国产盗摄一区二区三区| 亚洲男人都懂的| 666欧美在线视频| 国产乱码字幕精品高清av| 国产精品全国免费观看高清 | 午夜精品免费在线| 日韩欧美一级在线播放| 成人sese在线| 午夜成人在线视频| 国产亚洲一区二区三区在线观看| 97成人超碰视| 蜜桃精品视频在线| 国产精品日韩精品欧美在线| 欧美日产国产精品| 国产精品综合在线视频| 一个色妞综合视频在线观看| www成人在线观看| 91久久精品日日躁夜夜躁欧美| 免费成人av在线播放| 欧美国产日韩亚洲一区| 99r国产精品| 精品一区二区三区在线播放视频 | 91免费观看在线| 蜜桃av一区二区三区| 亚洲国产精品v| 日韩视频免费直播| 精品视频免费看| 99久久久久久| 国产乱色国产精品免费视频| 亚洲成人精品一区| 欧美激情一区二区三区蜜桃视频| 欧美精品国产精品| 日本高清不卡在线观看| 国产成人午夜电影网| 美国欧美日韩国产在线播放| 一级精品视频在线观看宜春院| 久久久精品影视| 日韩三级免费观看| 欧美日韩国产首页在线观看| 97久久人人超碰| 成人教育av在线| 91福利在线免费观看| 国产91丝袜在线观看| 蜜臀av一区二区在线免费观看| 一区二区三区不卡视频 | 亚洲激情图片小说视频| 国产精品无人区| 午夜久久久久久| 一区二区三区在线视频观看 | 亚洲一区中文日韩| 国产精品电影一区二区| 国产日产欧美一区二区视频| 精品欧美久久久| 日韩欧美综合在线| 欧美一区二区女人| 91精品久久久久久久99蜜桃| 欧美日韩夫妻久久| 欧美人成免费网站| 日韩欧美在线综合网| 91精品欧美综合在线观看最新| 欧美日韩一区 二区 三区 久久精品| 日本精品免费观看高清观看| 色婷婷久久久亚洲一区二区三区| 99精品视频在线观看| 99国产精品久| 欧美在线免费观看视频| 欧美三级日韩三级| 欧美一级视频精品观看| 欧美成人猛片aaaaaaa| 日韩欧美国产一区二区三区| 日韩欧美一区在线观看| 久久久久久久综合日本| 中文文精品字幕一区二区| 中文字幕亚洲欧美在线不卡| 一区二区三区免费观看| 成人一区二区视频| 成人高清免费观看| 在线观看国产日韩| 日韩欧美一区在线观看| 欧美国产日韩a欧美在线观看 | 蜜乳av一区二区| 岛国av在线一区| 欧洲视频一区二区| 日韩免费在线观看| 中文字幕一区在线| 天天av天天翘天天综合网| 精品一区二区三区的国产在线播放| 成人性视频免费网站| 欧美在线你懂得| 精品成人免费观看| 一区二区视频在线| 国产综合色视频| 91久久久免费一区二区| 精品三级在线看| 亚洲激情五月婷婷| 国产一区高清在线| 欧美影院午夜播放| 国产日韩一级二级三级| 日日夜夜精品免费视频| 国产成人久久精品77777最新版本 国产成人鲁色资源国产91色综 | 91麻豆精品久久久久蜜臀| 亚洲国产精品v| 精品一区二区三区不卡| 欧美日韩一级大片网址| 国产精品久久久久久久久快鸭|