标签: opengl

GLSL中的顶点着色器属性映射

我正在使用GLSL着色器编写一个小型渲染引擎:

每个网格(井,子网格)都有一些顶点流(例如位置,法线,纹理,切线等)到一个大的VBO和一个MaterialID中.

每个材质都有一组纹理和属性(例如镜面反射颜色,漫反射颜色,颜色纹理,法线贴图等)

然后我有一个GLSL着色器,它的制服和属性.让我们说:

uniform vec3 DiffuseColor;
uniform sampler2D NormalMapTexture;
attribute vec3 Position;
attribute vec2 TexCoord;
Run Code Online (Sandbox Code Playgroud)

我试图为GLSL着色器设计一种方法来定义属性和制服的流映射(语义),然后将顶点流绑定到适当的属性.

对网格说法的内容:"将您的位置流放在属性"位置"中,将您的tex坐标放在"TexCoord"中.还将材质的漫反射颜色放在"DiffuseColor"中,将材质的第二个纹理放在"NormalMapTexture"中

目前我正在使用硬编码的名称作为属性(即顶点pos始终是"位置"等)并检查每个统一和属性名称以了解着色器使用它的内容.

我想我正在寻找一种创建"顶点声明"的方法,但也包括制服和纹理.

所以我只是想知道人们如何在大型渲染引擎中做到这一点.

编辑:

回顾建议的方法:

1.属性/统一语义由变量名称给出 (我现在正在做什么)为每个可能的属性使用预定义的名称.GLSL绑定器将查询每个属性的名称并基于该属性链接顶点数组.变量名称:

//global static variable

semantics (name,normalize,offset) = {"Position",false,0} {"Normal",true,1},{"TextureUV,false,2}

 ...when linking
for (int index=0;index<allAttribs;index++)
{
   glGetActiveAttrib(program,index,bufSize,length,size[index],type[index],name);      
   semantics[index]= GetSemanticsFromGlobalHardCodedList(name);
} 
... when binding vertex arrays for render
 for (int index=0;index<allAttribs;index++)
{
    glVertexAttribPointer(index,size[index],type[index],semantics[index]->normalized,bufferStride,semantics[index]->offset);

}  
Run Code Online (Sandbox Code Playgroud)

2.每个语义的预定义位置

GLSL绑定器将始终将顶点数组绑定到相同的位置.着色器可以使用相应的名称进行匹配.(这看起来非常类似于方法1,但除非我误解,否则这意味着绑定所有可用的顶点数据,即使着色器不使用它)

.. when linking the program...
glBindAttribLocation(prog, 0, "mg_Position");
glBindAttribLocation(prog, 1, "mg_Color");
glBindAttribLocation(prog, 2, "mg_Normal");
Run Code Online (Sandbox Code Playgroud)

3.来自Material,Engine globals,Renderer和Mesh的可用属性的字典

维护活动材质,引擎全局,当前渲染器和当前场景节点发布的可用属性列表.

例如:

 Material has (uniformName,value) = …
Run Code Online (Sandbox Code Playgroud)

opengl glsl rendering-engine

37
推荐指数
2
解决办法
3万
查看次数

如何仅使用OpenGL方法绘制文本?

我没有选择使用OpenGL方法(即glxxx()方法).我只需要使用gl方法绘制文本.读完红皮书后,我明白只有通过这种glBitmap()方法才有可能.如果这是唯一可行的方法,那么任何人都可以帮助我获取所有字符的像素数组信息.有没有其他方式来绘制文字?

c c++ opengl graphics

37
推荐指数
4
解决办法
11万
查看次数

归一化价值意味着什么?

我目前正在研究OpenGL中的照明,它使用GLSL中的一个函数,称为normalize.根据OpenGL文档,它说它"计算两个向量的标准化乘积".但是,它仍然无法解释"正常化"的含义.我已经尝试过在Google上查找标准化产品,但我似乎无法找到任何相关信息.任何人都可以解释正常化的含义并提供一些标准化值的例子吗?

opengl glsl normalization

37
推荐指数
2
解决办法
3万
查看次数

VBO何时比"简单"OpenGL原语(glBegin())更快?

经过多年关于顶点缓冲对象(VBO)的讨论,我终于决定尝试它们(我的东西通常不是性能关键,显然......)

我将在下面描述我的实验,但总而言之,我看到"简单"直接模式(glBegin()/ glEnd()),顶点数组(CPU端)和VBO(GPU端)之间无法区分性能渲染模式.我试图理解为什么会这样,并且在什么条件下我可以期待看到VBO明显优于他们原始(双关语)的祖先.

实验细节

对于实验,我生成了一个具有大量点的(静态)3D高斯云.每个点都有与之关联的顶点和颜色信息.然后我在连续的帧中围绕云旋转相机,这是一种"轨道"行为.同样,这些点是静态的,只有眼睛移动(通过gluLookAt()).数据在任何渲染之前生成一次并存储在两个数组中以用于渲染循环.

对于直接渲染,整个数据集在单个glBegin()/ glEnd()块中呈现,其中包含一个循环,每个循环包含glColor3fv()和glVertex3fv().

对于顶点数组和VBO渲染,整个数据集使用单个glDrawArrays()调用进行渲染.

然后,我只需在紧凑的循环中运行一分钟左右,并使用高性能计时器测量平均FPS.

表现结果##

如上所述,我的台式机(XP x64,8GB RAM,512 MB Quadro 1700)和笔记本电脑(XP32,4GB RAM,256 MB Quadro NVS 110)的性能难以区分.然而,它确实按照预期的点数进行了扩展.显然,我也禁用了vsync.

笔记本电脑运行的具体结果(使用GL_POINTS渲染):

在glBegin()/ glEnd():

  • 1K分 - > 603 FPS
  • 10K分 - > 401 FPS
  • 100K分 - > 97 FPS
  • 1M点 - > 14 FPS

顶点阵列(CPU端):

  • 1K分 - > 603 FPS
  • 10K分 - > 402 FPS
  • 100K分 - > 97 FPS
  • 1M点 - > 14 FPS

顶点缓冲对象(GPU端):

  • 1K分 - > 604 FPS
  • 10K分 - > 399 FPS
  • 100K分 - > 95 …

opengl graphics performance vbo vertex-buffer

36
推荐指数
2
解决办法
2万
查看次数

在OpenGL引擎中组织GLSL着色器

哪个更好 ?

  1. 具有一个着色器程序有很多制服指定灯使用,或映射做(例如,我需要一个网格被视差映射,并且映射另一个视差/镜面).我会制作一个缓存转移制服的缓存列表,如果需要的话,只需为每个下一个网格更换一些制服.

  2. 要 为每个需要的案例设置很多着色器程序,每个案例都有少量制服,如果需要的话,每个网格都使用glUseProgram进行惰性绑定.在这里,我假设网格已正确批处理,以避免冗余切换.

c++ opengl shader glsl

36
推荐指数
2
解决办法
4706
查看次数

带有std :: vector的VBO

我用C++和OpenGL编写了一个模型加载器.我用std::vectors来存储我的顶点数据,但现在我想把它传递给它glBufferData(),但是数据类型却截然不同.我想知道如果有之间进行转换的方式std::vector所记录const GLvoid *glBufferData().

顶点类型

typedef struct
{
    float x, y, z;
    float nx, ny, nz;
    float u, v;
}
Vertex;

vector<Vertex> vertices;
Run Code Online (Sandbox Code Playgroud)

glBufferData()调用

glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(float), vertices, GL_STATIC_DRAW);
Run Code Online (Sandbox Code Playgroud)

