【发布时间】:2015-06-12 03:46:20
【问题描述】:
我已经开始学习如何使用 OpenGL,我非常讨厌在 main() 之前将我的着色器声明为全局变量。
我认为创建一个可以从我的项目目录中的文件中读取着色器的结构或类会很酷。文件读取工作得很好,但由于某种原因,它实际上不会像我在 main 之前声明着色器那样输出图像。这是我的例子。
着色器读取结构:
#include "allHeader.h"
struct shaderReader
{
shaderReader::shaderReader(std::string);
const GLchar* source;
};
shaderReader::shaderReader(std::string name)
{
std::string line, allLines;
std::ifstream theFile(name);
if (theFile.is_open())
{
while (std::getline(theFile, line))
{
allLines = allLines + line + "\n";
}
source = allLines.c_str();
std::cout << source;
theFile.close();
}
else
{
std::cout << "Unable to open file.";
}
}
main() 之前的区域快照
shaderReader vertexShader = shaderReader("vertex.txt");
shaderReader fragmentShader = shaderReader("fragment.txt");
const GLchar* vertexSource =
"#version 150 core\n"
"in vec2 position;"
"void main() {"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const GLchar* fragmentSource =
"#version 150 core\n"
"out vec4 outColor;"
"void main() {"
" outColor = vec4(1.0, 1.0, 1.0, 1.0);"
"}";
int main()
{
//stuff
}
作品
GLuint vertexShaderObject = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderObject, 1, &vertexSource, NULL);
glCompileShader(vertexShaderObject);
//Now let's create the Fragment Shader Object
GLuint fragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderObject, 1, &fragmentSource, NULL);
glCompileShader(fragmentShaderObject);
由于某些原因不起作用
const GLchar* ob1 = vertexShader.source;
const GLchar* ob2 = fragmentShader.source;
GLuint vertexShaderObject = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderObject, 1, &ob1, NULL);
glCompileShader(vertexShaderObject);
//Now let's create the Fragment Shader Object
GLuint fragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderObject, 1, &ob2, NULL);
glCompileShader(fragmentShaderObject);
也不起作用
GLuint vertexShaderObject = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderObject, 1, &vertexShader.source, NULL);
glCompileShader(vertexShaderObject);
//Now let's create the Fragment Shader Object
GLuint fragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderObject, 1, &fragmentShader.source, NULL);
glCompileShader(fragmentShaderObject);
上面的代码在工作时会在黑屏中间打印出一个白色三角形。但是,当不工作时,我只会黑屏。我尝试检查着色器是否存在编译错误,但完全没有错误。我认为结构中可能有问题,我没有做对。感谢您阅读我的问题,如果您有类似的问题,希望我的问题对您有所帮助。
【问题讨论】:
-
在阅读完代码后,您让
allLines字符串超出范围。因此,包含着色器代码的内存将在您使用之前被释放。 -
将着色器放入
.txt文件中。在开始和结束处将每一行包裹在""中。以;结束。然后const GLChar* some_shader =,换行,#include "shader.txt"。你看!编译时间字符串,运行时不加载文件,你的着色器不碍事? -
嘿,@RetoKoradi
allLines究竟是如何超出范围的? @Yakk 如果可能的话,你能举个例子作为答案吗,谢谢。 -
@BryantheLion 你在构造函数中声明了
allLines。所以当构造函数结束时allLines被销毁了。 -
您不要将
allLines的内容复制到source中。你得到一个指向allLines内部数据的指针,并将该指针分配给source。然后,当allLines在构造函数结束时超出范围时,它会释放其内存,而source现在指向已释放的内存。