返回语句被忽略

时间:2017-03-21 12:31:11

标签: c windows

为未来的读者

不要厌倦代码。它会把你变成一个小小的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语句。 Output 1

这是LoadGLSLFromFile("glsl", GL_VERTEX_SHADER);的控制台输出 注意:第3行不应该发生,因为之前有一个return语句。 Output 2

有一个特别阻止进一步执行的返回语句,但它仍然执行。我对这种行为感到非常困惑,因为据我所知,返回意味着&#34;立即回到那个叫你的线路上。

非常感谢任何和所有的帮助。

1 个答案:

答案 0 :(得分:1)

您说返回值被忽略。这正是您的代码正在做的事情:

GLuint LoadAllShaders() {

    // return value is ignored
    LoadGLSLFromFile("glsl", GL_VERTEX_SHADER);


    GLuint VShader = glCreateShader(GL_VERTEX_SHADER);

因为您没有检查返回值,所以没有什么可以阻止您的代码继续。

也许您会将returnexit()混淆。 return语句从函数返回一个值,以便调用函数可以决定如何继续。 exit函数导致程序终止,传入的值是程序的返回值。

如果您希望程序退出,则应使用exit。如果没有,那么你需要检查上面代码中的返回值并采取相应的行动。

编辑:

这就是MCVE如此重要的原因。

发布主要代码后,问题是您要拨打LoadGLSLFromFile两次。您首先直接从main拨打电话。然后main调用LoadAllShaders,再次调用LoadGLSLFromFile

所以“Wurbulgurb”会在第一次调用时打印,而第二次调用时会打印“尝试加载无效文件”或“文件缓冲区大小”。