gpt4 book ai didi

c++ - 顶点着色器由于非 Ascii 字符而无法编译?

转载 作者:搜寻专家 更新时间:2023-10-31 02:17:01 26 4
gpt4 key购买 nike

所以我开始使用带有 glew 和 GLFW 的 OpenGL 来创建游戏引擎,但在开始使用着色器时我几乎立即遇到了一个问题:

它们没有被使用,或者即使被使用也没有任何效果。

我一直在用大量其他示例检查我的代码,它们都匹配,没有什么不合适的地方,我开始耗尽想法和耐心(我一直试图弄清楚为什么将近现在一个月)。

我的主要核心代码在这里:

  #include "headers/Default.hpp"

//Window width and height variables
int windowWidth = 800;
int windowHeight = 600;
float Aspect = (float)windowWidth / (float)windowHeight;

//Buffer width and buffer height
int bufferWidth;
int bufferHeight;

double deltaTime;
double currentTime;
double newTime;

void CalculateDelta()
{
newTime = glfwGetTime();
deltaTime = newTime - currentTime;
currentTime = newTime;
}

//A call back function to get the window size
void UpdateWindowSize(GLFWwindow* window, int width, int height)
{
windowWidth = width;
windowHeight = height;

Aspect = (float)windowWidth / (float)windowHeight;
}

void UpdateFrameBufferSize(GLFWwindow* window, int width, int height)
{
bufferWidth = width;
bufferHeight = height;
}

//Starts on startup and creates an window context and starts the rendering loop
int main()
{
//Creates an engine startup log to keep
CreateStartupLog();

if (!glewInit())
{
WriteStartupLog("ERROR: GLEW failed to start\n");
return 1;
}
else
{
WriteStartupLog("INFO: GLEW initiated!\n");
}

//If glfw is not initiated for whatever reason we return an error
if (!glfwInit())
{
WriteStartupLog("ERROR: GLFW failed to start\n");
return 1;
}
else
{
WriteStartupLog("INFO: GLFW initiated!\n");
}

////////////////////////////////////////////////////////////////
// Window Section //
////////////////////////////////////////////////////////////////
//glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
//glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

//Gets the primary monitor of the PC and tells OpenGL to use that monitor
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* videoMode = glfwGetVideoMode(monitor);

//Creates a GLFW window context that we can work with
GLFWwindow* gameWindow = glfwCreateWindow(windowWidth/*videoMode->width*/, windowHeight/*videoMode->height*/, "FireTech Engine", NULL/*monitor*/, NULL);

//If the game window is not able to be created, prints an error and terminates the program
if (!gameWindow)
{
WriteStartupLog("ERROR: GLFW could not create a window\n");
glfwTerminate();
return 1;
}
else
{
WriteStartupLog("INFO: GLFW created a window!\n\n");
}

//Makes the current context
glfwMakeContextCurrent(gameWindow);

//Sets the window callback function for size
glfwSetWindowSizeCallback(gameWindow, UpdateWindowSize);
glfwSetFramebufferSizeCallback(gameWindow, UpdateFrameBufferSize);

//Initiate GLEW
glewExperimental = GL_TRUE;
glewInit();

////////////////////////////////////////////////////////////////
// Functions to set up various systems of the game engine //
////////////////////////////////////////////////////////////////

//Calls function to create a log file for the game engine
CreateEngineLog();
//Calls the function to compile the default shaders
CompileDefaultShader();
//Calls the function to get and print out hardware and OpenGL version
//PrintHardwareInfo();

////////////////////////////////////////////////////////////////
// Game Code //
////////////////////////////////////////////////////////////////
Sprite testSprite;

//Rendering loop
while (!glfwWindowShouldClose(gameWindow))
{
CalculateDelta();
glClearColor(0.3, 0.6, 1.0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//Viewport and ortho settings
glViewport(0, 0, windowWidth, windowHeight);
glOrtho(-1, 1, -1 / Aspect, 1 / Aspect, 0, 1);

//Draw a sprite
if (GLFW_PRESS == glfwGetKey(gameWindow, GLFW_KEY_F2))
{
testSprite.DebugDraw();
}
else
{
testSprite.Draw();
}

//Draws the stuff we just rendered
glfwSwapBuffers(gameWindow);
glLoadIdentity();

//Polls different events, like input for example
glfwPollEvents();

if (GLFW_PRESS == glfwGetKey(gameWindow, GLFW_KEY_F1))
{
int fps = GetFPS();
printf("FPS: ");
printf("%d\n", fps);

printf("Frequency: ");
printf("%f\n", 1/double(fps));
}

if (GLFW_PRESS == glfwGetKey(gameWindow, GLFW_KEY_ESCAPE))
{
glfwSetWindowShouldClose(gameWindow, 1);
}
}

glfwTerminate();
WriteEngineLog("PROGRAM EXITED: Window closed");
return 0;
}

这是 shader.cpp 代码:

        #include "../headers/Default.hpp"

string ReadShaderFile(char* path)
{
ifstream shaderFile;
shaderFile.open(path, std::ifstream::in);
string output;

if (shaderFile.is_open())
{
printf("Opened shader file located at: \"%s\"\n", path);

while (!shaderFile.eof())
{
output += shaderFile.get();
}

printf("Successfully read shader file located at: \"%s\"\n", path);
}
else
{
WriteEngineLog("ERROR: Could not read shader file!\n");
}

shaderFile.close();
return output;
}

Shader::Shader()
{
WriteEngineLog("WARNING: There was no path to any GLSL Shader files\n");
}

Shader::Shader(char* VertexShaderPathIn, char* FragmentShaderPathIn)
{
string vertexShaderString = ReadShaderFile(VertexShaderPathIn);
string fragmentShaderString = ReadShaderFile(FragmentShaderPathIn);

//Prints out the string to show the shader's code
printf("\n%s\n", vertexShaderString.c_str());
printf("\n%s\n", fragmentShaderString.c_str());

//Creates the GLchars needed to input the shader code
const GLchar* vertex_shader = vertexShaderString.c_str();
const GLchar* fragment_shader = fragmentShaderString.c_str();

//Creates a vertex shader and compiles it
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
WriteEngineLog("Blank vertex shader created\n");
glShaderSource(vertexShader, 1, &vertex_shader, NULL);
WriteEngineLog("Vertex shader given source\n");
glCompileShader(vertexShader);

//Compilation error checking begions here
GLint isVertexCompiled = 0;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isVertexCompiled);
if (isVertexCompiled == GL_FALSE)
{
//Gets the length of the log
GLint maxLength = 0;
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);

//Creates and writes the log to the errorLog
GLchar* errorLog = (GLchar*)malloc(maxLength);
glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &errorLog[0]);

