我正在实现一个基于OpenGL构建的GUI.我遇到了每个GUI都有的问题 - 文本渲染.我知道在OpenGL中渲染文本的几种方法,但是,我想知道哪种方法最适合GUI.
通常在GUI中我们有两种类型的文本 - 静态和实时.静态很容易 - 我们可以将TTF渲染到纹理并忘记它.这是"现场"文本,更让我烦恼 - 想象控制台,或多人游戏中的实时聊天.
我想到了几个选择:
因此问题是 - 如何有效地在OpenGL中呈现文本?
如果这有帮助,我将使用STL/Boost-heavy C++进行编码,并针对GForce 6及更高版本的显卡.
我试图清楚地知道何时应该使用带有gl [Multi] DrawElements等绘制的OpenGL顶点的索引数组,而不是我应该简单地使用连续的顶点数组,用gl [Multi] DrawArrays绘制.
(更新:我得到的回复中的共识是,应该始终使用索引顶点.)
我已经多次在这个问题上来回走动了,所以我将概述我目前的理解,希望有人可以告诉我,我现在终于或多或少正确,或者指出我遗留的误解在哪里.具体来说,我有三个结论,粗体.如果错误请纠正.
一个简单的例子是如果我的几何体由网格组成以形成曲面.在这种情况下,网格中间的顶点对于使用顶点的每个三角形将具有相同的属性(位置,法线,颜色,纹理坐标等).
这使我得出结论:
对于接缝很少的几何体,索引数组是一个巨大的胜利.
始终遵循规则1,除了:
对于非常"块状"的几何体,其中每个边都代表一个接缝,索引数组的好处不那么明显.以一个简单的立方体为例,虽然每个顶点用于三个不同的面,但我们不能在它们之间共享顶点,因为对于单个顶点,表面法线(以及可能的其他东西,如颜色和纹理合作) )每张脸都会有所不同.因此,我们需要在我们的数组中明确引入冗余顶点位置,以便可以使用不同的法线等多次使用相同的位置.这意味着索引数组的使用较少.
例如,渲染立方体的单个面时:
0 1
o---o
|\ |
| \ |
| \|
o---o
3 2
Run Code Online (Sandbox Code Playgroud)
(这可以单独考虑,因为这个面和所有相邻面之间的接缝意味着这些顶点之间不能共享这些顶点)
如果使用GL_TRIANGLE_FAN(或_STRIP)进行渲染,则可以渲染立方体的每个面:
verts = [v0, v1, v2, v3]
colors = [c0, c0, c0, c0]
normal = [n0, n0, n0, n0]
Run Code Online (Sandbox Code Playgroud)
添加索引不允许我们简化此操作.
由此我得出结论:
2.当渲染所有接缝或大多数接缝的几何体时,当使用GL_TRIANGLE_STRIP或_FAN时,我应该永远不要使用索引数组,而应该总是使用gl [Multi] DrawArrays.
(更新:回复表明这个结论是错误的.即使索引不允许我们在这里减小数组的大小,仍然应该使用它们,因为其他性能优势,如评论中所讨论的)
规则2的唯一例外是:
当使用GL_TRIANGLES(而不是条带或扇形)时,一半的顶点仍然可以重复使用两次,具有相同的法线和颜色等,因为每个立方体面都呈现为两个独立的三角形.同样,对于相同的单个立方体面:
0 1
o---o
|\ |
| \ |
| \|
o---o
3 2
Run Code Online (Sandbox Code Playgroud)
没有索引,使用GL_TRIANGLES,数组将是这样的:
verts = [v0, v1, v2, v2, v3, …Run Code Online (Sandbox Code Playgroud) 我最近开始学习OpenGL(> 3.3)并且我注意到很多示例和教程都使用了freeglut和glew,但是并没有真正解释它们的区别.我在谷歌搜索和阅读广告后发现的最好的描述是这个OpenGL相关的工具包和API,但发现它缺乏.我甚至在SO上读过标签信息.
作为OpenGL的新手,我仍然试图掌握不同的概念.我已经到了创建基本程序的阶段,该程序使用glew,创建上下文(在Windows上,VS2010),并绘制真正基本的形状,所有这些都不需要明确包含freeglut.所以我不明白为什么我需要它.
所以我的问题是,有什么区别:
-freeglut
-glew
- (&glfw)
另一个人不能
做什么呢?
我能找到的每个介绍和样本似乎都使用GLUT或其他一些框架来"初始化"OpenGL.有没有办法用GL和GLU中的可用内容初始化OpenGL?如果没有,那么没有它,GLUT做什么是不可能的?
void main(void)
{
vec4 clipCoord = glModelViewProjectionmatrix * gl_Vertex;
gl_Position = clipCoord;
gl_FrontColor = gl_Color;
vec3 ndc = clipCoord.xyz / clipCoord.w;
Run Code Online (Sandbox Code Playgroud)
所以这clipCoord只是做标准的固定管道转换.为什么我会分开w,我从中得到什么?
我知道有一些关于学习OpenGL的问题.这就是我所知道的:
以下是我想知道的: - OpenGL 4.0 核心配置文件(或后者) - Shader Language 400(或后者) - 上面的每一部分(如果它不能在供应商之间工作那么它仍然不会打扰我)
这是我不想知道的 - 固定功能管道(永远不会使用它!) - 旧的OpenGL - 兼容性配置文件
我更喜欢大部分信息,如教程,系列文章,书籍.
PS如果您了解opengl 3.x核心配置文件的资源,也可以发布它们
我正在尝试使用ffmpeg渲染帧并将其从视频转换为OpenGL纹理以放置在四边形上.我已经筋疲力尽了谷歌并没有找到答案,我找到了答案,但似乎没有一个有效.
基本上,我avcodec_decode_video2()用来解码帧然后sws_scale()将帧转换为RGB然后glTexSubImage2D()从它创建一个openGL纹理,但似乎无法使任何东西工作.
我确保"目标"AVFrame在SWS上下文设置中具有2维的功能.这是我的代码:
SwsContext *img_convert_ctx = sws_getContext(pCodecCtx->width,
pCodecCtx->height, pCodecCtx->pix_fmt, 512,
256, PIX_FMT_RGB24, SWS_BICUBIC, NULL,
NULL, NULL);
//While still frames to read
while(av_read_frame(pFormatCtx, &packet)>=0) {
glClear(GL_COLOR_BUFFER_BIT);
//If the packet is from the video stream
if(packet.stream_index == videoStream) {
//Decode the video
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
//If we got a frame then convert it and put it into RGB buffer
if(frameFinished) {
printf("frame finished: %i\n", number);
sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
glBindTexture(GL_TEXTURE_2D, texture);
//gluBuild2DMipmaps(GL_TEXTURE_2D, …Run Code Online (Sandbox Code Playgroud) 我是否更愿意在CPU或GPU上计算矩阵?
假设我有以下矩阵P * V * M,我应该在CPU上计算它们以便我可以将最终矩阵发送到GPU(GLSL),还是应该将这三个矩阵分别发送到GPU以便GLSL可以计算最终矩阵?
我的意思是在这种情况下,GLSL必须为每个顶点计算MVP矩阵,因此在CPU上预先计算它可能更快.
但是,让我们说GLSL只需要计算一次MVP矩阵,GPU会比CPU更快地计算出最终矩阵吗?
我的应用程序从网络获取数据并在场景中绘制(场景使用手工制作的OpenGL引擎).
它可以工作几个小时.当我不使用我的桌面时,我的显示器因显示器电源管理器信令(dpms)关闭.然后,当我触摸鼠标或键盘时,显示器打开,应用程序挂起(X也挂起).
如果我这样做
xset -dmps
操作系统不使用dpms并且应用程序工作稳定.
这些问题出现在Centos 6和Archlinux中,但是当我在Ubuntu 12.10下运行应用程序时,它运行得很好!
我尝试了不同的NVidia驱动程序.没有效果.
我尝试使用ssh进行远程登录并使用gdb附加到进程.打开监视器后,我无法在进程表中找到该应用程序.
如何诊断问题?当显示器关闭/打开时会发生什么(在OpengGL环境中)?使用dpms时,Ubuntu是否做了一些特别的事情?
我们猜测问题的原因!当监视器关闭时,我们失去了OpenGL上下文.当监视器唤醒时,应用程序挂起(无上下文).根据操作系统的不同,行为的差异是由于监视器连接不同:Kubuntu的监视器连接VGA电缆.所以(可能)它对X行为没有影响.
我知道在过去的几年中也有类似的问题,但在做了一些研究后,我仍然无法决定从哪里学习,应该学什么.我还希望通过更多的C++ OOP和着色器方法来了解您对现代OpenGL编程的当前实际观点.并确保我对某些事情的实际理解是有效的.
所以...目前我们已经有了OpenGL 4.2,当我读到某个地方需要dx11硬件(它是什么意思?)和一组'侧'库时,例如创建窗口.
有最常见的GLUT,我非常讨厌.其中一个主要原因是函数调用,它不允许我们创建主循环的方式自由.正如一些人所说,它不适合游戏.
还有GLFW,实际上对我来说非常好而直截了当.出于某种原因,人们将其与GLUT一起使用.(它不仅提供窗口初始化,还提供其他实用程序?)
还有SFML和SDL(SDL <SFML imo),而它们两者有时需要使用奇怪的方法来处理OGL,并且在某些情况下并不是很快.
而且我们还有GLEW,这是扩展加载实用程序......等待...... GLUT/GLFW已经不是扩展了吗?是否有任何理由使用它,就像是否有任何真正重要的扩展感兴趣?
直到现在我们都有窗口创建(和一些实用程序),但是...... OGL不会处理纹理,也不管3D模型.我需要多少个其他库?
我们现在提一下教育部分.有着名的NeHe教程.用C语言编写,使用WinApi,代码极其不清晰,过时的解决方案,但仍然是最受欢迎的解决方案.可以找到像Red Book这样的东西,这些东西与2.x或3.x等版本有关,但是只有少数(和未完成的)教程提到4.x.
怎么办?