LINUX.ORG.RU

Как нарисовать закрашенный круг на GLSL #version 120

 , ,


0

4

Может у кого-нибудь есть вершинный и фрагментные шейдеры, которые рисуют закрашенный круг в (x, y) с радиусом r ?

В инете есть туториалы, но они для более новых шейдеров и конкретно для glsl #120 я не нашел :(

Буду очень признателен, если у кого-нить что-нибудь завалялось.
Заранее спасибо!

Логика там одна и та же должна быть. Рисуется quad на экране. В шейдеры передаются радиус и координаты центра. Далее во фрагментном шейдере определяется дистанция от текущего пикселя до центра окружности и если она больше радиуса, то делается discard, иначе пишется цвет в gl_FragColor.

Amp ★★★
()
Ответ на: комментарий от Amp

Все, спасибо! Все получилось и как причешу код, выложу сюда для тех, кому понадобиться в будущем.
Всем спасибо!

Glaciuse
() автор топика

нарисовать закрашенный круг на GLSL

Eddy_Em

anonymous
()
Ответ на: комментарий от Amp
#pragma once

#include <fstream>

#include <iostream>
#include <string>

#include <GLee.h>
#include <string.h>
#include <vector>

using std::vector;
using std::string;
using std::cout; using std::endl;

static const char* vertex_shared_src =
        "\n"
                "attribute vec2 tex_coords;\n"

                "varying vec2 _disc_tex_coords;\n"

                "void main()\n"
                "{\n"
                "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
                "   _disc_tex_coords = tex_coords;\n"
                "}\n";


static const char* fragment_shader_src =
        "\n"
                "uniform vec4 disc_color;\n"
                "varying vec2 _disc_tex_coords;\n"

                "float disc_radius = 1.0f;\n"
                "\n"
                "void main()\n"
                "{\n"
                "   float distance = distance(_disc_tex_coords, vec2(0.0, 0.0));\n"
                "   if (distance < disc_radius)\n"
                "       gl_FragColor = disc_color;\n"
                "   else\n"
                "       gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
                "}\n";

class Cell
{
public:
    Cell()
    {
        load_shaders();

        _disc_color = glGetUniformLocation(_program, "disc_color");
    };

    void draw()
    {
        glClearColor(0.2, 0.2, 0.2, 1.0);
        glUseProgram(_program);

        glUniform4f(_disc_color, 0.2f, 0.9f, 0.4f, 1.0f);
        glBindVertexArray(_vao);
        glDrawArrays(GL_QUADS, 0, 4 * (GLsizei)_cells.size());

        glUseProgram(0);
    }

    void add_cell(unsigned int x, unsigned int y, unsigned int r)
    {
        _CellData cd;
        cd.x1 = x - r; cd.y1 = y - r; cd.tex_x1 = -1.0f; cd.tex_y1 = -1.0f;
        cd.x2 = x - r; cd.y2 = y + r; cd.tex_x2 = -1.0f; cd.tex_y2 = 1.0f;
        cd.x3 = x + r; cd.y3 = y + r; cd.tex_x3 = 1.0f; cd.tex_y3 = 1.0f;
        cd.x4 = x + r; cd.y4 = y - r; cd.tex_x4 = 1.0f; cd.tex_y4 = -1.0f;
        _cells.push_back(cd);

        _bind_buffers();
    }
private:

    struct _CellData
    {
        GLfloat x1, y1, tex_x1, tex_y1;
        GLfloat x2, y2, tex_x2, tex_y2;
        GLfloat x3, y3, tex_x3, tex_y3;
        GLfloat x4, y4, tex_x4, tex_y4;
    };

    vector<_CellData> _cells;

    GLuint _program;
    GLint _disc_color;

    GLuint _vbo, _vao;

    void _bind_buffers()
    {
        GLchar* pointer = 0;

        glGenBuffers(1, &_vbo);
        glGenVertexArrays(1, &_vao);

        glBindBuffer(GL_ARRAY_BUFFER, _vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(_CellData) * _cells.size() * sizeof(GLfloat),
                     &_cells[0], GL_STATIC_DRAW);

        glBindVertexArray(_vao);
        glBindBuffer(GL_ARRAY_BUFFER, _vbo);
        // 0 - вершины
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 16, pointer); // 16 - размер одной записи x + y + tex_x1 + tex_y1
        // 1 - кординаты текстуры
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 16, pointer + 8);

        // Включаем массив атрибутов для вершин и координат текстур
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArrayARB(1);

    }

    void load_shaders()
    {
        auto vertex_shader_object = glCreateShader(GL_VERTEX_SHADER);
        auto fragment_shader_object = glCreateShader(GL_FRAGMENT_SHADER);

        glShaderSourceARB(vertex_shader_object, 1, &vertex_shared_src, NULL);
        glShaderSourceARB(fragment_shader_object, 1, &fragment_shader_src, NULL);

        glCompileShader(vertex_shader_object);
        _check_shader_compilation(vertex_shader_object, "vertex");

        glCompileShader(fragment_shader_object);
        _check_shader_compilation(fragment_shader_object, "fragment");

        _program = glCreateProgram();
        glAttachShader(_program, vertex_shader_object);
        glAttachShader(_program, fragment_shader_object);

        glBindAttribLocation(_program, 0, "gl_Vertex");
        glBindAttribLocation(_program, 1, "tex_coords");

        glLinkProgram(_program);
        _check_program_link(_program);
        _get_active_vertex_shader_inputs(_program);
    }

    void _check_shader_compilation(GLuint shader_object, string shader_name)
    {
        GLint compiled, blen, slen;
        glGetObjectParameterivARB(shader_object, GL_COMPILE_STATUS, &compiled);
        if(!compiled)
        {
            cout << "Cell: " << shader_name << " shader compilation failure!" << endl;
            glGetShaderiv(shader_object, GL_INFO_LOG_LENGTH, &blen);
            if(blen > 1)
            {
                GLchar* compiler_log = new GLchar[blen];
                glGetInfoLogARB(shader_object, blen, &slen, compiler_log);
                cout << "Log: " << endl << compiler_log;
                delete [] compiler_log;
            }
            exit(1);
        }
    }

    void _check_program_link(GLuint program)
    {
        GLint linked;
        GLint blen, slen;
        glGetProgramiv(program, GL_LINK_STATUS, &linked);
        if(!linked)
        {
            cout << "Cell shader program link failure!" << endl;
            glGetShaderiv(program, GL_INFO_LOG_LENGTH, &blen);
            if(blen > 1)
            {
                GLchar* link_log = new GLchar[blen];
                glGetInfoLogARB(program, blen, &slen, link_log);
                cout << "Log: " << endl << link_log;
                delete [] link_log;
            }
        }
    }

    void _get_active_vertex_shader_inputs(GLuint program)
    {
        char* name;
        GLint active_attribs, max_length;

        glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attribs);
        glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_length);

        name = new char[max_length + 1];

        for(unsigned int i = 0 ; i < active_attribs ; i++)
        {
            GLint size;
            GLenum type;

            glGetActiveAttrib(program, i, max_length + 1, NULL, &size, &type, name);

            cout << type << ", " << name << ", " << glGetAttribLocation(program, name) << endl;
        }

        delete [] name;

    }
};
Glaciuse
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.