//Writes to the engine log with the shader error
WriteEngineLog("ERROR: Vertex shader failed to compile!\n");
printf("%s\n", (char*)errorLog);

//Frees the errorLog allocation
free(errorLog);

//Deletes the shader so it doesn't leak
glDeleteShader(vertexShader);

WriteEngineLog("ERROR: Aborting shader creation.\n");
return;
}
//Writes in the engine log to report successful compilation
WriteEngineLog("Vertex shader successfully compiled!\n");

//Creates a fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
WriteEngineLog("Blank fragment shader created\n");
glShaderSource(fragmentShader, 1, &fragment_shader, NULL);
WriteEngineLog("Fragment shader given source\n");
glCompileShader(fragmentShader);

//Compilation error checking begions here
GLint isFragmentCompiled = 0;
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isFragmentCompiled);
if (isFragmentCompiled == GL_FALSE)
{
//Gets the length of the log
GLint maxLength = 0;
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);

//Creates and writes the log to the errorLog
GLchar* errorLog = (GLchar*)malloc(maxLength);
glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &errorLog[0]);

WriteEngineLog("ERROR: Fragment shader failed to compile\n");
printf("%s\n", (char*)errorLog);

//Frees the errorLog allocation
free(errorLog);

//Deletes the shader so it doesn't leak
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

WriteEngineLog("ERROR: Aborting shader creation.\n");
return;
}
//Writes in the engine log to report successful compilation
WriteEngineLog("Fragment shader successfully compiled!\n");

//Creates the final shader product
this->Program = glCreateProgram();
WriteEngineLog("Blank shader created\n");
glAttachShader(this->Program, vertexShader);
WriteEngineLog("Attatched Vertex shader to the shader\n");
glAttachShader(this->Program, fragmentShader);
WriteEngineLog("Attatched Fragment shader to the shader\n");
glLinkProgram(this->Program);

/*GLint isLinked = 0;
glGetProgramiv(this->Program, GL_LINK_STATUS, (int*)&isLinked);
if (isLinked == GL_FALSE)
{
//Gets the lngth of the shader info log
GLint maxLength = 0;
glGetProgramInfolog(ShaderOut, GL_INFO_LOG_LENGTH, &maxLength);

//Gets and puts the actual log into a GLchar
std::vector<GLchar> infoLog(maxLength);
glGetProgramInfoLog(ShaderOut, maxLength, &maxLength, &infoLog[0]);

//Deletes programs and shaders so they don't leak
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

WriteEngineLog((string)infoLog);

return;
}*/

