Не могу получить что-нибудь, чтобы показать на экране в простой программе OpenGL только цвет фона - PullRequest
0 голосов
/ 29 ноября 2018

У меня было glCreateProgram() ошибка возврата 1282 раньше, но исправлено после удаления контекстных glfwWindowsHint вызовов.Но даже после этого на экране ничего не появляется!Вот мой код шейдера:

Shader.h

#pragma once

#include <iostream>
#include "file_utils.h"
#include "GL/glew.h"

class Shader {

private:
     GLuint shaderID;
     const char *vertPath;
     const char *fragPath;
public:
    Shader(const char *vertexPath, const char *fragmentPath);
    ~Shader();

    void enable() const;
    void disable() const;
private:
    GLuint load();

};

Shader.cpp

#include "shader.h"


Shader::Shader(const char *vertexPath, const char *fragmentPath)
{
    vertPath = vertexPath;
    fragPath = fragmentPath;

    shaderID = load();
}

Shader::~Shader()
{

    glDeleteProgram(shaderID);
}


GLuint Shader::load()
{

    GLuint program = glCreateProgram();
    GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
    GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);



    std::string g_vert = FileUtils::readFile(vertPath);
    std::string g_frag = FileUtils::readFile(fragPath);

    const char *vertSource = g_vert.c_str();
    const char *fragSource = g_frag.c_str();


    glShaderSource(vertex, 1, &vertSource, NULL);
    glCompileShader(vertex);


    GLchar infoL[1024];
    GLint result;
    glGetShaderiv(vertex, GL_COMPILE_STATUS, &result);
    if (result == GL_FALSE)
    {
        glGetShaderInfoLog(vertex, sizeof(infoL), 0, infoL);
        std::cout << "ERROR COMPLING VERTEX SHADER: " << infoL << std::endl;
        glDeleteShader(vertex);
        return 0;
    }

    glShaderSource(fragment, 1, &fragSource, NULL);
    glCompileShader(fragment);

    glGetShaderiv(fragment, GL_COMPILE_STATUS, &result);
    if (result == GL_FALSE)
    {
        glGetShaderInfoLog(fragment, sizeof(infoL), 0, infoL);
        std::cout << "ERROR COMPLING FRAGMENT SHADER: " << infoL << std::endl;
        glDeleteShader(fragment);
        return 0;
    }

    glAttachShader(program, vertex);
    glAttachShader(program, fragment);

    glLinkProgram(program);
    glValidateProgram(program);

    glDeleteShader(vertex);
    glDeleteShader(fragment);

    return program;
}



void Shader::enable() const
{

    glUseProgram(shaderID);

}

void Shader::disable() const
{
    glUseProgram(0);
}

vertex.glsl

#version 330 core


layout (location = 0) in vec4 position;


uniform mat4 pr_matrix;
uniform mat4 vw_matrix = mat4(1.0);
uniform mat4 ml_matrix = mat4(1.0);


void main()
{
   gl_Position = position;
}

фрагмент.glsl

#version 330 core


layout (location = 0) out vec4 color;


void main()
{
  color = vec4(1.0, 0.0, 1.0, 1.0);
}

И, наконец, главное:

#include <iostream>

#include "WindowCreation.h"
#include "Maths.h"
#include "shader.h"





const int SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600; 


int main(){

    WindowCreation *mainWindow = new WindowCreation();




    if (mainWindow->createWindow(&SCREEN_WIDTH, &SCREEN_HEIGHT, "GoldSpark Engine") == 0)
    {
        glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    }
    else
    {
        cout << "Could not create window. EXITING..." << endl;
        return 1;
    }


    GLfloat vertices[] = {
       -0.5f, -0.5f,  0.0f,
       -0.5f,  0.5f,  0.0f,
       0.5f,  0.5f,   0.0f,
        0.5f,  0.5f,  0.0f,
        0.5f,  -0.5f, 0.0f, 
        -0.5f, -0.5f, 0.0f
    };

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);


    GLuint vbo = 0;

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);


    Shader shaders("resources/shaders/vertex.glsl", "resources/shaders/fragment.glsl");
    shaders.enable();


    while(!mainWindow->getShouldClose())
    {

        mainWindow->clear();


        glDrawArrays(GL_TRIANGLES, 0, 6);


        mainWindow->update();


    }
    shaders.disable();

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    delete mainWindow; 

    return 0;
}

WindowCreation.h

#pragma once

#include <iostream>

#include "GL/glew.h"
#include "GLFW/glfw3.h"


using namespace std;

class WindowCreation
{
public:
    int bufferWidth, bufferHeight;

    WindowCreation();
    ~WindowCreation();

    bool getShouldClose() { return glfwWindowShouldClose(window); }
    void createCallBacks(); 


    GLfloat getXChange() {
        GLfloat xCh = xChange;
        xChange = 0.0f;
        return xCh;
    }
    GLfloat getYChange() {
        GLfloat yCh = yChange;
        yChange = 0.0f;
        return yCh;
    }
    bool *getKeyPress() { return keys; }

