不要厌倦代码。它会把你变成一个小小的dink。
我的问题是我有两个单独的输出似乎相互碰撞。一个超出了返回声明,因此令人震惊的是代码正在被执行。但是,我没有想过使用Visual Studio的搜索功能检查每个其他文件,看看是否有其他原因我得到了输出。据我所知,只有一次调用LoadGLSLFromFile函数,实际上只有两次。
结果是我的极度沮丧,因为我肯定没有其他调用该函数,并且不知何故必须对我的代码进行优化,否则要么搞砸了函数的顺序,或者,return语句不能正常运行(无论出于何种原因)。
如果您要发布问题,我建议您重新评估被视为相关的问题"码。你来到这里是因为你毕竟没有看到别人能做到的事情。
如果您阅读了这些评论,您会看到StoryTeller试图让我知道我假设发生的事情确实不可能,而且我的调试方法不正确。 StoryTeller,如果你正在读这篇文章,我真诚地道歉。
===============================
编辑2:请注意,我遇到的问题是当我告诉它时函数没有返回。它继续在返回之外执行,在同一个函数内,直到它击中第二个。
所以,我真的很想知道为什么会这样,但这是我的代码。因此,通常我所做的是检查严重故障,如果存在严重问题,我会返回一个已知的"错误"值。但是,在多个位置忽略返回,并且代码以错误的顺序执行。 (请参阅错误订单的第二张图片)
编辑:
我的问题是代码在return语句之外执行。
#include "Loader.h"
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/GL.h>
#include <GL/GLU.h>
#include <GLFW/glfw3.h>
static const GLchar * VSource[] = {
"#version 450 core\n"
"layout (location = 0) in vec4 offset;\n"
"layout (location = 1) in vec4 color;\n"
"out VS_OUT {\n"
" vec4 color;"
"} vs_out;\n"
"void main(void)\n"
"{\n"
" const vec4 vertices[3] = vec4[3](vec4(0.25, -0.25, 0.5, 1.0),\n"
" vec4(-0.25, -0.25, 0.5, 1.0),\n"
" vec4(0.25, 0.25, 0.5, 1.0));\n"
" gl_Position = vertices[gl_VertexID] + offset;\n"
" vs_out.color = color;"
"}\n"
};
static const GLchar* FSource[] = {
"#version 450 core\n"
"in VS_OUT {\n"
" vec4 color;\n"
"} fs_in;\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" color = fs_in.color;\n"
"}\n"
};
static const GLchar* TControlSource[] = {
"#version 450 core\n"
"layout (vertices = 3) out;\n"
"void main(void) {\n"
" if(gl_InvocationID == 0) {\n"
" gl_TessLevelInner[0] = 5.0;\n"
" gl_TessLevelOuter[0] = 5.0;\n"
" gl_TessLevelOuter[1] = 5.0;\n"
" gl_TessLevelOuter[2] = 5.0;\n"
" }\n"
" gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
"}"
};
GLuint LoadAllShaders() {
LoadGLSLFromFile("glsl", GL_VERTEX_SHADER);
GLuint VShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VShader, 1, VSource, NULL);
glCompileShader(VShader);
LogCompileStatus(VShader, "VShader");
GLuint FShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FShader, 1, FSource, NULL);
glCompileShader(FShader);
LogCompileStatus(FShader, "FShader");
GLuint TShader = glCreateShader(GL_TESS_CONTROL_SHADER);
glShaderSource(TShader, 1, TControlSource, NULL);
glCompileShader(TShader);
LogCompileStatus(TShader, "Tessellation Shader");
GLuint Program = glCreateProgram();
glAttachShader(Program, VShader);
glAttachShader(Program, FShader);
glAttachShader(Program, TShader);
glLinkProgram(Program);
glDeleteShader(VShader);
glDeleteShader(FShader);
glDeleteShader(TShader);
return Program;
}
void LogCompileStatus(GLuint Shader, char* ShaderName) {
// Checking compile status of VShader
if (ShaderName == NULL || sizeof(ShaderName) == 0)
ShaderName = ("Unnamed Shader with ID: %i" + (char)&Shader);
GLuint ShaderSuccess = GL_FALSE;
glGetShaderiv(Shader, GL_COMPILE_STATUS, &ShaderSuccess);
if (ShaderSuccess == GL_TRUE)
printf("%s successfully compiled\n", ShaderName);
else {
GLint LogLength;
glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &LogLength);
char* buffer = (char*)malloc(LogLength);
glGetShaderInfoLog(Shader, LogLength, NULL, buffer);
printf("%s failed to compile.\n%s\n", ShaderName, buffer);
free(buffer);
}
}
GLuint LoadGLSLFromFile(char* location, GLenum ShaderType) {
if (sizeof(location) < 6 || strstr(location, ".glsl") == NULL) {
fprintf(stderr, "Attempted to load invalid file.\n");
return 0;
}
switch (ShaderType) {
case(GL_COMPUTE_SHADER):
case(GL_VERTEX_SHADER):
case(GL_TESS_CONTROL_SHADER):
case(GL_TESS_EVALUATION_SHADER):
case(GL_GEOMETRY_SHADER):
case(GL_FRAGMENT_SHADER):
break;
default:
fprintf(stderr, "Invalid Shadertype\n");
break;
}
FILE* shaderFile = fopen(location, "r");
if (shaderFile == NULL) {
fprintf(stderr, "Wurbulgurb\n");
return 0;
}
size_t bufferSize = fseek(shaderFile, 0, SEEK_END);
printf("File Buffer size: %i\n", (int)bufferSize);
fclose(shaderFile);
/*
glShaderSource(shd, 1, VSource, NULL);
glCompileShader(shd);
LogCompileStatus(shd, "VShader");
*/
return 1;
}
主文件:
#include <stdio.h>
#include <stdlib.h>
#include <GL\glew.h>
#include <GL\GL.h>
#include <GL\GLU.h>
#include <GL\wglew.h>
#include <GLFW\glfw3.h>
#include "Loader.h"
#define CL_BUFFER (GLfloat[4]) { 0.3f, 0.3f, 0.3f, 1.0f }
int main(void);
void err(int error, const char * msg);
void keypress(GLFWwindow *window, int key, int scancode, int action, int mods);
static GLfloat attrib[] = { 0.0f, 0.0f, 0.5f, 1.0f };
int main(void) {
if (!glfwInit())
return -1;
GLFWwindow *window = glfwCreateWindow(1024, 768, "Fididdler", NULL, NULL);
glfwWindowHint(GLFW_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_VERSION_MINOR, 5);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
if (window == NULL)
return -1;
LoadGLSLFromFile("./Condoms.glsl", GL_VERTEX_SHADER);
glfwSetErrorCallback(err);
glfwSetKeyCallback(window, keypress);
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
return -1;
printf("GL Version String: %s \n", glGetString(GL_VERSION));
GLuint RProg = LoadAllShaders();
GLuint VAO;
glCreateVertexArrays(1, &VAO);
glBindVertexArray(VAO);
printf("Loading complete");
while (!glfwWindowShouldClose(window)) {
glClearBufferfv(GL_COLOR, 0, CL_BUFFER);
glUseProgram(RProg);
glVertexAttrib4fv(0, attrib);
glDrawArrays(GL_TRIANGLES, 0, 3);
/* End drawing logic*/
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteProgram(RProg);
glfwTerminate();
return 1;
}
void err(int error, const char * msg) {
printf("Error: %s", msg);
}
void keypress(GLFWwindow *window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
switch (key) {
case(GLFW_KEY_W):
attrib[1] += 0.01f;
printf("W pressed");
break;
case(GLFW_KEY_S):
attrib[1] -= 0.01f;
printf("S pressed");
break;
}
switch (key) {
case(GLFW_KEY_A):
attrib[0] -= 0.01f;
printf("A pressed");
break;
case(GLFW_KEY_D):
attrib[0] += 0.01f;
printf("D pressed");
break;
}
}
这是LoadGLSLFromFile("TessControl.glsl", GL_VERTEX_SHADER);
的控制台输出。注意:第3行不应该发生,因为之前有一个return语句。
这是LoadGLSLFromFile("glsl", GL_VERTEX_SHADER);
的控制台输出
注意:第3行不应该发生,因为之前有一个return语句。
有一个特别阻止进一步执行的返回语句,但它仍然执行。我对这种行为感到非常困惑,因为据我所知,返回意味着&#34;立即回到那个叫你的线路上。
非常感谢任何和所有的帮助。
答案 0 :(得分:1)
您说返回值被忽略。这正是您的代码正在做的事情:
GLuint LoadAllShaders() {
// return value is ignored
LoadGLSLFromFile("glsl", GL_VERTEX_SHADER);
GLuint VShader = glCreateShader(GL_VERTEX_SHADER);
因为您没有检查返回值,所以没有什么可以阻止您的代码继续。
也许您会将return
与exit()
混淆。 return
语句从函数返回一个值,以便调用函数可以决定如何继续。 exit
函数导致程序终止,传入的值是程序的返回值。
如果您希望程序退出,则应使用exit
。如果没有,那么你需要检查上面代码中的返回值并采取相应的行动。
编辑:
这就是MCVE如此重要的原因。
发布主要代码后,问题是您要拨打LoadGLSLFromFile
两次。您首先直接从main
拨打电话。然后main
调用LoadAllShaders
,再次调用LoadGLSLFromFile
。
所以“Wurbulgurb”会在第一次调用时打印,而第二次调用时会打印“尝试加载无效文件”或“文件缓冲区大小”。