在新的OpenGL版本(3.0和4.0版本)中,不推荐使用gl_Vertex等内置顶点属性.实际渲染任何东西的"新方法"是为位置,颜色等指定自己的顶点属性,然后将这些自定义属性绑定到缓冲区.
我的问题是:如果不将渲染代码和着色器紧密耦合,怎么能做到这一点?如果我编写一个使用"position"作为顶点位置的着色器,使用着色器的主代码必须知道并将顶点数据作为"position"传递.如果我想使用写入的不同着色器来获取"vertex_pos"中的顶点数据,我必须首先重写该着色器,或者修改我的主机代码以将顶点数据发送为"vertex_pos".
是否有一组所有着色器应使用的标准顶点和片段属性的最佳实践名称?或者是否存在Balkanized引擎特定标准,以便为一个引擎编写的着色器无法在没有修改的情况下在另一个引擎上工作?或者根本没有标准,一般来说,每个对象都需要自己的自定义渲染代码来匹配其自定义着色器?
我想使用WebGL中OpenGL 4的一些功能(特别是曲面细分着色器和更新的着色器语言版本).这是可能的,无论是符合标准还是以hackish方式?是否有一些神奇的价值我可以使用而不是说gl.FRAGMENT_SHADER来告诉基础GL实现编译曲面细分着色器?
我使用gltexSubImage2D()更新到OpenGL 4.0中的texture2D.纹理使用自动生成的mipmap生成
glGenerateMipmap(GL_TEXTURE_2D);
Run Code Online (Sandbox Code Playgroud)
我的纹理更新失败,直到我明白我必须在更新时重新生成mipmap (或删除mipmaps生成).然后我读了这个 wiki,当生成mipmap时有一个glTexStorage2D的用法.我实际上从来没有注意过这个方法.所以我我想知道每次使用mipmap生成纹理时是否必须使用它?
更新:
我从方法规格中看出它
同时指定二维纹理或一维纹理阵列的所有级别的存储要求
我想在使用它时应该会在生成mipmap时提高性能吗?这是真的吗?
"着色器存储缓冲区对象"(SSBO)和图像加载存储操作之间存在什么差异
什么时候应该使用而不是另一个?
它们都可以有原子操作,我认为它们存储在相同类型的内存中.并且无论它们是否存储在相同类型的内存中,它们是否具有相同的性能特征?
编辑:原始问题是SSBO和统一缓冲区对象之间的问题,它意味着在SSBO和图像加载存储之间.
我正在按照步骤进行操作HOWTOBUILD.txt.我已经为glfw构建了必要的文件.链接器第一次抱怨glfw.搜索后,似乎我需要链接反对gl3w 看到这个链接.我为它生成了静态库gl3w.现在,我已经开了一个新项目并包含了路径include,见下图.
对于链接器,我已经链接glfw3dll.lib gl3w.lib opengl32.lib并包含它们的路径.如果我从第一章开始运行样本,
main.cpp
#include "sb7.h"
class my_application : public sb7::application
{
void render(double currentTime)
{
static const GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, red);
}
};
DECLARE_MAIN(my_application);
Run Code Online (Sandbox Code Playgroud)
我收到链接器错误.
1>main.obj : error LNK2019: unresolved external symbol "int __cdecl sb6IsExtensionSupported(char const *)" (?sb6IsExtensionSupported@@YAHPBD@Z) referenced in function "public: virtual void __thiscall sb7::application::run(class sb7::application *)" (?run@application@sb7@@UAEXPAV12@@Z)
1>main.obj : error LNK2019: unresolved external symbol "private: static void …Run Code Online (Sandbox Code Playgroud) 首先,OpenGL中有8种类型的缓冲区对象:
它们是枚举,或者更具体地说是GLenum.其中GLenum是一个无符号的32位整数,其值可达~4,743,222,432.
缓冲区对象的大多数用法都涉及将它们绑定到某个目标,例如:
glBindBuffer(GL_ARRAY_BUFFER,Buffers [size]);
[void glBindBuffer(GLenum target,GLuint buffer)]文档
我的问题是 - 如果它的枚举,它的唯一值必须分别为0,1,2,3,4..7,那么为什么要一直走到32位整数,如果它的值只有7?请原谅我对CS和OpenGL的了解,这似乎是不道德的.
我试图通过一个非常基本的示例来弄清楚 SSBO 是如何工作的。顶点着色器:
#version 430
layout(location = 0) in vec2 Vertex;
void main() {
gl_Position = vec4(Vertex, 0.0, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
和片段着色器:
#version 430
layout(std430, binding = 2) buffer ColorSSBO {
vec3 color;
};
void main() {
gl_FragColor = vec4(color, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
我知道它们有效,因为如果我替换vec4(color, 1.0)为,vec4(1.0, 1.0, 1.0, 1.0)我会在屏幕中央看到一个白色三角形。
我使用以下代码初始化并绑定 SSBO:
GLuint ssbo;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
float color[] = {1.f, 1.f, 1.f};
glBufferData(GL_SHADER_STORAGE_BUFFER, 3*sizeof(float), color, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
Run Code Online (Sandbox Code Playgroud)
这里有什么问题吗?
我正在使用OpenGL(4.5核心,使用LWJGL 3.0.0 build 90),我注意到纹理上的一些工件使用GL_REPEAT了具有大量重复的包装模式:
这里,平面的大小是100x100,UV是10000x10000.这个截图是真的很接近它(从更远的,质地是如此之小,我们只看到一台灰色),近平面是在0.0001和10远平面,我不知道问题出在自OpenGL默认值以来,深度缓冲区在更近距离处具有非常高的精度.
(编辑:我在考虑纹理坐标上的浮点错误,但我不确定)
这是我的着色器(我使用延迟渲染,纹理采样在几何传递中,所以我只给出几何传递着色器).
顶点着色器:
#version 450 core
uniform mat4 projViewModel;
uniform mat4 viewModel;
uniform mat3 normalView;
in vec3 normal_model;
in vec3 position_model;
in vec2 uv;
in vec2 uv2;
out vec3 pass_position_view;
out vec3 pass_normal_view;
out vec2 pass_uv;
out vec2 pass_uv2;
void main(){
pass_position_view = (viewModel * vec4(position_model, 1.0)).xyz;
pass_normal_view = normalView * normal_model;
pass_uv = uv;
pass_uv2 = uv2;
gl_Position = projViewModel * vec4(position_model, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
片段着色器:
#version 450 core
struct …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用着色器存储缓冲区对象(又名缓冲区块),但有些事情我还没有完全掌握。我想做的是在其中存储不确定数量的灯光的(简化)数据n,以便我的着色器可以遍历它们并执行计算。
首先,我说我得到了正确的结果,并且OpenGL没有错误。然而,困扰我不知道为什么它是工作。
因此,在我的着色器中,我得到了以下内容:
struct PointLight {
vec3 pos;
float intensity;
};
layout (std430, binding = 0) buffer PointLights {
PointLight pointLights[];
};
void main() {
PointLight light;
for (int i = 0; i < pointLights.length(); i++) {
light = pointLights[i];
// etc
}
}
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中:
struct PointLightData {
glm::vec3 pos;
float intensity;
};
class PointLight {
// ...
PointLightData data;
// ...
};
std::vector<PointLight*> pointLights;
glGenBuffers(1, &BBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, BBO);
glNamedBufferStorage(BBO, n * sizeof(PointLightData), NULL, GL_DYNAMIC_STORAGE_BIT);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, …Run Code Online (Sandbox Code Playgroud) 我正在学习 opengl 并尝试使用 glDrawEmelents 绘制索引圆,但由于某种原因它不起作用。但是,当我使用 glDrawElements 绘制三角形时(请参阅注释代码),它可以很好地绘制三角形。我认为这与我的元素/索引有关,但我不知道。
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("GL Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 500, 500, SDL_WINDOW_OPENGL);
SDL_GLContext context = SDL_GL_CreateContext(window);
glewExperimental = true;
GLenum error = glewInit();
if (error != GLEW_OK)
return -1;
if (context == NULL)
return -1;
SDL_Event event;
GLuint vShader = 0;
GLuint fShader = 0;
static const GLchar* fragText[] = {
"#version 450 core \n"
"\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" color = vec4(0.5,0.8,1.0,0.7);\n"
"}\n"
}; …Run Code Online (Sandbox Code Playgroud)