2016-11-20 1 views
0

Soit je suis stupide ou incroyablement inexpérimenté (probablement les deux) mais je suis resté bloqué en dessinant un simple rectangle de couleur en utilisant opengl. Cela ne devrait pas être un problème puisque je viens de terminer un simple chargeur de modèle opengl (mais c'était mon premier projet, donc je n'ai fait que tout une fois avec référence). De toute façon rien ne se montre sauf le fond bleu. J'ai essayé de faire des classes simples pour les formes de base. Voici la classe de rectangle:Opengl Rectangle ne rendra pas

class AVRect{ 
private: 
    AVcolor Color; 
    GLuint VBO, VAO, EBO; 
    GLuint indices[6] = { // Note that we start from 0! 
     0, 1, 3, // First Triangle 
     1, 2, 3 // Second Triangle 
    }; 
public: 
    GLfloat geometry[12]; 
    AVRect(int Drawmode, GLfloat x, GLfloat y, GLfloat x2, GLfloat y2,GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4,GLfloat r,GLfloat b,GLfloat g,GLfloat a); 
    void Draw(Shader shader); 
}; 

Ne vous inquiétez pas pour la couleur. Je l'ai seulement mis dans la source mais il n'est pas utilisé ailleurs. Je vais l'implémenter dès que le rectangle fonctionnera avec une couleur fixe.

Source de la classe rect:

#include "stdafx.h" 
#include "Shapes.h" 

AVRect::AVRect(int Drawmode,GLfloat x, GLfloat y, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4, GLfloat r, GLfloat b, GLfloat g, GLfloat a) { 
    geometry[0] = x; 
    geometry[1] = y; 
    geometry[2] = 0.0f; 
    geometry[3] = x2; 
    geometry[4] = y2; 
    geometry[5] = 0.0f; 
    geometry[6] = x3; 
    geometry[7] = y3; 
    geometry[8] = 0.0f; 
    geometry[9] = x4; 
    geometry[10] = y4; 
    geometry[11] = 0.0f; 
    Color.r = r; 
    Color.b = b; 
    Color.g = g; 
    Color.a = a; 
    glGenVertexArrays(1, &VAO); 
    glGenBuffers(1, &VBO); 
    glGenBuffers(1, &EBO); 
    glBindVertexArray(VAO); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(geometry), geometry, Drawmode); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, Drawmode); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); 
    glEnableVertexAttribArray(0); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glBindVertexArray(0); 

} 

void AVRect::Draw(Shader shader) { 
    glUseProgram(shader.Program); 
    glBindVertexArray(VAO); 
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 
    glBindVertexArray(0); 
} 

Le principal est assez explicite:

// Bullethell.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include <GL/glew.h> 
#include <SDL.h> 
#include <SDL_opengl.h> 
#include <GLTextures.h> 
#include <Shaders.h> 
#include <ctime> 
#include "Shapes.h" 
#define HEIGHT 600 
#define WIDTH 600 

int main(int argc, char* args[]) 
{ 
    SDL_Window *window; 
    SDL_Renderer *renderer; 
    window = SDL_CreateWindow("BulletHell", 100, 100, HEIGHT, WIDTH, SDL_WINDOW_OPENGL); 
    SDL_GLContext glcontext = SDL_GL_CreateContext(window); 

    glewExperimental = GL_TRUE; 
    if (GLEW_OK != glewInit()) 
    { 
     // GLEW failed! 
     printf("GLEW INIT FAILED!"); 
    } 
    Shader basic("./shaders/colorTest/colorTest.vs", "./shaders/colorTest/colorTest.frag"); 
    AVRect test(GL_STATIC_DRAW,0.5f,0.5f,0.5f,-0.5f,-0.5f,-0.5f,0.5f,-0.5f,0.5f,0.9f,0.2f,0.5f); 
    int error = 0; 
    while (SDL_PollEvent(NULL)) 
    { 
     clock_t start = clock(); 
     glClearColor(0.2, 0.2, 0.5, 1); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     test.Draw(basic); 
     SDL_GL_SwapWindow(window); 
     error = glGetError(); 
     if (error != GL_NO_ERROR) 
      printf("GL ERROR:%d ", error); 
     while (((clock() - start) * 1000/CLOCKS_PER_SEC) <16) 
      ; 

     float MS = (float)((clock() - start) * 1000/CLOCKS_PER_SEC); 
     // Frames per seconds 
     float FPS = 1000.0f/MS; 
     //printf("%f \n",FPS); 
     // printf("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); 
    } 
    return 1; 
} 

La classe Shader est testé et fonctionne. Le shader est simple et devrait également fonctionner (ne transmet que des valeurs et assigne une couleur fixe). Je suis probablement juste aveugle parce que je ne peux pas voir l'erreur. S'il vous plaît aidez-moi sur celui-ci.


Voici la source Shader pour être complet:

#include "stdafx.h" 
#include "Shaders.h" 

Shader::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 Shader::Use() 
{ 
    glUseProgram(this->Program); 
} 
+0

J'ai ajouté la source à la publication principale. J'ai utilisé la même Source pour mon autre projet (un chargeur de modèle simple avec des textures et un éclairage de base) et cela a fonctionné aussi. – MoustacheSpy

Répondre

3

Vous dessinez des triangles dégénérés, donc pas de pixels seront rendus. Si vous regardez les coordonnées de votre « rectangle », espacées pour faciliter la lecture:

0.5f, 0.5f, 
0.5f, -0.5f, 
-0.5f, -0.5f, 
0.5f, -0.5f 

vous pouvez voir que le 2ème et le 4ème sommet ont les mêmes coordonnées. La disposition de vos sommets ressemble à ceci:

 0 

2  1/3 

Comparez cela avec vos indices:

0, 1, 3, // First Triangle 
1, 2, 3 // Second Triangle 

et vous verrez que les deux triangles sont dégénérés, parce que deux de leurs sommets sont les mêmes.

Le vous coordonne probablement voulu dire à utiliser sont:

0.5f, 0.5f, 
0.5f, -0.5f, 
-0.5f, -0.5f, 
-0.5f, 0.5f 

Je recommande effectivement d'utiliser l'orientation dans le sens antihoraire pour la géométrie, puisque c'est l'ordre d'enroulement par défaut en OpenGL. Même si cela n'a pas vraiment d'importance, à moins que vous n'ayez l'intention d'activer l'abattage.

+0

Merci l'homme! J'ai bien travaillé! – MoustacheSpy