2017-12-27 43 views
1

私は現在、SDL2だけで時間を費やしてOpenGLをC++で使用する方法を学び、画面上に三角形を表示するのに苦労しています。私は一連のチュートリアルに従っていて、すべての仕組みを深く理解しようとしています。私は画面上に表示する単純な固体色の三角形を得ることに成功しましたが、すべての頂点に異なる色を与えようとすると、背景を除いて何も表示されません。最新のOpenGL + SDL2トライアングルが表示されない

#include <iostream> 
#include <string> 

#include <GL/glew.h> 
#include <GL/GLU.h> 
#include <SDL.h> 
#include <SDL_opengl.h> 

//*************************************************************************** 
// The Width of the screen 
//*************************************************************************** 
const GLuint SCREEN_WIDTH = 800; 

//*************************************************************************** 
// The height of the screen 
//*************************************************************************** 
const GLuint SCREEN_HEIGHT = 600; 

bool success = GL_TRUE; 

const GLchar* vertexShaderSource = "#version 330 core\n" 
"layout (location = 0) in vec3 position;\n" 
"layout (location = 1) in vec3 color;\n" 
"out vec3 ourColor;\n" 
"void main()\n" 
"{\n" 
"gl_Position = vec4(position, 1.0);\n" 
"ourColor = color;\n" 
"}\0"; 

const GLchar* fragmentShaderSource = "#version 330 core\n" 
"in vec3 ourColor;\n" 
"out vec4 color;\n" 
"void main()\n" 
"{\n" 
"color = vec4(ourColor, 1.0f);\n" 
"}\n\0"; 

bool quit; 

