Zeichnen von Pixel in OpenGL

Ich bin dabei, ein Computer-Grafik-Kurs an meiner Uni. Ich brauche zu implementieren-basic-line-drawing-algorithmen, die in modernen OpenGL(3.3+) zu zeichnen primitive auf dem Bildschirm. Hier ist die Funktion für den Bresenham - Linien-Algorithmus, den ich umsetzen will -

void bresenham(GLint xStart, GLint yStart, GLint xEnd, GLint yEnd) {
    if (!(xStart < xEnd)) {
    swap(xStart, xEnd);
    swap(yStart, yEnd); 
    }

    GLint dx = xEnd - xStart;
    GLint dy = yEnd - yStart;
    GLint p = 2 * dy - dx;

    GLint x = xStart;
    GLint y = yStart;
    setPixel(x,y);

    while (x < xEnd) {
        x += 1;
        if (p < 0)
            p += (2 * dy);
        else {
            p += (2 * (dy - dx));
            y += 1;
        setPixel(x,y);
        }
    }
}

Ich bin ratlos, wie realisieren Sie das setPixel() Funktion. Die meisten Antworten fand ich hier und anderswo mit älteren OpenGL-Funktionen -

void setPixel(int x, int y)
{
    glColor3f(0.0, 0.0, 0.0); //Set pixel to black  
    glBegin(GL_POINTS);
    glVertex2i(x, y); //Set pixel coordinates 
    glEnd();
    glFlush(); //Render pixel
}

Was ist das äquivalent Möglichkeit, dies zu tun in OpenGl 3.3+?
Angenommen, Sie können hinzufügen, die "Pixel" auf eine std::vector array, wie kann ich die Initialisierung des vertex-buffer-array-Daten zu speichern?

Einem anderen problem, das ich gestoßen bin, während Sie versuchen zu zeichnen einen Punkt mit GL_POINTS ist, dass durch clipping während der Konvertierung in normalisierten device-Koordinaten, die Punkte außerhalb des Intervalls [-1,1] in beide Richtungen zeigen nicht auf die Fenster.

Beispielsweise nur die ersten drei Punkte zeigen, bis auf die Fenster-Bildschirm. Finden Sie die initialize() Funktion -

#include <stdio.h>
#include <stdlib.h>

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <cstdlib>
#include <vector>
#include <iostream>
#include <fstream>

//Read a shader source from a file
//store the shader source in a std::vector<char>
void read_shader_src(const char* fname, std::vector<char> &buffer);

//Compile a shader
GLuint load_and_compile_shader(const char *fname, GLenum shaderType);

//Create a program from two shaders
GLuint create_program(const char *path_vert_shader, const char *path_frag_shader);

//Render scene
void display(GLuint &vao, GLFWwindow* window);

//Initialize the data to be rendered
void initialize(GLuint &vao);


//GLFW Callbacks
static void error_callback(int error, const char* description) {
    fprintf(stderr, "Error: %s\n", description);
}

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
    if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
        glfwSetWindowShouldClose(window, GL_TRUE);
    }
}

int main() {
    glfwSetErrorCallback(error_callback);
    //Initialize GLFW
    if (!glfwInit()) {
        fprintf(stderr, "Failed to initialize GLFW.\n");
        return -1;
    }

    //Set GLFW window settings and create window
    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);
    GLFWwindow* window = glfwCreateWindow(500, 500, "My window", NULL, NULL);
    if(!window) {
        fprintf(stderr, "Window or context creation failed.\n");
        return -1;
    }

    glfwSetKeyCallback(window, key_callback);
    glfwMakeContextCurrent(window);

    //Initialize GLEW
    glewExperimental = GL_TRUE;
    if(glewInit() != GLEW_OK) {
        fprintf(stderr, "Failed to initialize glew");
        glfwTerminate();
        return -1;
    }
    //Create a vertex array object
    GLuint vao;

    //Initialize the data to be rendered
    initialize(vao);

    while (!glfwWindowShouldClose(window)) {
        display(vao, window);
        glfwPollEvents();
    }
    glfwTerminate();
    return 0;
}

//Render scene
void display(GLuint &vao, GLFWwindow* window) {
    //Red background
    glClearColor(1.0f, 0.0f, 0.0f, 0.0f); 
    glClear(GL_COLOR_BUFFER_BIT);

    glBindVertexArray(vao);
    glDrawArrays(GL_POINTS, 0, 12);
    //Swap front and back buffers
    glfwSwapBuffers(window);
}

