【问题标题】:512 bytes length vertex shaders not supported不支持 512 字节长度的顶点着色器
【发布时间】:2018-02-11 20:57:00
【问题描述】:

我正在开发一个基于着色器的简单游戏,随着我的顶点着色器文件的增长,它的大小达到 512 字节,我现在无法在 c++ 中加载它。 我认为这不是一个常见问题,但我想它来自我的自定义着色器加载程序,而不是来自 opengl 限制。 这是我的简单顶点着色器的代码(它应该将笛卡尔坐标映射到球形坐标,它的大小是583字节):

#version 330 core

uniform mat4 projection;
uniform mat4 camera;

layout (location=0) in vec3 vertex;
layout (location=1) in vec4 color;

in mat4 object;

out vec4 vColor;

void main()
{
  float x=sqrt(max(1.0-0.5*pow(vertex.y,2)-0.5*pow(vertex.z,2)+pow(vertex.y*vertex.z,2)/3.0,0.0));
  float y=sqrt(max(1.0-0.5*pow(vertex.x,2)-0.5*pow(vertex.z,2)+pow(vertex.x*vertex.z,2)/3.0,0.0));
  float z=sqrt(max(1.0-0.5*pow(vertex.x,2)-0.5*pow(vertex.y,2)+pow(vertex.x*vertex.y,2)/3.0,0.0));
  gl_Position=projection*camera*object*vec4(x,y,z,1.0); 
  vColor=color;
} 

以及加载器的代码:

GLuint vs;
vs=glCreateShader(GL_VERTEX_SHADER);
std::ifstream vertexShaderStream(_vsPath);
vertexShaderStream.seekg(0,std::ios::end);
unsigned int vsSourceLen=(unsigned int)vertexShaderStream.tellg();
vertexShaderStream.seekg(0,std::ios::beg);
char vertexShaderSource[vsSourceLen];
vertexShaderStream.read(vertexShaderSource,vsSourceLen);
vertexShaderStream.close();

const char *vsConstSource(vertexShaderSource);
glShaderSource(vs,1,&vsConstSource,NULL);
glCompileShader(vs);
int status;
glGetShaderiv(vs,GL_COMPILE_STATUS,&status);
if(!status)
{
    char log[256];
    glGetShaderInfoLog(vs,sizeof log,NULL,log);
    std::cout << log << std::endl;
    return -1;
}

当我将大小减小到 512bytes(2^9...)(511 及以下)以下时效果很好。 我正在使用 GLFW3 加载 openGL。 你见过这样的问题吗?

【问题讨论】:

  • char vertexShaderSource[vsSourceLen]; 甚至可以编译吗?堆栈数组只能以编译时已知的大小声明,但vsSourceLen 在编译时绝对不知道。
  • @BDL 这不在标准 C++ 中,但我们都知道这是一个常见的扩展。
  • opengl 遇到什么错误?
  • 是的,我已经将 y 更改为 z,这只是我在这篇文章中犯的一个错误。 OpenGL 抛出一个奇怪的错误“'= syntax error syntax error”

标签: c++ opengl glsl vertex-shader shading


【解决方案1】:

一个问题是您正在使用read 将着色器源读入char[] 缓冲区,而没有添加NUL 终止符,然后您使用NULL 调用glShaderSource 作为长度向量,所以它看起来用于 NUL 终止符来计算字符串的长度。所以我希望它随机失败,这取决于字符串之后内存中发生的情况(它是否幸运地显示为 NUL 终止,因为下一个字节恰好为 0)。

您需要正确地 NUL 终止您的字符串,或者将指向字符串长度的指针作为第四个参数传递给 glShaderSource

【讨论】:

  • 事实上它终于在没有指定尺寸的情况下工作了,但你说得对,这是在玩彩票,我终于把它设置正确了。
【解决方案2】:

在 ifstream 构造函数中添加 std::ifstream::binary 作为第二个参数解决了这个问题。我不完全理解为什么默认情况下将文件视为文本文件的 ifstream 会在文件长度达到 512 字节时停止计算行尾并添加一些随机字节以匹配实际大小。无论如何,使用 ifstream 肯定不是加载文件的最佳方式,但就它只是处理着色器而言,我会说这是可以的(使用适当的“ios::binary”标志)。

【讨论】:

  • 那是因为ftell 和朋友们返回文本流中的字节偏移量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多