我正在使用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方法(即glxxx()方法).我只需要使用gl方法绘制文本.读完红皮书后,我明白只有通过这种glBitmap()方法才有可能.如果这是唯一可行的方法,那么任何人都可以帮助我获取所有字符的像素数组信息.有没有其他方式来绘制文字?
我目前正在研究OpenGL中的照明,它使用GLSL中的一个函数,称为normalize.根据OpenGL文档,它说它"计算两个向量的标准化乘积".但是,它仍然无法解释"正常化"的含义.我已经尝试过在Google上查找标准化产品,但我似乎无法找到任何相关信息.任何人都可以解释正常化的含义并提供一些标准化值的例子吗?
经过多年关于顶点缓冲对象(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():
顶点阵列(CPU端):
顶点缓冲对象(GPU端):
哪个更好 ?
到具有一个着色器程序有很多制服指定灯使用,或映射做(例如,我需要一个网格被视差映射,并且映射另一个视差/镜面).我会制作一个缓存转移制服的缓存列表,如果需要的话,只需为每个下一个网格更换一些制服.
要 为每个需要的案例设置很多着色器程序,每个案例都有少量制服,如果需要的话,每个网格都使用glUseProgram进行惰性绑定.在这里,我假设网格已正确批处理,以避免冗余切换.
我用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(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)很可能是段错误,但我想先解决类型错误.
我正在使用OpenGL数学库(glm.g-truc.net),并希望glm::mat4使用float-array 初始化a .
float aaa[16];
glm::mat4 bbb(aaa);
Run Code Online (Sandbox Code Playgroud)
这不起作用.
我想这个解决方案很简单,但我不知道怎么做.我找不到关于glm的好文档.我会很感激一些有用的链接.
正如标题所说,我似乎无法使用OpenGL和Glut构建项目.
我得到OpenGL函数的Undefined引用错误.
我试过做:
project(testas)
find_package(OpenGL)
find_package(GLUT)
add_executable(testas main.cpp)
Run Code Online (Sandbox Code Playgroud)
但这不起作用.
有什么建议?
我的大学开始教授包含OpenGL编程的课程.他们让我们使用FreeGLUT为OpenGL创建窗口和上下文,但我在lynda.com上找到了一个关于OpenGL的在线课程,他们使用GLFW而不是FreeGLUT.
所以我想知道我应该使用哪一个,两者之间有什么区别?
我正在尝试一个项目,我可以使用opengl/directx或GDI为windows 7壁纸设置动画.我调查了Windows桌面窗口是如何布局的,我想出了整体
"Progman" - >"SHELLDLL_DefView" - >"SysListView32"
层次结构.我尝试连接SysListView32的WndProc,并尝试使用注入的c#dll搞乱消息,这样当我使用控制面板 - >个性化菜单强制更改时,我可以阻止桌面绘制壁纸.这些都没有实际阻止壁纸更新,所以我认为explorer.exe实际上并不处理绘制壁纸.
为了确认这一点,我杀死了explorer.exe并设置了一个小的c#程序,它将10秒计时器上的壁纸改为随机的.正如我所料,壁纸不断变化,让我相信explorer.exe实际上并没有处理壁纸的绘制!
不幸的是,这是我完全迷失的地方.我不知道还有什么负责绘制壁纸,以及我如何能够接管它的绘图以便我可以处理绘图.我已经尝试谷歌这几天了,几乎没有进展.我希望有人能指引我朝着正确的方向前进.