int main(int argc, char *argv[]) 
{ 
    //*********************************************************************** 
    // Initialize SDL 
    //*********************************************************************** 
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0) 
    { 
     std::cout << "SDL could not initialize!SDL Error :" << 
      std::string(SDL_GetError()); 

     return EXIT_FAILURE; 
    } 
    else 
    { 
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); 
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); 
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 
      SDL_GL_CONTEXT_PROFILE_CORE); 

     SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); 
     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 

     //******************************************************************* 
     //The window we'll be rendering to 
     //******************************************************************* 
     SDL_Window *window = SDL_CreateWindow("Triangle", 
      SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, 
      SCREEN_HEIGHT, SDL_WINDOW_SHOWN | 
      SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); 

     if (window == NULL) 
     { 
      std::cout << "Window could not be created!SDL_Error: " << 
       std::string(SDL_GetError()) << std::endl; 

      return EXIT_FAILURE; 
     } 

     //******************************************************************* 
     //OpenGL context 
     //******************************************************************* 
     SDL_GLContext context = SDL_GL_CreateContext(window); 

     //******************************************************************* 
     // Set the required callback functions 
     //******************************************************************* 
     SDL_Event windowEvent; 

     //******************************************************************* 
     //Use OpenGL 3.3 
     //******************************************************************* 

     //******************************************************************* 
     // 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 
     //******************************************************************* 
     GLenum glewError = glewInit(); 
     if (GLEW_OK != glewError) 
     { 
      std::cout << "Failed to initialize GLEW: " << 
       glewGetErrorString(glewError) << std::endl; 

      return EXIT_FAILURE; 
     } 

     glEnable(GL_CULL_FACE); 
     glEnable(GL_BLEND); 
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 


     //******************************************************************* 
     // Build and compile our shader program 
     // Vertex shader 
     //******************************************************************* 
     GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); 
     glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); 
     glCompileShader(vertexShader); 

     //******************************************************************* 
     // Check for compile time errors 
     //******************************************************************* 
     GLint success; 
     GLchar infoLog[512]; 
     glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); 
     if (!success) 
     { 
      glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); 
      std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED: " << 
       infoLog << std::endl; 
     } 

     //******************************************************************* 
     // Fragment shader 
     //******************************************************************* 
     GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
     glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); 
     glCompileShader(fragmentShader); 

     //******************************************************************* 
     // Check for compile time errors 
     //******************************************************************* 
     glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); 
     if (!success) 
     { 
      glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); 
      std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED: " << 
       infoLog << std::endl; 
     } 

     //******************************************************************* 
     // Link shaders 
     //******************************************************************* 
     GLuint shaderProgram = glCreateProgram(); 
     glAttachShader(shaderProgram, vertexShader); 
     glAttachShader(shaderProgram, fragmentShader); 
     glLinkProgram(shaderProgram); 

     //******************************************************************* 
     // Check for linking errors 
     //******************************************************************* 
     glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); 
     if (!success) { 
      glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); 
      std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED: " << infoLog << std::endl; 
     } 
     glDeleteShader(vertexShader); 
     glDeleteShader(fragmentShader); 

     //******************************************************************* 
     // 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 
     }; 

     GLfloat colors[] = { 
      1.0f, 0.0f, 0.0f, 1.0f, 
      0.0f, 1.0f, 0.0f, 1.0f, 
      0.0f, 0.0f, 1.0f, 1.0f 
     }; 

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

     //******************************************************************* 
     // Note that this is allowed, the call to glVertexAttribPointer 
     // registered VBO as the currently bound vertex buffer object so 
     // afterwards we can safely unbind 
     //******************************************************************* 
     glBindBuffer(GL_ARRAY_BUFFER, 0); 

     //******************************************************************* 
     // Unbind VAO (it's always a good thing to unbind any buffer/array to 
     // prevent strange bugs) 
     //******************************************************************* 
     glBindVertexArray(0); 

     //******************************************************************* 
     // DeltaTime variables 
     //******************************************************************* 
     GLdouble deltaTime = 0.0f; 
     Uint64 lastFrame = 0L; 
     Uint64 currentFrame = SDL_GetPerformanceCounter(); 

     quit = false; 

     while (!quit) 
     { 
      //*************************************************************** 
      // Calculate delta time 
      //*************************************************************** 
      lastFrame = currentFrame; 
      currentFrame = SDL_GetPerformanceCounter(); 

      deltaTime = ((currentFrame - lastFrame) * 1000/
       (GLdouble)SDL_GetPerformanceFrequency()); 

      double tmpDeltaTime = deltaTime; 

      //std::cout << "Hello 1 - deltaTime: " << std::to_string(deltaTime) << 
      // std::endl; 

      if (SDL_PollEvent(&windowEvent)) 
      { 
       if (windowEvent.type == SDL_QUIT) 
       { 
        quit = true; 
       } 
      } 

      //*************************************************************** 
      // Clear the colorbuffer and render 
      //*************************************************************** 
      glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 
      glClear(GL_COLOR_BUFFER_BIT); 

      //*************************************************************** 
      // Draw our first triangle 
      //*************************************************************** 
      glUseProgram(shaderProgram); 
      glBindVertexArray(VAO); 
      glDrawArrays(GL_TRIANGLES, 0, 3); 
      glBindVertexArray(0); 

      //*************************************************************** 
      // draw OpenGL: Swap the screen buffers 
      //*************************************************************** 
      SDL_GL_SwapWindow(window); 
     } 

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

     SDL_GL_DeleteContext(context); 
     SDL_DestroyWindow(window); 
     SDL_Quit(); 
    } 

    return EXIT_SUCCESS; 
} 

私は同じプロジェクトでOpenGLとSDL2の両方を使用しようとしています。このコードを実行すると、コンソールにエラーは表示されず、緑色の背景が表示されますが、三角形は表示されません。私はいくつかの "シェイダーの仕組み"のビデオを見直して、何も見逃してしまったかどうかを確認しましたが、問題の原因を見つけることができませんでした。私は何を取りこぼしたか?

答えて

3

あなたのプログラムは、エラーを発生させない有効なGLプログラムです。それは正しく背景色を描画し、正しく三角形を描画しません。

GLのデフォルトの前面の向きは反時計回り(GL_CCW)です。あなたが定義する三角形は、クリップ空間(およびそれに続くすべてのスペースNDCとウィンドウスペース)で時計回りに向きが決められています。その結果、

glEnable(GL_CULL_FACE); 

は、ラスタライズ前に三角形をカリングの効果があります。三角形を見るには、無効にするか(デフォルトでは無効にしてください)GL_CULL_FACE、または前面の表記法をglFrontFace(GL_CW)で時計回りに設定するか、またはglCullFace(GL_FRONT)に設定して、配列内の任意の2つの頂点を交換するだけです。

+0

ありがとう、これは問題を解決し、何かを学びました! – slugz

関連する問題