WriteEngineLog("Shader linked!\n\n");

WriteEngineLog("INFO: Shader created!\n");

glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}

void Shader::Use()
{
glUseProgram(this->Program);
}

这是 quad.cpp 代码:

  #include "../headers/Default.hpp"

Quad::Quad()
{
position.x = 0;
position.y = 0;
scale.x = 1;
scale.y = 1;

VertexArray = CreateVertexArray();
}

//Quad constructor with one arg
Quad::Quad(Vector2 Position)
{
position = Position;

VertexArray = CreateVertexArray();
}

//Quad constructor with two args
Quad::Quad(Vector2 Position, Vector2 Scale)
{
position = Position;
scale = Scale;

VertexArray = CreateVertexArray();
}

GLuint Quad::CreateVertexArray()
{
GLfloat Vertices[] =
{
//VERTICES //COLORS //TEXCOORDS
0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, //1.0f, 1.0f, //Top Right Vertice
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, //1.0f, 0.0f, //Top Left Vertice
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f//, 0.0f, 0.0f //Bottom Left Vertice
};

GLuint vbo, vao;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);

glBindVertexArray(vao);

//Copy vertices into the buffer
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

//Attribute Pointers
//Position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
//Color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);

//Unbinds the VAO
glBindVertexArray(0);

return vao;
}

//Quad debug drawing function
void Quad::DebugDraw()
{
//Use the default shader
DefaultShader.Use();

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBindVertexArray(VertexArray);

// draw points 0-3 from the currently bound VAO with current in-use shader
glDrawArrays(GL_TRIANGLES, 0, 3);
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //CAUSING A CRASH AT THE MOMENT

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

//Unbinds the VAO
glBindVertexArray(0);
}

这是 sprite.cpp 代码:

  #include "../headers/Default.hpp"

Sprite::Sprite()
{
position.x = 0;
position.y = 0;
}

Sprite::Sprite(Texture tex)
{
defaultTexture = tex;
currentTexture = tex;
}

Sprite::Sprite(Texture tex, Vector2 pos)
{
defaultTexture = tex;
currentTexture = tex;
position = pos;
}

Sprite::Sprite(Texture tex, Vector2 pos, Vector2 Scale)
{
defaultTexture = tex;
currentTexture = tex;
position = pos;
scale = Scale;
}

void Sprite::Draw()
{
//Binds the default shader again
glBindVertexArray(VertexArray);

//Use the default shader
DefaultShader.Use();

// draw points 0-3 from the currently bound VAO with current in-use shader
glDrawArrays(GL_TRIANGLES, 0, 3);

glBindVertexArray(0);
}

这是我的顶点着色器和片段着色器代码(按顺序):

  //Vertex Shader
#version 330 core

layout (location = 0) in vec3 position; // The position variable has attribute position 0
layout (location = 1) in vec3 color;

out vec3 ourColor;

void main()
{
gl_Position = vec4(position, 1.0f); // See how we directly give a vec3 to vec4's constructor
ourColor = color;
}

//Fragment shader
#version 330 core

in vec3 ourColor;
out vec4 color;

void main()
{
color = ourColor;
}

我收到一条警告,提示我的着色器未编译...错误是顶点着色器的第 0 行有一个非 ascii 字符。

最佳答案

我有完全相同的错误。这几乎可以肯定是由于 Unicode Byte Order Marks , 或文本编辑器生成的类似未打印字符。

这些在 unicode 文件的第一个字符中很常见,但可以出现在任何地方。

您可以在编译之前以编程方式从您的着色器源代码字符串中去除这些,但如果您正在编译许多着色器,这可能会很昂贵。如果您走这条路,请参阅上面的链接以获取要删除的数据。

另一种方法是将文件保持为 ANSI/ASCII 格式。我相信大多数文本编辑器都有设置/转换格式的功能,但我会给出 Notepad++作为示例,因为它是我用来编辑 GLSL 的工具:

  1. 打开 GLSL 文件。
  2. 编码 -> 转换为 ANSI。 (请注意,仅点击“使用 ANSI 编码”不会删除字符)
  3. 保存文件。

上面的代码还应该去除其他容易混淆 GLSL 解析器(和一般的 C/C++)的字符。

您可以通知用户(/开发人员)文件在调试构建中加载时格式不正确。

关于c++ - 顶点着色器由于非 Ascii 字符而无法编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36241598/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com