2017-12-17 82 views
4

OpenGL 프로젝트의 쉐이더가 컴파일되지 않습니다. CLion을 사용하여 우분투 16.04 LTS를 사용하고 있습니다. 해결책을 찾지 못했습니다. 그래서 여기 묻는 것입니다.OpenGL 쉐이더가 컴파일되지 않습니다.

다음
#ifndef SHADER_H 
#define SHADER_H 

#include <string> 
#include <fstream> 
#include <sstream> 
#include <iostream> 

#include <GL/glew.h> 
#include <cstring> 

class Shader 
{ 
public: 
    GLuint Program; 
    // Constructor generates the shader on the fly 
    Shader(const GLchar *vertexPath, const GLchar *fragmentPath) 
    { 
     // 1. Retrieve the vertex/fragment source code from filePath 
     std::string vertexCode; 
     std::string fragmentCode; 
     std::ifstream vShaderFile; 
     std::ifstream fShaderFile; 
     // ensures ifstream objects can throw exceptions: 
     vShaderFile.exceptions (std::ifstream::badbit); 
     fShaderFile.exceptions (std::ifstream::badbit); 
     try 
     { 
      // Open files 
      vShaderFile.open(vertexPath); 
      fShaderFile.open(fragmentPath); 
      std::stringstream vShaderStream, fShaderStream; 
      // Read file's buffer contents into streams 
      vShaderStream << vShaderFile.rdbuf(); 
      fShaderStream << fShaderFile.rdbuf(); 
      // close file handlers 
      vShaderFile.close(); 
      fShaderFile.close(); 
      // Convert stream into string 
      vertexCode = vShaderStream.str(); 
      fragmentCode = fShaderStream.str(); 
     } 
     catch (std::ifstream::failure e) 
     { 
      std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; 
     } 
     const GLchar *vShaderCode = vertexCode.c_str(); 
     const GLchar *fShaderCode = fragmentCode.c_str(); 
     // 2. Compile shaders 
     GLuint vertex, fragment; 
     GLint success; 
     GLchar infoLog[512]; 
     // Vertex Shader 
     vertex = glCreateShader(GL_VERTEX_SHADER); 
     glShaderSource(vertex, 1, &vShaderCode, NULL); 
     glCompileShader(vertex); 
     // Print compile errors if any 
     glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); 
     if (!success) 
     { 
      glGetShaderInfoLog(vertex, 512, NULL, infoLog); 
      std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; 
     } 
     // Fragment Shader 
     fragment = glCreateShader(GL_FRAGMENT_SHADER); 
     glShaderSource(fragment, 1, &fShaderCode, NULL); 
     glCompileShader(fragment); 
     // Print compile errors if any 
     glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); 
     if (!success) 
     { 
      glGetShaderInfoLog(fragment, 512, NULL, infoLog); 
      std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; 
     } 
     // Shader Program 
     this->Program = glCreateProgram(); 
     glAttachShader(this->Program, vertex); 
     glAttachShader(this->Program, fragment); 
     glLinkProgram(this->Program); 
     // Print linking errors if any 
     glGetProgramiv(this->Program, GL_LINK_STATUS, &success); 
     if (!success) 
     { 
      glGetProgramInfoLog(this->Program, 512, NULL, infoLog); 
      std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; 
     } 
     // Delete the shaders as they're linked into our program now and no longer necessery 
     glDeleteShader(vertex); 
     glDeleteShader(fragment); 

    } 
    // Uses the current shader 
    void Use() 
    { 
     glUseProgram(this->Program); 
    } 
}; 

#endif 

내 core.vs입니다 :

#include <iostream> 

// GLEW 
#define GLEW_STATIC 
#include <GL/glew.h> 

// GLFW 
#include <GLFW/glfw3.h> 

// Other includes 
#include "Shader.h" 

// Window dimensions 
const GLuint WIDTH = 800, HEIGHT = 600; 

// The MAIN function, from here we start the application and run the game loop 
int main() 
{ 
    // Init GLFW 
    glfwInit(); 

    // Set all the required options for GLFW 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 

    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); 

    // Create a GLFWwindow object that we can use for GLFW's functions 
    GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); 

    int screenWidth, screenHeight; 
    glfwGetFramebufferSize(window, &screenWidth, &screenHeight); 

    if (nullptr == window) 
    { 
     std::cout << "Failed to create GLFW window" << std::endl; 
     glfwTerminate(); 

     return EXIT_FAILURE; 
    } 

    glfwMakeContextCurrent(window); 

    // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions 
    glewExperimental = GL_TRUE; 
    // Initialize GLEW to setup the OpenGL Function pointers 
    if (GLEW_OK != glewInit()) 
    { 
     std::cout << "Failed to initialize GLEW" << std::endl; 
     return EXIT_FAILURE; 
    } 

    // Define the viewport dimensions 
    glViewport(0, 0, screenWidth, screenHeight); 

    // Build and compile our shader program 
    Shader ourShader("core.vs", "core.frag"); 


    // Set up vertex data (and buffer(s)) and attribute pointers 
    GLfloat vertices[] = 
      { 
        // Positions   // Colors 
        0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Right 
        -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // Bottom Left 
        0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // Top 
      }; 
    GLuint VBO, VAO; 
    glGenVertexArrays(1, &VAO); 
    glGenBuffers(1, &VBO); 
    // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). 
    glBindVertexArray(VAO); 

    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

    // 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); 

    glBindVertexArray(0); // Unbind VAO 

    // Game loop 
    while (!glfwWindowShouldClose(window)) 
    { 
     // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions 
     glfwPollEvents(); 

     // Render 
     // Clear the colorbuffer 
     glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 
     glClear(GL_COLOR_BUFFER_BIT); 

     // Draw the triangle 
     ourShader.Use(); 
     glBindVertexArray(VAO); 
     glDrawArrays(GL_TRIANGLES, 0, 3); 
     glBindVertexArray(0); 

     // Swap the screen buffers 
     glfwSwapBuffers(window); 
    } 

    // Properly de-allocate all resources once they've outlived their purpose 
    glDeleteVertexArrays(1, &VAO); 
    glDeleteBuffers(1, &VBO); 

    // Terminate GLFW, clearing any resources allocated by GLFW. 
    glfwTerminate(); 

    return EXIT_SUCCESS; 
} 