    void update() {

        glfwPollEvents();
        glClear(GL_COLOR_BUFFER_BIT);
    }

    void clear() {

        glfwSwapBuffers(window);

    }

    int createWindow(const int *screenWidth, const int *screenHeight, const char* title); // ovdje pravimo sve sto treba da se prozor pojavi
    GLFWwindow *getWindow() { return window; }

private:
    GLFWwindow *window;
    bool firstTime; 
    bool keys[1024]; 

    GLfloat lastX, lastY, xChange, yChange;

    static void handleKeyboard(GLFWwindow* window, int key, int code, int action, int mode);
    static void handleMouse(GLFWwindow* window, double xPos, double yPos); 


};

WindowCreation.cpp

#include "WindowCreation.h"



WindowCreation::WindowCreation()
{

    //sve na 0 postavimo prvo
    for (size_t i = 0; i < 1024; i++)
    {
        keys[i] = 0;
    }


    xChange = 0.0f;
    yChange = 0.0f;
    firstTime = true;

}

void WindowCreation::createCallBacks()
{
    glfwSetKeyCallback(getWindow(), handleKeyboard);
    glfwSetCursorPosCallback(getWindow(), handleMouse);
}

 void WindowCreation::handleKeyboard(GLFWwindow* window, int key, int code, int action, int mode)
{




     WindowCreation *thisWindow = static_cast<WindowCreation*>(glfwGetWindowUserPointer(window));

     if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
     {
         glfwSetWindowShouldClose(thisWindow->window, GLFW_TRUE);
     }

     if (key >= 0 && key <= 1024)
     {

         if (action == GLFW_PRESS)
         {
            thisWindow->keys[key] = true;
         }
         else if (action == GLFW_RELEASE)
         {
             thisWindow->keys[key] = false;
         }


     }


}



 void WindowCreation::handleMouse(GLFWwindow* window, double xPos, double yPos)
{
     WindowCreation *thisWindow = static_cast<WindowCreation*>(glfwGetWindowUserPointer(window));

     if (thisWindow->firstTime)
     {
         thisWindow->lastX = xPos;
         thisWindow->lastY = yPos;
         thisWindow->firstTime = false;
     }


     thisWindow->xChange = xPos - thisWindow->lastX;
     thisWindow->yChange = thisWindow->lastY - yPos;

     thisWindow->lastX = xPos;
     thisWindow->lastY = yPos;

}





int WindowCreation::createWindow(const int *screenWidth,const int *screenHeight, const char* title)
{

        bufferWidth = 0;
        bufferHeight = 0; 



    if (!glfwInit()) // inicijalizujemo glfw
    {

        cout << "Could not initialize glfw." << endl;
        glfwTerminate();
        return 1;

    }

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



    window = glfwCreateWindow(*screenWidth, *screenHeight, title, NULL, NULL);

    glfwGetFramebufferSize(window, &bufferWidth, &bufferHeight); 

    if (!window)
    {
        cout << "Window could not be created." << endl;
        system("pause");
        glfwDestroyWindow(window);
        glfwTerminate();
        return 1;
    }
    glfwMakeContextCurrent(window); 




    if (glewInit() != GLEW_OK)
    {
        cout << "Could not initialize GLEW";
        system("pause");
        glfwDestroyWindow(window);
        glfwTerminate();
        return 1;
    }

    glewExperimental = true; 



    glViewport(0, 0, bufferWidth, bufferHeight); 



    glfwSetWindowUserPointer(window, this); 
    createCallBacks(); 




    return 0;

}


WindowCreation::~WindowCreation() 
{

    glfwDestroyWindow(window);
    glfwTerminate();


    for (size_t i = 0; i < 1024; i++)
    {
        keys[i] = 0;
    }

    window = nullptr;
    xChange = 0.0f;
    yChange = 0.0f;

    lastX = 0.0f;
    lastY = 0.0f;

}

Понятия не имею, что я тут не так сделал,Это очень просто, как вы можете видеть, и шейдерный код должен быть запущен.Я проверил строки загрузчиков файлов, которые он возвращает, и они верны, как в этих .glsl файлах.

В функции mainWindow->update() - glfwSwapBuffers(window), а в функции mainWindow->clear() -по порядку: glClear(GL_COLOR_BUFFER_BIT); glfwPollEvents();

Также эти информационные журналы ничего не возвращают.Окно действительно появляется, но все синее, в середине нет квадрата.

Ответы [ 3 ]

0 голосов
/ 30 ноября 2018

Обновление: теперь вы предоставили код WindowCreation, проверьте ваш метод WindowCreation-> update, где вы вызываете glClear, удалите вызов glClear, и вы увидите ваш визуализированный прямоугольник.

