LINUX.ORG.RU

Нарисавать пунктирную линию

 


0

1

Привет. Раньше всё было просто - для линии задавалась битовая маска.

     glLineStipple(1, 0x00ff);
     glEnable(GL_LINE_STIPPLE);
     glBegin(GL_LINE);
     ...
     glEnd();
Как это сделать в новом стиле? В сети пишут про использование текстуры, но ни одного примера. Ребята помогите, если не сложно. Я набросал заготовку, рисует диагональ.
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <utility>
#include <chrono>
#include <thread>
#include <iostream>

static const char *vertexShaderSource =
   "#version 330 core\n"
   "layout (location = 0) in vec2 position;\n"
   "void main() {\n"
   "   gl_Position = vec4(position.x, position.y, 0, 1.0);\n"
   "}\n";
static const char *fragmentShaderSource =
   "#version 330 core\n"
   "out vec4 color;\n"
   "void main() {\n"
   "   color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
   "}\n";

class Shader_prg
{
   GLuint shaderProgram;
public:
   Shader_prg(const char *vs, const char *fs)
   {
      GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
      glShaderSource(vertexShader, 1, &vs, NULL);
      glCompileShader(vertexShader);

      GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
      glShaderSource(fragmentShader, 1, &fs, NULL);
      glCompileShader(fragmentShader);

      this->shaderProgram = glCreateProgram();
      glAttachShader(this->shaderProgram, vertexShader);
      glAttachShader(this->shaderProgram, fragmentShader);
      glLinkProgram(this->shaderProgram);

      glDeleteShader(vertexShader);
      glDeleteShader(fragmentShader);
   }
   ~Shader_prg() {glDeleteProgram(this->shaderProgram);}
   Shader_prg(Shader_prg &) = delete;
   Shader_prg &operator=(Shader_prg &) = delete;
   operator GLuint() {return this->shaderProgram;}
   void use() { glUseProgram(this->shaderProgram); }
};

int main(void)
{
   using namespace std::chrono_literals;
    if (!glfwInit())
        return -1;
    GLFWwindow* window = glfwCreateWindow(800, 600, "Hello World", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK)
       return -1;
    Shader_prg sh_prg{vertexShaderSource, fragmentShaderSource};

    GLfloat vertices[] = {-1.0, -1.0,    1.0,  1.0};
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
    glEnableVertexAttribArray(0);
    glBindVertexArray(0);

    // Создаю текстуру
    GLuint txtr;
    glGenTextures(1, &txtr);
    glBindTexture(GL_TEXTURE_1D, txtr);
//    glTexImage1D(GL_TEXTURE_1D, ...)

    while (!glfwWindowShouldClose(window))
    {
        glfwPollEvents();

        glClearColor(0.1f, 0.25f, 0.2f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        sh_prg.use();
        glBindVertexArray(vao);
        glDrawArrays(GL_LINES, 0, 2);

        glfwSwapBuffers(window);
        std::this_thread::sleep_for(30ms);
    }

    glfwTerminate();
    return 0;
}
И хотелось бы генерить текстуру во время выполнения, а не тоскать с собой рисунок. Может можно что-то хитрое во фрагментном шейдере и текстура не нужна? Я тут не очень силён, прошу помочь.

Ответ на: комментарий от pavlick

Да, рабочий вариант. Подтверждаю. Вообще увлекательный такой квест для вроде бы простых вещей :). Я вначале даже не думал, что реализовать это необходимо столь низкоуровнего, искал в доках какую-нибудь функцию, наивный.

pavlick ()
Ответ на: комментарий от anonymous

Да я же не против. Opengl сделал правильный шаг в своём развитии думаю, всё это позитивно влияет на производительность. Просто после старого opengl немного не по себе.

pavlick ()