void initialize(GLuint &vao) {
    glEnable(GL_PROGRAM_POINT_SIZE);
    //Use a Vertex Array Object
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    //Store verex positions in an array
    GLfloat vertices[24] = {
        0.0, 0.0, //Only these
        0.5, 0.5, //three points show up
        1.0, 1.0, //on the window screen

        4.0, 4.0,
        5.0, 5.0,
        6.0, 6.0,

        7.0, 7.0,
        8.0, 8.0,
        9.0, 9.0,

        10.0, 10.0,
        11.0, 11.0,
        12.0, 12.0,
    };

    //Create a vertex buffer object to store the vertex data
    GLuint vbo;
    //Generates 1 buffer object name and stores it in vbo
    glGenBuffers(1, &vbo);
    //Bind the buffer object to the buffer binding target
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    //Creates and initializes the buffer object's data store(with data from vertices)
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    GLuint shaderProgram = create_program("/Users/.../vert.shader", "/Users/.../frag.shader"); //path to shader files

    //Get the location of the attributes that enters in the vertex shader
    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");

    //Specify how the data for position can be accessed
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

    //Enable the attribute
    glEnableVertexAttribArray(posAttrib);
}

//Read a shader source from a file
//store the shader source in a std::vector<char>
void read_shader_src(const char *fname, std::vector<char> &buffer) {
    std::ifstream in;
    in.open(fname, std::ios::binary);

    if(in.is_open()) {
        //Get the number of bytes stored in this file
        in.seekg(0, std::ios::end);
        size_t length = (size_t)in.tellg();

        //Go to start of the file
        in.seekg(0, std::ios::beg);

        //Read the content of the file in a buffer
        buffer.resize(length + 1);
        in.read(&buffer[0], length);
        in.close();
        //Add a valid C - string end
        buffer[length] = '\0';
    }
    else {
        std::cerr << "Unable to open " << fname << " I'm out!" << std::endl;
        exit(-1);
    }
}

//Compile a shader
GLuint load_and_compile_shader(const char* fname, GLenum shaderType) {
    //Load a shader from an external file
    std::vector<char> buffer;
    read_shader_src(fname, buffer);
    const char *src = &buffer[0];

    //Create and compile the shader
    GLuint shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, &src, NULL);
    glCompileShader(shader);

    GLint shader_compiled;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_compiled);
    if(!shader_compiled) {
        GLchar message[1024];
        glGetShaderInfoLog(shader, 1024, NULL, message);
        std::cerr << "Shader compilation failed.";
        std::cerr << "Log: " << &message << std::endl;
        glfwTerminate();
        exit(-1);
    }
    return shader;
}

//Create a program from two shaders
GLuint create_program(const char *path_vert_shader, const char *path_frag_shader) {
    //Load and compile the vertex and fragment shaders
    GLuint vertexShader = load_and_compile_shader(path_vert_shader, GL_VERTEX_SHADER);
    GLuint fragmentShader = load_and_compile_shader(path_frag_shader, GL_FRAGMENT_SHADER);

    //Attach the above shader to a program
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);

    //Flag the shaders for deletion
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    //Link and use the program
    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);

    return shaderProgram;
}

Welche änderungen muss ich machen, damit ich zeichnen können der rest der Punkte?

Vertex-Shader -

#version 150 core

in vec4 position;

void main() {
    gl_Position = position;
    gl_PointSize = 10.0;
}

Fragment-Shader -

#version 150 core

out vec4 out_color;

void main() {
    out_color = vec4(1.0, 1.0, 1.0, 1.0);
}
Ich verstehe, dass dies nur für die Praxis, aber die Einstellung separaten Pixel unter Verwendung von OpenGL zum zeichnen von primitiven irgendwie leugnet, dass der Zweck der GL...
Tun Sie nur haben, um Linien zu zeichnen oder benutzen Sie Bresenham-Algorithmus?
Ich habe die Verwendung des Algorithmus für die "rasterisation". Ich weiß, ich hätte GL_LINES sonst.
Einfach speichern Sie die x und y in der Reihenfolge in ein array und verwenden Sie glDrawArrays() mit GL_POINTS Rendern der Linien. Als pro -1,1 erstellen Sie eine 2D-Projektion-matrix, vielleicht mit glm und senden Sie es an Ihre shader und multiplizieren Sie einfach Punkte, indem Sie es.
Dies kann ein bisschen eine dumme Art und Weise, es zu tun, aber man könnte die Grenze ziehen w/ Bresenham-Algorithmus, um eine textur auf der CPU Ende und ziehen Sie dann das quad auf den Bildschirm, in der Regel. Ich kann schreiben, bis eine ausführlichere Antwort, wenn Sie interessiert sind

InformationsquelleAutor ByteMan2021 | 2016-09-10

Schreibe einen Kommentar