Как отмечено в комментариях, которые вы не предоставиливесь код, необходимый для создания окна, и, как сказал Робтеблок, вы не создали массив вершин, ниже приведена рабочая смесь вашего основного кода с учебным кодом для создания окна и рендеринга треугольников из http://www.opengl -tutorial.org /beginners-tutorials / tutorial-1-открытие-a-window / , который успешно отображает квадрат и использует ваш класс Shader, после изменения, чтобы обойти отсутствующий код File_Utils.Скомпилировано и проверено в Visual Studio 2017 для Windows 10.

#include "shader.h"
#include "GL/glew.h"
#include "GLFW/glfw3.h"

GLFWwindow* window;

int main(void)
{
    // Initialise GLFW
    if (!glfwInit())
    {
        fprintf(stderr, "Failed to initialize GLFW\n");
        getchar();
        return -1;
    }

    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // Open a window and create its OpenGL context
    window = glfwCreateWindow(1024, 768, "Tutorial 02 - Purple Square", NULL, NULL);
    if (window == NULL) {
        fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n");
        getchar();
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // Initialize GLEW
    glewExperimental = true; // Needed for core profile
    if (glewInit() != GLEW_OK) {
        fprintf(stderr, "Failed to initialize GLEW\n");
        getchar();
        glfwTerminate();
        return -1;
    }

    // Ensure we can capture the escape key being pressed below
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

    // Dark blue background
    glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    // Create and compile our GLSL program from the shaders
    Shader shader("vertex.glsl", "fragment.glsl");


    static const GLfloat g_vertex_buffer_data[] = {
                -0.5f, -0.5f,  0.0f,
                -0.5f,  0.5f,  0.0f,
                0.5f,  0.5f,   0.0f,
                0.5f,  0.5f,  0.0f,
                0.5f,  -0.5f, 0.0f,
                -0.5f, -0.5f, 0.0f
            };

    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

    do {

        // Clear the screen
        glClear(GL_COLOR_BUFFER_BIT);

        // Use our shader
        //glUseProgram(programID);
        shader.enable();

        // 1rst attribute buffer : vertices
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glVertexAttribPointer(
            0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  // size
            GL_FLOAT,           // type
            GL_FALSE,           // normalized?
            0,                  // stride
            (void*)0            // array buffer offset
        );

        // Draw the square !
        glDrawArrays(GL_TRIANGLES, 0, 6); // 

        glDisableVertexAttribArray(0);

        // Swap buffers
        glfwSwapBuffers(window);
        glfwPollEvents();

    } // Check if the ESC key was pressed or the window was closed
    while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
        glfwWindowShouldClose(window) == 0);

    // Cleanup VBO
    glDeleteBuffers(1, &vertexbuffer);
    glDeleteVertexArrays(1, &VertexArrayID);

    shader.disable();
    shader.~Shader();

    // Close OpenGL window and terminate GLFW
    glfwTerminate();

    return 0;
}
0 голосов
/ 07 декабря 2018

Ну, видимо, все время у меня были неправильные индексы вершин.Ницца!Он даже не отображался при использовании старого рисунка opengl, который был glBegin() и т.д ... glClearColor показывал цвет, но треугольник не рисовал только потому, что я положил минус на вершину, которая должна была быть UP.

0 голосов
/ 29 ноября 2018

Пока вы настраиваете программу для использования (судя по всему), вы не устанавливаете какие-либо унифицированные матричные параметры в программе.Вершинный шейдер не может преобразовать ваши вершины в результате.

Как уже упоминалось, всегда проверяйте ошибки GL вашей программы (или включайте профиль отладки и используйте более новый API отладки ).Как минимум, у вас должно быть что-то вроде этого:

void printError(int err, const char* str, const char* file, const int line)
{
  std::cout << "gl_error: " << str << ": " << file << "." << line << " > ";
  switch(err) 
  {
  case GL_INVALID_ENUM: std::cout << "GL_INVALID_ENUM" << std::endl;
  case GL_INVALID_VALUE: std::cout << "GL_INVALID_VALUE" << std::endl;
  case GL_INVALID_OPERATION: std::cout << "GL_INVALID_OPERATION" << std::endl;
  case GL_INVALID_FRAMEBUFFER_OPERATION: std::cout << "GL_INVALID_FRAMEBUFFER_OPERATION" << std::endl;
  case GL_OUT_OF_MEMORY: std::cout << "GL_OUT_OF_MEMORY" << std::endl;
  case GL_STACK_UNDERFLOW: std::cout << "GL_STACK_UNDERFLOW" << std::endl;
  case GL_STACK_OVERFLOW: std::cout << "GL_STACK_OVERFLOW" << std::endl;
  default: break;
  }
}

#define CHECK_GL(X) X; { \
   int __err = glGetError(); \
   if(__err != GL_NO_ERROR) printError(__err, #X, __FILE__, __LINE__); \
}

, которое вы можете использовать в своих вызовах GL следующим образом:

CHECK_GL(glDeleteProgram(1, &prog));
...