我得到以下(预期)错误:

error: cannot convert ‘std::vector<Vertex>’ to ‘const GLvoid*’ in argument passing
Run Code Online (Sandbox Code Playgroud)

如何将矢量转换为兼容的类型glBufferData()

NB.我不关心目前正确的内存分配; vertices.size() * 3 * sizeof(float)很可能是段错误,但我想先解决类型错误.

c++ opengl vector vbo

36
推荐指数
2
解决办法
2万
查看次数

如何使用数组初始化glm :: mat4?

我正在使用OpenGL数学库(glm.g-truc.net),并希望glm::mat4使用float-array 初始化a .

float aaa[16];
glm::mat4 bbb(aaa);
Run Code Online (Sandbox Code Playgroud)

这不起作用.

我想这个解决方案很简单,但我不知道怎么做.我找不到关于glm的好文档.我会很感激一些有用的链接.

c++ opengl math glm-math

36
推荐指数
3
解决办法
4万
查看次数

如何用linux中的CMake和Kdevelop编译GLUT + OpenGL项目?

正如标题所说,我似乎无法使用OpenGL和Glut构建项目.

我得到OpenGL函数的Undefined引用错误.

我试过做:

project(testas)
find_package(OpenGL)
find_package(GLUT)
add_executable(testas main.cpp)
Run Code Online (Sandbox Code Playgroud)

但这不起作用.

有什么建议?

linux opengl cmake

36
推荐指数
3
解决办法
5万
查看次数

FreeGLUT和GLFW有什么区别?

我的大学开始教授包含OpenGL编程的课程.他们让我们使用FreeGLUT为OpenGL创建窗口和上下文,但我在lynda.com上找到了一个关于OpenGL的在线课程,他们使用GLFW而不是FreeGLUT.

所以我想知道我应该使用哪一个,两者之间有什么区别?

opengl glut freeglut glfw

36
推荐指数
1
解决办法
2万
查看次数

什么实际处理Windows壁纸的绘图?

我正在尝试一个项目,我可以使用opengl/directx或GDI为windows 7壁纸设置动画.我调查了Windows桌面窗口是如何布局的,我想出了整体

"Progman" - >"SHELLDLL_DefView" - >"SysListView32"

层次结构.我尝试连接SysListView32的WndProc,并尝试使用注入的c#dll搞乱消息,这样当我使用控制面板 - >个性化菜单强制更改时,我可以阻止桌面绘制壁纸.这些都没有实际阻止壁纸更新,所以我认为explorer.exe实际上并不处理绘制壁纸.

为了确认这一点,我杀死了explorer.exe并设置了一个小的c#程序,它将10秒计时器上的壁纸改为随机的.正如我所料,壁纸不断变化,让我相信explorer.exe实际上并没有处理壁纸的绘制!

不幸的是,这是我完全迷失的地方.我不知道还有什么负责绘制壁纸,以及我如何能够接管它的绘图以便我可以处理绘图.我已经尝试谷歌这几天了,几乎没有进展.我希望有人能指引我朝着正确的方向前进.

c# windows opengl drawing windows-7

36
推荐指数
1
解决办法
1565
查看次数