Shader.h 코드 :

ATTENTION: default value of option force_s3tc_enable overridden by environment. 
ERROR::SHADER::VERTEX::COMPILATION_FAILED 
0:1(1): error: syntax error, unexpected $end 

ERROR::SHADER::FRAGMENT::COMPILATION_FAILED 
0:1(1): error: syntax error, unexpected $end 

ERROR::SHADER::PROGRAM::LINKING_FAILED 
error: linking with uncompiled shadererror: linking with uncompiled shader 

가 여기 내 MAIN.CPP 코드입니다 : 여기

내 errorlist입니다

#version 330 core 
layout (location = 0) in vec3 position; 
layout (location = 1) in vec3 color; 
layout (location = 2) in vec2 texCoord; 

out vec3 ourColor; 
out vec2 TexCoord; 

void main() 
{ 
    gl_Position = vec4(position, 1.0f); 
    ourColor = color; 
    // We swap the y-axis by substracing our coordinates from 1. This is done because most images have the top y-axis inversed with OpenGL's top y-axis. 
    // TexCoord = texCoord; 
    TexCoord = vec2(texCoord.x, 1.0 - texCoord.y); 
} 

... 그리고 core.frag :

#version 330 core 
in vec3 ourColor; 
in vec2 TexCoord; 

out vec4 color; 

// Texture samplers 
uniform sampler2D ourTexture1; 

void main() 
{ 
// Linearly interpolate between both textures (second texture is only slightly combined) 
color = texture(ourTexture1, TexCoord); 
} 

나는 또한 내 CMakeLists.txt을 첨부했습니다. 도움이 되었으면합니다.

cmake_minimum_required(VERSION 3.9) 
project(STUDY_GL) 

set(CMAKE_CXX_STANDARD 11) 

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -pthread -fpermissive") 

find_package (OpenGL REQUIRED) 
find_package (GLUT REQUIRED) 
find_package (glfw3 REQUIRED) 
find_library (glew REQUIRED) 
find_library (glad REQUIRED) 


include_directories(${/usr/include/GLFW/}) 
include_directories(${/usr/include/GL/}) 


file(GLOB SOURCE_FILES 
     *.cpp 
     *.h 
     ) 

add_executable(main.cpp ${SOURCE_FILES} Shader.h) 

target_link_libraries (main.cpp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${GLFW3_LIBRARIES} -lGL -lglfw -lglut -lGLEW) 

프로젝트 내에 SOIL2 디렉토리가 있습니다. 여기에 link이 있습니다.

+0

그리고 GLSL 버전 선언 후에'core'를 쓰지 않으면 어떻게 될까요? 내가 그런 선언을 본 적이 없기 때문에 묻고. – Matso

답변

3

일반적으로 코드는 괜찮지 만 std::ifstream::failbitstd::ios::exceptions으로 전달해야합니다. std::ifstream::open에 오류가 발생하면 오류 비트 상태 플래그가 설정됩니다.

vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); 
fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit); 
try 
{ 
    vShaderFile.open(vertexPath); 
    fShaderFile.open(fragmentPath); 
    ..... 
} 
catch (std::ifstream::failure e) 
{ 
    std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; 
} 

작업 디렉토리가 올바르지 않습니다. 디버그 이유로 쉐이더 파일에 대한 절대 파일 경로를 사용하십시오.
쉐이더 소스 파일에 액세스 할 수없고 코드에서 예외가 발생하지 않으면 빈 문자열을 컴파일하려고합니다. 이로 인해 오류 메시지가 발생합니다. 그런데


, 당신은 당신의 질문에 게시 코드 조각의 모든 텍스처를 사용하지 않기 때문에, 당신이 당신의 조각 쉐이더에 다음과 같은 변경을 수행해야합니다

// color = texture(ourTexture1, TexCoord); <--- skip 
color = vec4(ourColor,1.0);    <--- add 
+0

'badbit'만 통과하면 문자열이 비어 있다고 생각할 때 맞습니까? – Matso

+0

@Matso 예, 당신은 – Rabbid76

+0

대단히 감사합니다! 그것은 작동합니다! – yk4r2

1

표시되는 오류가 일반적으로 발생 최종 끝에 null 종결자가없는 셰이더 소스가 소스 문자열 길이를 지정하지 않고 glShaderSource로 전달 될 때. 일반적인 파일에는 일반적으로 널 종결자가 포함되어 있지 않으므로 OpenGL은 소스 문자열의 끝을지나 읽습니다.

해결 방법은 셰이더 원본 문자열의 정확한 길이를 전달하는 것입니다.

+0

'std :: string :: c_str'가 항상 null로 끝나는 문자열을 반환하지 않는가? – Rabbid76

+0

@ Rabbid76 : 그래야합니다. – datenwolf

+0

질문의 코드에서 소스 코드는'const GLchar * vShaderCode = vertexCode.c_str()'에 의해 얻어집니다. – Rabbid76