精华内容
下载资源
问答
  • Shikoba:使用FreeType 2的OpenGL 3字体库
  • 适用于OpenTK的现代OpenGL文本呈现。 从。 原始 您可以通过安装此。 支持平台 QuickFont已通过测试,可在Windows,Linux和OSX上运行。 最低支持的OpenGL版本是3.0 请注意,示例项目将需要更改以在OSX上...
  • OpenGL字体绘制

    2019-08-15 14:35:32
    opengl字体类,提供初学者参考学习 opengl初始化之后,创建字体 font.init(L"微软雅黑", 32, 512); 然后在绘制函数里面添加以下测试代码: //开启2D模式,后面的800x600要根据窗口的实际客户区大小设置,不然...
    /*
    
     glfont.hpp
    
     sdragonx 2019-08-15 00:03:33
    
     opengl字体类,提供初学者参考学习
    
    opengl初始化之后,创建字体
    font.init(L"微软雅黑", 32, 512);
    
    然后在绘制函数里面添加以下测试代码:
    
    //开启2D模式,后面的800x600要根据窗口的实际客户区大小设置,不然缩放之后效果不好
    push_view2D(0, 0, 800, 600);
    
    wchar_t* str = L"abcdef字体绘制abcdef?123456ijk微软雅黑";
    
    font.color = vec4ub(255, 255, 255, 128);
    font.print(0, 0, str, wcslen(str));
    
    font.tab_print(0, 32, L"abc\t123456\t7890", TEXT_MAX);
    
    wchar_t* tabled = L"abcdef字体绘制\tabc制表符\t123456";
    font.color = vec4ub(255, 0, 0, 255);
    font.tab_print(0, 64, tabled, wcslen(tabled));
    
    font.color = vec4ub(255, 0, 0, 255);
    font.draw_text(0, 200, 200, 400, str, wcslen(str), PT_LEFT);
    font.color = vec4ub(0, 255, 0, 255);
    font.draw_text(300, 200, 200, 400, str, wcslen(str), PT_CENTER);
    font.color = vec4ub(255, 0, 255, 255);
    font.draw_text(600, 200, 200, 400, str, wcslen(str), PT_RIGHT);
    
    pop_view();
    //代码结束
    
    */
    #ifndef GLFONT_HPP_20190815000333
    #define GLFONT_HPP_20190815000333
    
    #include <windows.h>
    
    #include <stdint.h>
    #include <map>
    #include <vector>
    
    //opengl头文件,根据环境更改
    #ifdef __glew_h__
    	#include <glew.h>
    #elif defined(__glad_h_)
    	#include <glad.h>
    #else
    	#include <gl/gl.h>
    #endif
    
    #if defined(__GNUC__) || defined(__clang__)
    	#define TYPENAME typename
    #else
    	#define TYPENAME
    #endif
    
    #define CGL_DEFAULT_FONT_SIZE 16	//默认字体大小
    #define TEXT_MAX UINT32_MAX 		//0xFFFFFFFF
    
    namespace cgl{
    
    #pragma pack(push, 1)
    
    //大纹理里面小图块结构
    class teximage
    {
    public:
    	typedef teximage this_type;
    
    public:
    	intptr_t image;					//纹理
    	uint16_t x, y, width, height;	//小图在大图里面的位置信息
    	float u1, v1, u2, v2;			//小图的uv坐标信息
    
    public:
    	teximage():image(), x(), y(), width(), height(), u1(0.0f), v1(0.0f), u2(1.0f), v2(1.0f)
    	{
    	}
    
    	this_type& operator=(const this_type& div)
    	{
    		image = div.image;
    		x = div.x;
    		y = div.y;
    		width = div.width;
    		height = div.height;
    		u1 = div.u1;
    		v1 = div.v1;
    		u2 = div.u2;
    		v2 = div.v2;
    		return *this;
    	}
    };
    
    //字符信息
    //如果一个字符需要输出到left、top的位置,字符实际位置是left+x、top+y
    //输出完毕之后,下一个字符的位置是left+next_x、top+next_y
    struct char_info
    {
    	int16_t x;	//字符偏移位置
    	int16_t y;
    	int16_t next_x;//字符大小,下一字符偏移位置
    	int16_t next_y;
    };
    
    //vec3<T>
    template<typename T>
    struct vec3
    {
    	T x, y, z;
    };
    
    typedef vec3<int> vec3i;
    typedef vec3<float> vec3f;
    
    //vec4<T>
    template<typename T>
    struct vec4
    {
    	union{
    		T data[4];
    		struct{
    			T x, y, width, height;
    		};
    		struct{
                T red, green, blue, alpha;
            };
        };
    
    	vec4() : x(), y(), width(), height(){/*void*/}
    	vec4(T vx, T vy, T vw, T vh) : x(vx), y(vy), width(vw), height(vh){/*void*/}
    };
    
    typedef vec4<int> vec4i;
    typedef vec4<float> vec4f;
    typedef vec4<BYTE> vec4ub;
    
    
    template<typename VT, typename TT, typename CT>
    struct vtx3t2c4
    {
    	typedef vtx3t2c4 this_type;
    	typedef vec4<CT> color_type;
    
    	VT x, y, z;
    	TT u, v;
    	color_type color;
    
    	vtx3t2c4() : x(), y(), z(), u(), v(), color(){/*void*/}
    	vtx3t2c4(const vec3<VT>& vtx, TT tu, TT tv, const color_type& cc) :
    		x(v.x), y(v.y), z(v.z), u(tu), v(tv), color(cc) { /*void*/ }
    
    	vtx3t2c4(VT vx, VT vy, VT vz, TT vu, TT vv, const color_type& cc) :
    		x(vx), y(vy), z(vz), u(vu), v(vv), color(cc) { /*void*/ }
    
    	this_type& operator=(const vec3<VT>& p)
    	{
    		x = p.x;
    		y = p.y;
    		z = p.z;
    		return *this;
    	}
    };
    
    typedef vtx3t2c4<float, float, uint8_t> vtx3f;
    
    #pragma pack(pop)
    
    //---------------------------------------------------------------------------
    //opengl的一些扩展函数
    
    //2D视觉模式,如果你使用的是矩阵操作,把这里面的函数替换成矩阵操作
    void push_view2D(int left, int top, int width, int height)
    {
    	glMatrixMode(GL_PROJECTION);
    	glPushMatrix();
    	glLoadIdentity();
    /*
    #if CGL_COORDINATE == CGL_LOWER_LEFT
    	//直角坐标系
    	this->ortho(left, width, top, height, 0, INT16_MAX);
    	//重新设置正面,默认GL_CCW
    	glFrontFace(GL_CCW);
    
    #else*/
    
    	//windows坐标系
    	glOrtho(left, left+width, top+height, top, 0, INT16_MAX);
    	glFrontFace(GL_CW);
    //#endif
    
    	//十字坐标系
    	//glOrtho(-width/2, width/2, -height/2, height/2, 0, INT_MAX);//
    
    	//反转屏幕
    	//glScalef(1.0f, -1.0f, 1.0f);
    	//glTranslatef(0.0f, -height, 0.0f);
    
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    	glTranslatef(0.375f, 0.375f, 0.0f);//GL_POINTS and GL_LINES don't touch the right pixels
    	glDisable(GL_DEPTH_TEST);//关闭深度测试
    	glDisable(GL_CULL_FACE); //关闭面剔除
    }
    
    //还原视觉模式
    void pop_view()
    {
    	glMatrixMode(GL_PROJECTION);
    	glPopMatrix();
    	glMatrixMode(GL_MODELVIEW);
    }
    
    //绘图函数,这个根据使用的库更改和优化
    void vtx_begin(const vtx3f* vtx)
    {
    	glVertexPointer(3, GL_FLOAT, sizeof(vtx3f), vtx);
    	glTexCoordPointer(2, GL_FLOAT, sizeof(vtx3f), &vtx->u);
    	glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vtx3f), vtx->color.data);
    
    	glEnableClientState(GL_VERTEX_ARRAY);
    	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    	glEnableClientState(GL_COLOR_ARRAY);
    }
    
    void vtx_end(const vtx3f* vtx)
    {
    	glDisableClientState(GL_VERTEX_ARRAY);
    	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    	glDisableClientState(GL_COLOR_ARRAY);
    }
    
    int draw_arrays(int shape, const vtx3f* vtx, size_t pos, size_t size)
    {
    	vtx_begin(vtx);
    	glDrawArrays(shape, pos, size);
    	vtx_end(vtx);
    	return 0;
    }
    
    //绘制图片
    int draw_image(intptr_t image, vec4ub color, float x, float y, float width, float height,
    		float u1 = 0.0f, float v1 = 0.0f, float u2 = 1.0f, float v2 = 1.0f)
    {
    	vtx3f vtx[] = {
    		vtx3f(x,         y,          0.0f, u1, v1, color),
    		vtx3f(x + width, y,          0.0f, u2, v1, color),
    		vtx3f(x + width, y + height, 0.0f, u2, v2, color),
    		vtx3f(x        , y + height, 0.0f, u1, v2, color)
    	};
    	glBindTexture(GL_TEXTURE_2D, image);
    	return draw_arrays(GL_TRIANGLE_FAN, vtx, 0, 4);
    }
    
    int draw_image(const teximage& image, vec4ub color, float x, float y, float width, float height)
    {
    	return draw_image(image.image, color, x, y, width, height, image.u1, image.v1, image.u2, image.v2);
    }
    
    //---------------------------------------------------------------------------
    //GDI字体封装类
    //有需要的,可以把这个类替换成freetype等其他字体库
    //实现方法不变,直接替换掉这个类就好
    //比如我用freetype2实现一个ftFont的类
    //或者用stb_font(一个轻量级freetype库)实现一个stbFont类
    
    class gdifont
    {
    private:
    	HDC m_dc;			//内存DC
    	HFONT m_font;		//字体句柄
    	GLYPHMETRICS m_gm;	//字符模型信息
    	MAT2 m_mat;			//转置矩阵,默认初始矩阵
    
    	std::wstring m_ttfile;//用于保存单独字体文件的路径
    	std::vector<BYTE> m_pixelbuf;//用于保存字符像素信息
    	//std::vector<BYTE> m_fontResource;//内存字体
    
    public:
    	gdifont() : m_dc(NULL), m_font(NULL), m_ttfile(), m_pixelbuf()
    	{
    		//初始化字体转置矩阵,默认初始矩阵
    		//这个矩阵可以实现字体的旋转、偏移、缩放等效果
    		//2x2矩阵
    		//1 0
    		//0 1
    		m_mat.eM11.value = 1;m_mat.eM11.fract = 0;
    		m_mat.eM12.value = 0;m_mat.eM12.fract = 0;
    		m_mat.eM21.value = 0;m_mat.eM21.fract = 0;
    		m_mat.eM22.value = 1;m_mat.eM22.fract = 0;
    	}
    
    	//字体句柄
    	HFONT handle()const
    	{
    		return m_font;
        }
    
    	//创建字体
    	int create(const wchar_t* fontname, int size, int charset = GB2312_CHARSET)
    	{
    		//如果需要,首先释放资源
            if(this->handle()){
    			this->dispose();
    		}
    
    		//创建内存DC
    		m_dc = CreateCompatibleDC(0);
    
    		//创建字体
    		m_font = CreateFontW(
                size, // logical height of font height
                0, // logical average character width
                0, // angle of escapement
                0, // base-line orientation angle
                0, // font weight
                0, // italic attribute flag
                0, // underline attribute flag
                0, // strikeout attribute flag
                charset, // character set identifier
                0, // output precision
                0, // clipping precision
                DEFAULT_QUALITY, // output quality
                DEFAULT_PITCH | FF_SWISS, // pitch and family
                fontname // pointer to typeface name string
    		);
    
    		//绑定字体到内存DC
    		SelectObject(m_dc, m_font);
    
    		return 0;
    	}
    
    	//加载单独的字体文件
    	/*例如:
    	font.load(
    		"myfont.ttf",	//字体文件,windows系统支持的字体,目录可以是绝对路径,也可以是相对路径
    		"字体名称",		//点开字体文件,上面显示的字体名称,比如“微软雅黑”
    		16,				//字体大小
            GB2312_CHARSET);//如果是中文字体,要设置中文字符集
    	*/
    
    	int load(const wchar_t* filename, const wchar_t* fontname, int size, int charset = 0)
    	{
    		if(this->handle()){
    			this->dispose();
    		}
    
            m_ttfile = filename;
            AddFontResourceExW(m_ttfile.c_str(), FR_PRIVATE, 0);
    		this->create(fontname, size, charset);
    
    		return 0;
    	}
    
    	//加载内存、程序资源内的字体,这个暂时懒得实现了,有需要的可以查一下WINAPI实现
    	/*
    	void load_memory(...)
        {
            FILE* f = fopen(filename, "rb");
            fseek(f, 0, SEEK_END);
            m_fontResource.resize(ftell(f));
            fseek(f, 0, SEEK_SET);
            fread(&m_fontResource[0], 1, m_fontResource.size(), f);
            fclose(f);
    
            DWORD dwFonts = 0;
    		m_fontH = (HFONT)AddFontMemResourceEx(&m_fontResource[0], m_fontResource.size(), 0, &dwFonts);
        }
        */
    
    	//释放资源
    	void dispose()
    	{
    		if(m_dc){
    			DeleteDC(m_dc);
    			m_dc = null;
    		}
    
            if(m_font){
    	    	DeleteObject(m_font);
        		m_font = null;
       		}
    
            if(!m_ttfile.empty()){
                RemoveFontResourceExW(m_ttfile.c_str(), FR_PRIVATE, 0);
                m_ttfile.clear();
            }
    
            //RemoveFontMemResourceEx(m_font);
    	}
    
    	//获取一个字体的位图和字符信息
    	int render_char(wchar_t ch, char_info& info)
    	{
    		//获取字符位图空间大小
    		int size = GetGlyphOutlineW(m_dc, ch, GGO_GRAY8_BITMAP, &m_gm, 0, NULL, &m_mat);
    		//重新设置位图缓冲区大小
    		m_pixelbuf.resize(size);
    		//获得字符位图像素信息
    		GetGlyphOutlineW(m_dc, ch, GGO_GRAY8_BITMAP, &m_gm, 64*64, &m_pixelbuf[0], &m_mat);
    		//GetGlyphOutline获得的位图像素是64阶灰度,要转换成256阶灰度
    		//当然如果你要通过shader渲染,并希望获得一些其他效果,可以不转换,或进行其他转换
    		gray256();
            //填写一下字符信息
    		info.x = m_gm.gmptGlyphOrigin.x;
    		info.y = m_gm.gmptGlyphOrigin.y;
    		info.next_x = m_gm.gmCellIncX;
    		info.next_y = m_gm.gmBlackBoxY;
    		return 0;
    	}
    
    	//位图宽度
    	int width()const
    	{
    		return m_gm.gmBlackBoxX;
    	}
    
    	//位图高度
    	int height()const
    	{
    		return m_gm.gmBlackBoxY;
    	}
    
    	//位图像素数据
    	void* data()
    	{
    		return &m_pixelbuf[0];
        }
    
    	//64阶灰度转256阶灰度
    	void gray256()
    	{
    		BYTE* p = &m_pixelbuf[0];
    		int c;
    		//数据行是四字节对齐的
    		DWORD linewidth = (m_gm.gmBlackBoxX + 3) & 0xFFFFFFFC;
    		for(size_t y=0; y<m_gm.gmBlackBoxY; ++y){
    			for(size_t x = 0; x < m_gm.gmBlackBoxX; ++x){
    				c = p[x];
    				c *= 4;//64x4 = 256
    				if(c > 255)c = 255;//约束在0~255范围之内
    				p[x] = c;
    			}
    			p += linewidth;//移动到下一行
    		}
    	}
    
    	//测试获取的位图,画到一个HDC上面
    	#ifdef _DEBUG
    	void paint(HDC dc)
    	{
    		BYTE* p = &m_pixelbuf[0];
    		int c;
    		//数据行是四字节对齐的
    		DWORD linewidth = (m_gm.gmBlackBoxX + 3) & 0xFFFFFFFC;
    		for(size_t y=0; y<m_gm.gmBlackBoxY; ++y){
    			for(size_t x = 0; x < m_gm.gmBlackBoxX; ++x){
    				c = p[x];
    				SetPixelV(dc, x, y, RGB(c, c, c));
    			}
    			p += linewidth;
    		}
    	}
    	#endif
    };
    
    //---------------------------------------------------------------------------
    //imagelist 图集类,自动把小图拼成图集
    //
    //这个简单的图集类,用于拼合高度大小变化不大的图片,比如图标
    //
    //有需要的,可以github搜索maxrects库,可以把不同大小的字体拼成一个大图
    //一般使用固定大小的字体,因为字符位图大小相对变化不大,空间浪费也不算太大
    //使用一个高度(字体高度)作为每一行高度,每添加进一个小图,x方向向右偏移一个位置
    //到达右边边界,换行。
    //如果到达纹理右下角,则自动添加一个纹理页
    
    template<typename T, typename U = int>
    class imagelist
    {
    public:
    	struct ITEM
    	{
    		teximage image;
    		U data;
    	};
    
    	typedef const ITEM* item_type;
    	typedef typename std::map<T, ITEM> map_type;
    	typedef typename map_type::iterator iterator;
    	typedef typename map_type::const_iterator const_iterator;
    
    private:
    	std::vector<GLuint> m_texlist;	//保存的纹理页
    	map_type m_itemlist;				//小图信息列表,使用std::map组织,也可以根据需要用数组组织
    	GLenum m_format;//纹理格式
    	int m_width;	//纹理大小
    	int m_height;
    	int m_filter;	//纹理过滤方式
    	int m_size;		//小图块大小,只记录高度
    	int m_u, m_v;	//当前小图块添加位置
    
    public:
    	imagelist():m_texlist(), m_itemlist(), m_format(GL_RGBA), m_filter(GL_LINEAR),
    		m_width(512), m_height(512), m_size(16), m_u(0), m_v(0)
    	{
    	}
    
    	~imagelist()
    	{
    		this->dispose();
    	}
    
    	//初始化创建图集
    	int create(size_t width, size_t height, size_t size, GLenum format = GL_RGBA, GLenum filter = GL_LINEAR)
    	{
    		this->dispose();
    		m_width  = width;
    		m_height = height;
    		m_format = format,
    		m_size   = size;
    		m_filter = filter;
    		m_u = m_v = 0;
    		return 0;
    	}
    
    	//释放资源
    	void dispose()
    	{
    		m_itemlist.clear();
    		if(!m_texlist.empty()){
    			//删除所有纹理页
    			glDeleteTextures(m_texlist.size(), &m_texlist[0]);
    			m_texlist.clear();
    		}
    		m_u = m_v = 0;
    	}
    
    	//当前缓存的小图块数量
    	size_t size()const
    	{
    		return m_imglist.size();
    	}
    
    	//添加一个小图块
    	int insert(const T& index, int width, int height, GLenum format, void* data, const U& userdata)
    	{
    		//首先移动坐标位置
    		position_move(width);
    		//绑定当前纹理,也就是图集的最后一个
    		glBindTexture(GL_TEXTURE_2D, m_texlist.back());
    		//更新纹理局部像素
    		glTexSubImage2D(GL_TEXTURE_2D, 0, m_u, m_v, width, std::min(m_size, height), format, GL_UNSIGNED_BYTE, data);
    		//保存信息
    		ITEM item;
    		item.image.image = m_texlist.back();
    		item.image.x = m_u;
    		item.image.y = m_v;
    		item.image.width = width;
    		item.image.height = std::min(height, m_size);
    		item.image.u1 = float(m_u) / m_width;
    		item.image.v1 = float(m_v) / m_height;
    		item.image.u2 = float(m_u+width)/m_width;
    		item.image.v2 = float(m_v+std::min(m_size, height))/m_height;
    		item.data = userdata;
    		m_itemlist[index] = item;
    		//x方向移动坐标
    		m_u += width + 1;//做一个像素的间距
    		return index;
    	}
    
    	//查询图块信息
    	item_type items(const T& index)const
    	{
    		const_iterator itr = m_itemlist.find(index);
    		if(itr != m_itemlist.end()){
    			return &itr->second;
    		}
    		else{
    			return null;
    		}
    	}
    
    	//查询图块是否存在
    	bool exist(const T& index)const
    	{
    		return items(index);
    	}
    
    private:
    	void position_move(int width)
    	{
    		GLuint tex = 0;
    		width += 1;//做一个像素的间距
    		if(m_u + width > m_width){//换行
    			m_u = 0;
    			m_v += m_size + 1;
    		}
    
    		//创建新纹理页
    		if(m_texlist.empty() || m_v + m_size > m_height){
    			glGenTextures(1, &tex);
    			glBindTexture(GL_TEXTURE_2D, tex);
    			glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);
    
    			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_filter);
    			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_filter);
    
    			m_texlist.push_back(tex);
    			m_u = 0;
    			m_v = 0;
    		}
    	}
    
    	teximage* BindTexture(int index)
    	{
    		iterator itr = m_imglist.find(index);
    		if(itr!=m_imglist.end())
    		{
    			glBindTexture(GL_TEXTURE_2D, itr->second.image.image);
    			return &itr->second.image;
    		}
    		return NULL;
    	}
    };
    
    //---------------------------------------------------------------------------
    //glfont 字体类
    //
    //gles对GL_ALPHA8支持貌似不好,可以替换成GL_RGBA(需要将256灰度转换成RGBA格式)
    //或者使用GL_RED等单通道格式,通过shader渲染字体
    //
    
    //draw_text字符串绘制参数
    #define PT_LEFT      0x00000000
    #define PT_RIGHT     0x00000001
    #define PT_CENTER    0x00000002
    #define PT_SHADOW    0x00010000
    #define PT_CALCRECT  0x80000000
    
    class glfont
    {
    public:
    	typedef imagelist<wchar_t, char_info> imagelist_type;
    
    	typedef TYPENAME imagelist_type::item_type char_item;
    
    	//const static int SHADOW_SIZE = 2;	//阴影大小,带阴影的字体,这个实现代码太长
    	enum{
    		TEXTURE_SIZE = 1024,	//默认纹理大小
    
    		TEX_FORMAT = GL_ALPHA8,	//PC默认使用GL_ALPHA8纹理格式
    		SRC_FORMAT = GL_ALPHA,	//位图数据默认格式
    
    		TAB_WIDTH = 4			//制表符宽度
    	};
    
    	struct PT_WORD
    	{
    		const wchar_t* begin;
    		const wchar_t* end;
    		size_t width;
    	};
    
    private:
    	gdifont m_font;		//字体类,可以替换成其他字体类
    	std::wstring m_name;//字体名字
    	int m_size;			//字体大小
    	imagelist_type m_imagelist;//图集类
    
    public:
    	vec4ub color;	//字体颜色
    
    public:
    	glfont() : m_font(), m_name(), m_size(), m_imagelist(), color(255, 255, 255, 255)
    	{
    
    	}
    
    	void init(const wchar_t* fontname, int size = CGL_DEFAULT_FONT_SIZE, int texture_size = TEXTURE_SIZE)
    	{
    		m_name = fontname;
    		m_size = size;
    		//m_imagelist = imagelist;
    		m_font.create(fontname, size);
    		m_imagelist.create(texture_size, texture_size, size, TEX_FORMAT, GL_NEAREST);
    	}
    
    	void clear()
    	{
    		m_imagelist.dispose();
    	}
    
    	void dispose()
    	{
    		m_imagelist.dispose();
    		m_size = 0;
    	}
    
    	//获得字符item
    	char_item char_items(wchar_t ch)
    	{
    		if(!m_imagelist.exist(ch)){
    			make_char(ch);
    		}
    		return m_imagelist.items(ch);
    	}
    
    	//获得字符宽度
    	int char_width(wchar_t ch)
    	{
            char_item item;
    		if(!m_imagelist.exist(ch)){
    			make_char(ch);
    		}
    		item = m_imagelist.items(ch);
    		return item ? item->data.next_x : 0;
        }
    
    	//获取字符高度
    	int char_height() { return m_size; }
    
    	//获取字符串宽度
    	int text_width(const wchar_t* text, size_t length)
    	{
            int width = 0;
    		for(size_t i=0; i<length; ++i){
    			width += char_width(text[i]);
    		}
    		return width;
        }
    
    	//输出一个字符
    	int put_char(int x, int y, wchar_t ch, int flag = 0)
    	{
    		char_item item = m_imagelist.items(ch);
    		if(!item){
    			make_char(ch);
    			item = m_imagelist.items(ch);
    		}
    		draw_image(item->image,
    			color,
    			x + item->data.x,
    			y + m_size - item->data.y,
    			item->image.width,
    			item->image.height);
    
    		return item->data.next_x;
    	}
    
    	//绘制一行字体,不支持制表符
    	int print(int x, int y, const wchar_t* text, size_t length)
    	{
    		if(length == TEXT_MAX)length = wcslen(text);
    		for(size_t i=0; i<length; ++i){
    			x += put_char(x, y, text[i]);
    		}
    		return 0;
    	}
    
    	//绘制一行字体,支持制表符
    	int tab_print(int x, int y, const wchar_t* text, size_t length)
    	{
    		int tab = TAB_WIDTH * (this->char_height() >> 1);
    		if(length == TEXT_MAX)length = wcslen(text);
    		for(size_t i=0; i<length; ++i)
    		{
    			if(text[i] == '\t'){
    				x = align_next(x, tab);
    			}
    			else{
    				x += put_char(x, y, text[i]);
    			}
    		}
    		return 0;
    	}
    
    	//仿GDI函数DrawText
    	int draw_text(
    		int left, int top, int width, int height,
    		const wchar_t* text,
    		size_t length,
    		int style);
    
    private:
    	int make_char(wchar_t ch);
    
    	//根据当前位置n,计算下一个tab的对齐位置 next_tab_position
    	int align_next(int n, int align)
    	{
    		n = n - n % align + align;
    		return n;
    	}
    
    	int get_tabled_line(const wchar_t* &l_end, const wchar_t* end, int width);
    };
    
    //缓存一个字符
    int glfont::make_char(wchar_t ch)
    {
    	char_info info;
    
    	//数据行4字节对齐
    	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    
    	//渲染字符
    	m_font.render_char(ch, info);
    
    	//添加到图集
    	return m_imagelist.insert(ch, m_font.width(), m_font.height(), GL_ALPHA, m_font.data(), info);
    }
    
    //返回下一个字符的绘制位置-1表示换行
    int glfont::get_tabled_line(const wchar_t* &l_end, const wchar_t* end, int width)
    {
    	int tab = TAB_WIDTH * (this->char_height() >> 1);
    	int n;// = 0;
    	int l_width = 0;
    
    	for(; l_end < end; ++l_end){
    		if(*l_end == '\r'){
    			continue;
    		}
    		else if(*l_end == '\n'){//next line
    			break;
    		}
    		//else if(*l_end == ' ')//add word
    		else if(*l_end == '\t'){
    			n = align_next(l_width, tab);
    			if(n < width){
    				l_width = n;
    			}
    			else{
    				//break;
    				return l_width;
    			}
    		}
    		else{
    			n = this->char_width(*l_end);
    			if(l_width + n < width){
    				l_width += n;
    			}
    			else{//next line
    				//break;
    				return l_width;
    			}
    		}
    	}
    	return l_width;
    }
    
    int glfont::draw_text(int left, int top, int width, int height, const wchar_t* text, size_t length, int style)
    {
    	int px = 0, py = top;	//字符绘制位置
    	//int chwidth = 0;		//字符宽度
    	int ch_size = this->char_height();
    	if(length == TEXT_MAX)length = wcslen(text);
    	int tab = TAB_WIDTH * (ch_size >> 1);
    
    	//vec4ub c = dc->color;
    
    	const wchar_t* end = text + length;
    	const wchar_t* l_begin;
    	const wchar_t* l_end = text;
    	int l_width = 0;
    	std::vector<PT_WORD> words;
    
    	int x = 0;
    
    	while(l_end < end)
    	{
    		//l_width = 0;
    		l_begin = l_end;
    		//word_begin = l_end;
    		//get line
    		l_width = get_tabled_line(l_end, end, width);
    
    
    		px = left;
    		if(style & PT_RIGHT){
    			px += width - l_width;
    		}
    		else if(style & PT_CENTER){
    			px += (width - l_width) / 2;
    		}
    		if(l_begin != l_end && !(style & PT_CALCRECT)){
    			if(style & PT_SHADOW){
    				//dc->color = shadow_color;
    				//draw_shadow(dc, px, py, text+begin, end-begin);
    			}
    			//dc->color = c;
    
    			x = 0;
    			for(; l_begin < l_end; ++l_begin)
    			{
    				if(*l_begin == '\t'){
    					x = align_next(x, tab);
    					continue;
    				}
    				else if(*l_begin == '\r' || *l_begin == '\n'){
    					continue;
    				}
    				x += put_char(px + x, py, *l_begin);
    			}
    		}
    
    		if(*l_end == '\n'){//next line
    			++l_end;
    		}
    
    		py += ch_size + (ch_size / 8);// 1/8 line space
    		if(int(top + height) < py + ch_size){
    			break;
    		}
    	}
    
    	return py - top;
    }
    
    
    }//end namespace cgl
    
    #endif //GLFONT_HPP_20190815000333

     

    展开全文
  • opengl字体

    千次阅读 2006-04-20 20:47:00
    英文字体显示:void GLfont::BuildFontGL(GLvoid) // 建立位图字体(Bitmap Fonts){ HFONT newFont; // 用以保存新的字体对象 HFONT oldFont; // 用以保存原字体对象 base = glGenLists(256); // 存储2

    英文字体显示:

    void GLfont::BuildFontGL(GLvoid)            // 建立位图字体(Bitmap Fonts)
    {
     HFONT newFont;             // 用以保存新的字体对象
     HFONT oldFont;             // 用以保存原字体对象
     base = glGenLists(256);            // 存储256个字符
     
     newFont =::CreateFont(-18,          // 字体的高度
      0,           // 字体的宽度
      0,           // 旋转的角度
      0,           // 定位角度
      FW_THIN,         // 字体的粗细
      FALSE,          // 斜体?
      FALSE,          // 下划线?
      FALSE,          // 删除线?
      ANSI_CHARSET,        // 字符集
      OUT_TT_PRECIS,        // 输出精度
      CLIP_DEFAULT_PRECIS,      // 裁减精度
      ANTIALIASED_QUALITY,      // 输出质量
      FF_DONTCARE|DEFAULT_PITCH,     // 间距和字体族
      "Tahoma");         // 字体名称
     
     oldFont = (HFONT)SelectObject(::GetDC(NULL), newFont);    // 选进设备描述表
     wglUseFontBitmaps(::GetDC(NULL), 0, 256, base);     // 建立256个字符
     SelectObject(::GetDC(NULL), oldFont);        // 恢复设备描述表
     DeleteObject(newFont);            // 删除新字体
    }

    GLvoid GLfont::KillFontGL(GLvoid)            // 删除保存字体的显示表
    {
     glDeleteLists(base, 256);           // 删除256个字符
    }

    GLvoid GLfont::glPrint(const char *fmt, ...)         // 建立Print函数
    {
     char  text[256];            // 用以保存格式化后的字符串
     va_list  ap;              // 指向参数列表的指针
     
     if (fmt == NULL)             // 没有可输出的字符?
      return;               // 返回
     va_start(ap, fmt);             // 遍历字符串,查找变量
     vsprintf(text, fmt, ap);          // 将变量转换为显示的数字
     va_end(ap);               // 结果保存在text内
     glPushAttrib(GL_LIST_BIT);           // 显示表状态入栈
     glListBase(base);             // 显示表偏移量
     glCallLists((int)strlen(text), GL_UNSIGNED_BYTE, text);    // 绘制字符串
     glPopAttrib();              // 显示表状态出栈
    }

    使用:

     GLfont font;
     font.BuildFontGL();
     glRasterPos2f(1.0,0.0); 
     glColor3f(1,0,0);
     font.glPrint("懒猪");

    中文字体显示:

    void GLfont::CreateFont(char *facename, int height, int weight, bool italic,bool underline,bool strikeout)
    {
     LOGFONT lf;
     
     lf.lfHeight = height;
     lf.lfWidth = 0;      
     lf.lfEscapement = 0; 
     lf.lfOrientation = 0;
     lf.lfWeight = weight;
     lf.lfItalic = italic;
     lf.lfUnderline = underline;
     lf.lfStrikeOut = strikeout;
     lf.lfCharSet = DEFAULT_CHARSET;
     lf.lfOutPrecision = OUT_TT_PRECIS;
     lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
     lf.lfQuality = PROOF_QUALITY;
     lf.lfPitchAndFamily = VARIABLE_PITCH | TMPF_TRUETYPE | FF_MODERN;
     strcpy(lf.lfFaceName,facename);
     
     // 创建字体
     m_hFont = CreateFontIndirect(&lf);
     
    }
    void GLfont::ShowText(int x, int y, LPCTSTR lpszText)
    {
     // 保存原投影矩阵,将投影矩阵设为平行投影
     glMatrixMode( GL_PROJECTION );
     glPushMatrix();
     glLoadIdentity();
     glOrtho( 0, 640, 0, 480, -1, 1 );
     
     // 保存原模型变换矩阵,平移至( x, y )
     glMatrixMode( GL_MODELVIEW );
     glPushMatrix();
     glLoadIdentity();
     RECT rect;
     GetClientRect(GetActiveWindow(),&rect);
     glTranslatef(x, float(rect.bottom-rect.top-35-y), 0 );
     
     
     HBITMAP hbitmap;
     BITMAP bm;
     SIZE size;
     UCHAR* pBmpBits;
     HFONT hOldFont;
     HDC hdc = wglGetCurrentDC();
     
     
     hOldFont = (HFONT)SelectObject(hdc, m_hFont);
     ::GetTextExtentPoint32(hdc, lpszText, strlen(lpszText), &size);
     hbitmap = CreateBitmap(size.cx, size.cy,1, 1, NULL);
     
     HDC hMemDC = ::CreateCompatibleDC(hdc);
     if(hMemDC)
     {
      HBITMAP hPrevBmp = (HBITMAP)SelectObject(hMemDC,hbitmap);
      HFONT hPrevFont = (HFONT)SelectObject(hMemDC, m_hFont);
      
      SetBkColor(hMemDC, RGB(0, 0, 0));
      SetTextColor(hMemDC, RGB(255, 0, 0));
      SetBkMode(hMemDC, OPAQUE);
      TextOut(hMemDC, 0, 0, lpszText, strlen(lpszText));
      
      // copy GDI bitmap to DIB
      SelectObject(hdc,hbitmap);
      GetObject(hbitmap, sizeof(bm), &bm);
      size.cx = (bm.bmWidth + 31) & (~31);
      size.cy = bm.bmHeight;
      int bufsize = size.cy * (((bm.bmWidth + 31) & (~31)) /8);
      pBmpBits = new UCHAR[bufsize];
      memset(pBmpBits, 0, sizeof(UCHAR)*bufsize);
      
      struct {
       BITMAPINFOHEADER bih;
       RGBQUAD col[2];
      }bic;
      BITMAPINFO *binf = (BITMAPINFO *)&bic;
      
      binf->bmiHeader.biSize = sizeof(binf->bmiHeader);
      binf->bmiHeader.biWidth = bm.bmWidth;
      binf->bmiHeader.biHeight = bm.bmHeight;
      binf->bmiHeader.biPlanes = 1;
      binf->bmiHeader.biBitCount = 1;
      binf->bmiHeader.biCompression = BI_RGB;
      binf->bmiHeader.biSizeImage = bufsize;
      binf->bmiHeader.biXPelsPerMeter = 1;
      binf->bmiHeader.biYPelsPerMeter = 1;
      binf->bmiHeader.biClrUsed = 0;
      binf->bmiHeader.biClrImportant = 0;
      
      ::GetDIBits(hdc, hbitmap, 0, bm.bmHeight, pBmpBits, binf,DIB_RGB_COLORS);
      
      SelectObject(hMemDC, hPrevBmp);
     }
     ::DeleteDC(hMemDC);
     
     // delete font from DC
     SelectObject(hdc, hOldFont);
     // display text
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
     glRasterPos2i(1,20);
     glBitmap(size.cx, size.cy, 0.0, 2.0, size.cx+2.0f, 0.0, pBmpBits);
     delete pBmpBits;
     // 恢复投影矩阵和模型变换矩阵
     glMatrixMode( GL_PROJECTION );
     glPopMatrix();
     glMatrixMode( GL_MODELVIEW );
     glPopMatrix();

    初学,网上书上看的,留下来供大家参考。

    展开全文
  • OpenGL学习笔记--字体库freetype2、FTGL

    千次阅读 2017-07-05 16:47:56
    freetype2FreeType是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,包括TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF等。FTGLFTGL即FreeType ...

    freetype2

    FreeType库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,包括TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF等。

    FTGL

    FTGL即FreeType Graphics Library,它相当于在freetype的基础上又封装了一道接口,更加方便使用。

    下载编译

    分别到各自官网上下载即可,如果是ubuntu下可直接使用apt-cache search搜索相关的安装包,进行安装,windows下下载源代码后使用VC打开对应工程编译即可,没有提供VC工程的,一般也会提供cmake文件去生成。
    注意的是因为FTGL是依赖于freetype的,所以需要先编译好freetype2,并在VC目录中添加头文件和库文件路径

    FTGL使用基本流程图

    Created with Raphaël 2.1.0 开始 构造字体对象 FTGLPixmapFont* pFont = new FTGLPixmapFont 设置字高 pFont- >FaceSize 设置字符集 pFont- >CharMap 绘画字符串 pFont- >Render 析构字体对象 delete pFont 结束

    代码示例

    #include <gl/glut.h>
    
    #include <freetype2/ft2build.h>
    #include <freetype2/freetype/freetype.h>
    #include <FTGL/ftgl.h>
    #include <locale.h>
    
    #ifdef WIN32
    #pragma comment(lib, "glew32.lib")
    #pragma comment(lib, "freeglut.lib")
    #pragma comment(lib, "freetype2410.lib")
    #pragma comment(lib, "ftgl_static.lib")
    #endif
    
    struct DrawInfo{
        int left;
        int right;
        int top;
        int bottom;
        GLuint color;
    };
    
    #define R(color) (((color) >> 24) & 0xFF)
    #define G(color) (((color) >> 16) & 0xFF)
    #define B(color) (((color) >>  8) & 0xFF)
    
    FTGLPixmapFont* pFont = NULL;
    void initFont(const char* fname, unsigned int h){
        if (!pFont){
            pFont = new FTGLPixmapFont(fname);
            pFont->FaceSize(h);
            pFont->CharMap(FT_ENCODING_UNICODE);
        }
    }
    
    void releaseFont(){
        if (pFont){
            delete pFont;
            pFont = NULL;
        }
    }
    
    void drawStr(const char* str, DrawInfo* di){
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0.0, glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT), 0.0, -1.0, 1.0);
    
        const char* mbs = str;
        int len_mbs = strlen(mbs);
        // linux下使用locale -a可以查看支持的本地化字符集,windows下使用chcp命令查看活动代码页
    #ifdef WIN32
        setlocale(LC_ALL,".936");
    #else 
        setlocale(LC_ALL,"ch_ZN.utf8");
    #endif
        int len_wcs = mbstowcs(NULL, mbs, 0);
        wchar_t* wcs = new wchar_t[len_wcs + 1];
        mbstowcs(wcs, mbs, strlen(mbs)+1);
    
        //windows也可使用MultiByteToWideChar这个API来进行多字节与宽字节的转化
    
        int r = R(di->color);
        int g = G(di->color);
        int b = B(di->color);
        glColor3ub(R(di->color), G(di->color), B(di->color));
        glRasterPos2i(di->left, di->bottom);
        pFont->Render(wcs);
        glColor3ub(255,255,255);
    
        delete[] wcs;
    }
    
    void reshape(int w, int h){
        glViewport(0, 0, w, h);
    
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0.0, w, h, 0.0, -1.0, 1.0);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }
    
    void display(){
        glClearColor(0.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
    
        DrawInfo di;
        di.left = 200;
        di.bottom = 200;
        di.color = 0xFFFF00FF;
        drawStr("FTGL使用范例", &di);
    
        glutSwapBuffers();
    }
    
    int main(int argc, char* argv[]){
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
        glutInitWindowPosition(0, 0);
        glutInitWindowSize(640, 480);
    
        int mainwnd = glutCreateWindow("glut window");
    
        glutReshapeFunc(reshape);
        glutDisplayFunc(display);
    
        // ttf文件可以到网上下载,windows下也可在C盘直接搜索*.ttf
        initFont("D:/simfang.ttf", 36);
    
        glutMainLoop();
    
        releaseFont();
    
        return 0;
    }

    效果图:
    ftgl

    展开全文
  • 飞利浦 字体库 - .NET 的 Freetype 字体渲染(OpenTK、OpenGL 或任何其他渲染引擎)
  • OpenGL开发的组成 开发基于OpenGL的应用程序,必须先了解OpenGL的库函数。它采用C语言风格,提供大量的函数来进行图形的处理和显示。OpenGL库函数的命名方式非常有规律。所有OpenGL函数采用了以下格式 前缀...

    OpenGL开发库的组成

    开发基于OpenGL的应用程序,必须先了解OpenGL的库函数。它采用C语言风格,提供大量的函数来进行图形的处理和显示。OpenGL库函数的命名方式非常有规律。所有OpenGL函数采用了以下格式
    <库前缀><根命令><可选的参数个数><可选的参数类型>
    库前缀有gl、glu、aux、glut、wgl、glx、agl等等,分别表示该函数属于OpenGL那个开发库等,从函数名后面中还可以看出需要多少个参数以及参数的类型。I代表int型,f代表float型,d代表double型,u代表无符号整型。例如glVertex3fv()表示了该函数属于gl库,参数是三个float型参数指针。我们用glVertex*()来表示这一类函数。



    OpenGL函数库相关的API有核心库(gl)、实用库(glu)、辅助库(aux)、实用工具库(glut)、窗口库(glx、agl、wgl)和扩展函数库等。从图1可以看出,gl是核心,glu是对gl的部分封装。glx、agl、wgl 是针对不同窗口系统的函数。glut是为跨平台的OpenGL程序的工具包,比aux功能强大。扩展函数库是硬件厂商为实现硬件更新利用OpenGL的扩展机制开发的函数。下面逐一对这些库进行详细介绍。
    1.  OpenGL核心库
    核心库包含有115个函数,函数名的前缀为gl。
    这部分函数用于常规的、核心的图形处理。此函数由gl.dll来负责解释执行。由于许多函数可以接收不同数以下几类。据类型的参数,因此派生出来的函数原形多达300多个。核心库中的函数主要可以分为以下几类函数。
    绘制基本几何图元的函数。如绘制图元的函数glBegain()、glEnd()、glNormal*()、glVertex*()。
    矩阵操作、几何变换和投影变换的函数。如矩阵入栈函数glPushMatrix()、矩阵出栈 函数glPopMatrix()、装载矩阵函数glLoadMatrix()、矩阵相乘函数glMultMatrix(),当前矩阵函数glMatrixMode()和矩阵标准化函数glLoadIdentity(),几何变换函数glTranslate*()、glRotate*()和glScale*(),投影变换函数glOrtho()、glFrustum()和视口变换函数glViewport()等等。
    颜色、光照和材质的函数。如设置颜色模式函数glColor*()、glIndex*(),设置光照效果的函数glLight*() 、glLightModel*()和设置材质效果函数glMaterial()等等。
    显示列表函数、主要有创建、结束、生成、删除和调用显示列表的函数glNewList()、 glEndList()、glGenLists()、glCallList()和glDeleteLists()。
    纹理映射函数,主要有一维纹理函数glTexImage1D()、二维纹理函数glTexImage2D()、 设置纹理参数、纹理环境和纹理坐标的函数glTexParameter*()、glTexEnv*()和glTetCoord*()等。
    特殊效果函数。融合函数glBlendFunc()、反走样函数glHint()和雾化效果glFog*()。
    光栅化、象素操作函数。如象素位置glRasterPos*()、线型宽度glLineWidth()、多边形绘制模式glPolygonMode(),读取象素glReadPixel()、复制象素glCopyPixel()等。
    选择与反馈函数。主要有渲染模式glRenderMode()、选择缓冲区glSelectBuffer()和反馈缓冲区glFeedbackBuffer()等。
    曲线与曲面的绘制函数。生成曲线或曲面的函数glMap*()、glMapGrid*(),求值器的函数glEvalCoord*() glEvalMesh*()。
    状态设置与查询函数。主要有glGet*()、glEnable()、glGetError()等。
    2.  OpenGL实用库The OpenGL Utility Library (GLU)
    包含有43个函数,函数名的前缀为glu。
    OpenGL提供了强大的但是为数不多的绘图命令,所有较复杂的绘图都必须从点。线、面开始。Glu 为了减轻繁重的编程工作,封装了OpenGL函数,Glu函数通过调用核心库的函数,为开发者提供相对简单的用法,实现一些较为复杂的操作。此函数由glu.dll来负责解释执行。OpenGL中的核心库和实用库可以在所有的OpenGL平台上运行。主要包括了以下几种。
    辅助纹理贴图函数,有gluScaleImage() 、gluBuild1Dmipmaps()、gluBuild2Dmipmaps()。
    坐标转换和投影变换函数,定义投影方式函数gluPerspective()、gluOrtho2D() 、gluLookAt(),拾取投影视景体函数gluPickMatrix(),投影矩阵计算gluProject()和 gluUnProject()等等。
    多边形镶嵌工具,有gluNewTess()、 gluDeleteTess()、gluTessCallback()、gluBeginPolygon() gluTessVertex()、gluNextContour()、gluEndPolygon()等等。
    二次曲面绘制工具,主要有绘制球面、锥面、柱面、圆环面gluNewQuadric()、gluSphere()、gluCylinder()、gluDisk()、gluPartialDisk()、gluDeleteQuadric()等等。
    非均匀有理B样条绘制工具,主要用来定义和绘制Nurbs曲线和曲面,包括gluNewNurbsRenderer()、gluNurbsCurve()、gluBeginSurface()、gluEndSurface()、gluBeginCurve()、gluNurbsProperty()等函数。
    错误反馈工具,获取出错信息的字符串gluErrorString().
    3.  OpenGL辅助库
    包含有31个函数,函数名前缀为aux。
    这部分函数提供窗口管理、输入输出处理以及绘制一些简单三维物体。此函数由glaux.dll来负责解释执行。创建aux库是为了学习和编写OpenGL程序,它更像是一个用于测试创意的预备基础接管。Aux库在windows实现有很多错误,因此很容易导致频繁的崩溃。在跨平台的编程实例和演示中,aux很大程度上已经被glut库取代。OpenGL中的辅助库不能在所有的OpenGL平台上运行。
    辅助库函数主要包括以下几类。
    窗口初始化和退出函数,auxInitDisplayMode()和auxInitPosition()。
    窗口处理和时间输入函数,auxReshapeFunc()、auxKeyFunc()和auxMouseFunc()。
    颜色索引装入函数,auxSetOneColor()。
    三维物体绘制函数。包括了两种形式网状体和实心体,如绘制立方体auxWireCube()和 auxSolidCube()。这里以网状体为例,长方体auxWireBox()、环形圆纹面auxWireTorus()、圆柱auxWireCylinder()、二十面体auxWireIcosahedron()、八面体auxWireOctahedron()、四面体auxWireTetrahedron()、十二面体auxWireDodecahedron()、圆锥体auxWireCone()和茶壶auxWireTeapot()。
    背景过程管理函数auxIdleFunc()。
    程序运行函数auxMainLoop()。
    4.  OpenGL工具库 OpenGL Utility Toolkit
    包含大约30多个函数,函数名前缀为glut。
    glut是不依赖于窗口平台的OpenGL工具包,由Mark KLilgrad在SGI编写(现在在Nvidia),目的是隐藏不同窗口平台API的复杂度。 函数以glut开头,它们作为aux库功能更强的替代品,提供更为复杂的绘制功能,此函数由glut.dll来负责解释执行。由于glut中的窗口管理函数是不依赖于运行环境的,因此OpenGL中的工具库可以在X-Window, Windows NT, OS/2等系统下运行,特别适合于开发不需要复杂界面的OpenGL示例程序。对于有经验的程序员来说,一般先用glut理顺3D图形代码,然后再集成为完整的应用程序。
    这部分函数主要包括
    窗口操作函数,窗口初始化、窗口大小、窗口位置等函数glutInit() glutInitDisplayMode() glutInitWindowSize() glutInitWindowPosition()等。
    回调函数。响应刷新消息、键盘消息、鼠标消息、定时器函数等,GlutDisplayFunc() glutPostRedisplay() glutReshapeFunc() glutTimerFunc() glutKeyboardFunc() glutMouseFunc()。
    创建复杂的三维物体。这些和aux库的函数功能相同。创建网状体和实心体。如glutSolidSphere()、glutWireSphere()等。在此不再叙述。
    菜单函数。创建添加菜单的函数GlutCreateMenu()、glutSetMenu()、glutAddMenuEntry()、glutAddSubMenu() 和glutAttachMenu()。
    程序运行函数,glutMainLoop()。
    5.  Windows专用库
    针对windows平台的扩展。包含有16个函数,函数名前缀为wgl。
    这部分函数主要用于连接OpenGL和Windows ,以弥补OpenGL在文本方面的不足。  Windows专用库只能用于Windows环境中。
    这类函数主要包括以下几类
    绘图上下文相关函数wglCreateContext(), wglDeleteContext()wglGetCurrentContent() wglGetCurrentDC() wglDeleteContent()等
    文字和文本处理函数 wglUseFontBitmaps()、wglUseFontOutlines()。
    覆盖层、地层和主平面层处理函数 wglCopyContext()、wglCreateLayerPlane()、  wglDescribeLayerPlane()、wglReakizeLayerPlatte()等
    其他函数,wglShareLists()、wglGetProcAddress()等。
    6.  Win32 API函数库
     包含有6个函数,函数名无专用前缀。
    是win32扩展函数。这部分函数主要用于处理像素存储格式和双帧缓存。这6个函数将替换Windows GDI中原有的同样的函数。Win32API函数库只能用于Windows 95/98/NT环境中。
    7         X窗口专用库
    是针对Unix和Linux的扩展函数。
    包括渲染上下文、绘制图元、显示列表、纹理贴图、等等
    初始化 glXQueryExtension()
    渲染上下文函数, glXCreateContext() glXDestroyContext() glXCopyContext() glXMakeCurrent() glXCreateGLXPixmap()
    执行 glXWaitGL()、glXWaitX()
    缓冲区和字体 glXSwapBuffers()、glXUseXFont()
    8 其他扩展库
    这些函数可能是新的OpenGL函数,并没有在标准OpenGL库中实现,或者它们是用来扩展已存在的OpenGL函数的功能。和glu、glx和wgl一样,这些OpenGL扩展是由硬件厂商和厂商组织开发的。OpenGL扩展(OpenGL Extention)包含了大量的扩展API函数。
    随着硬件的更新,硬件厂商首先向SGI申请登记新的扩展,编写规格说明书(specification)。然后按照说明书进行开发扩展程序。不同的OpenGL实现(OpenGL Implementation)支持的扩展可能不一样,只有随着某一扩展的推广与应用以及硬件技术的提高该扩展才会在所有的OpenGL实现中被给予支持,从而最终成为OpenGL标准库的一部分。扩展由SGI维护,在SGI网站上列出了目前公开的已注册的扩展及其官方说明书。
    扩展源由扩展函数的后缀来指明(或使用扩展常量后缀)。例如,后缀WIN表明一个符合Windows规范的扩展,EXT或ARB后缀表明该扩展由多个卖主定义。
    下面给出OpenGL官方规定的命名规则:
    ARB – OpenGL Architecture Review Board 正式核准的扩展,往往由厂商开发的扩展发展而来,如果同时存在厂商开发的扩展和ARB扩展,应该优先使用ARB扩展
    EXT – 多家OpenGL厂商同意支持的扩展
    HP – Hewlett-Packard 惠普
    IBM – International Business Machines
    KTX – Kinetix, maker of 3D Studio Max
    INTEL – Intel 公司
    NV – NVIDIA 公司
    MESA – Brian Paul’s freeware portable OpenGL implementation
    SGI – Silicon Graphics公司开发的扩展
    SGIX – Silicon Graphics (experimental) 公司开发的实验性扩展
    SUN – Sun Microsystems
    WIN – Microsoft
    由于OpenGL扩展在针对不同平台和不同驱动,OpenGL不可能把所有的接口程序全部放到gl.h、glx.h、wgl.h中,而是将这些函数头放在了glext.h、glxext.h和wglext.h中。这些扩展被看作时OpenGL核心库规范的增加和修改。
    OpenGL扩展也不是没有缺点,正因为各个硬件厂商都可以开发自己的扩展,所以扩展的数目比较大,而且有点混乱,有些扩展实现的相同的功能,可因为是不同厂商开发的,接口却不一样,所以程序中为了实现这个功能,往往要为不同的显卡写不同的程序。这个问题在OpenGL 2.0出来后可能会得到解决,OpenGL 2.0的一个目标就是统一扩展,减少扩展数目。

    展开全文
  • OPENGL GLUT

    2015-03-23 22:28:45
    OpenGL中的gl是核心,glu是实用,glut是实用工具, gl是核心,glu是对gl的部分封装,glut是OpenGL的跨平台工具,gl中包含了最基本的3D函数,而glu似乎对gl的辅助,如果算数好,不用glu的情况下,也是...
  • OpenGL函数

    千次阅读 2013-04-12 23:53:33
    OpenGL图形一共有100多个函数,它们分别属于OpenGL的基本、实用、辅助等不同的。 1、核心 包含的函数有115个,它们是最基本的函数,其前缀是gl;这部分函数用于常规的、核心的图形处理,由gl.dll来...
  • OpenGL开发介绍

    2013-07-17 21:07:20
    OpenGl开发介绍 2013-07-17 ////////////////////////////////////////////////////////////////////// 转自:http://www.cppblog.com/tx7do/archive/2007/04/07/21472.html  OpenGL函数相关的API有核心(gl)...
  • OpenGL FreeType 概述

    千次阅读 2017-07-27 12:56:14
    NeHe OpenGL第四十三课...使用FreeType可以创建非常好看的反走样的字体,记住暴雪公司就是使用这个的,就是那个做魔兽世界的。尝试一下吧,我只告诉你了基本的使用方式,你可以走的更远。   在OpenGL中使用FreeTyp
  • openGL函数简介

    2013-05-16 21:26:31
    OpenGL函数 1、OpenGL核心  核心包含有115个函数。函数名的前缀为gl。  这部分函数常用户常规的、核心的图形处理。 2、OpenGL实用 GLU  包含43个函数,前缀为glu。  OpenGL提供了强大的但是位数不...
  • OpenGL函数介绍

    2014-09-11 16:35:05
      开发基于OpenGL的应用程序,必须先了解OpenGL的库函数。它采用C语言风格,提供大量的函数来进行图形的处理和显示。OpenGL库函数的命名...前缀&gt;&lt;根命令&gt;&lt;可选的参数个数&g...
  • OpenGL开发的介绍

    2017-01-17 08:25:59
    开发基于 OpenGL的应用程序,必须先了解 OpenGL的库函数。...前缀有 gl、glu、aux、glut、wgl、glx、agl等等,分别表示该函数属于 OpenGL那个开发,从函数名后面中还可以看出需要多少个参数以及参数的类型。 I代表
  • /* GLUT font sub-API */ GLUTAPI void APIENTRY glutBitmapCharacter(void ...Font表示要使用的图像字体,如下表所示: GLUT_BITMAP_8_BY_13 一种固定宽度字体,每个字符都放在一个8x13像素的矩形框内 GLUT_BITMAP_9_BY
  • OpenGL开发的组成

    2012-05-03 01:06:42
    OpenGL开发的组成 OpenGL开发的组成 开发基于OpenGL的应用程序,必须先了解OpenGL的库函数。它采用C语言风格,提供大量的函数来进行图形的处理和显示。OpenGL库函数的命名方式非常有规律。所有OpenGL函数采用...
  • Opengl开发介绍

    千次阅读 2008-01-15 12:44:00
    Opengl开发介绍 开发基于OpenGL的应用程序,必须先了解OpenGL的库函数。它采用C语言风格,提供大量的函数来进行图形的处理和显示。OpenGL库函数的命名方式非常有规律。所有OpenGL函数采用了以下格式:
  • OpenGL

    千次阅读 2009-08-04 11:54:00
    OpenGL库函数的命名方式为:前缀>根命令>可选的参数个数>可选的参数类型>。前缀有gl、glu、aux、glut、wgl、glx、agl等等,表示该函数属于OpenGL哪个。参数的类型:I代表int型,f代表float型,d代表double型,...
  • opengl函数介绍

    千次阅读 2010-04-01 17:08:00
    所有OpenGL函数采用了以下格式: 前缀有gl、glu、aux、glut、wgl、glx、agl等等,分别表示该函数属于OpenGL那个开发,从函数名后面中还可以看出需要多少个参数以及参数的类型。I代表int型,
  • OPenGL函数说明

    千次阅读 2013-03-08 19:46:07
    ghjtlnit--初始化GLUT glutlnitwindowPosition--设置初始窗口位置 glutlnitwindowsize--设置初始窗口大小 glutlnitDisplayMode--设置初始显示模式 glutMainLoop--进人GLUT事件处理循环 窗口管理 ...
  • OpenGL 简介

    2018-08-18 07:18:09
    OpenGL 简介  OpenGL库函数的命名方式为:&lt;前缀&gt;&lt;根命令&gt;&lt;可选的参数个数&gt;&lt;可选的参数类型&gt;。 前缀有gl、glu、aux、glut、wgl、glx、agl等等,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,761
精华内容 3,904
关键字:

opengl字体库