Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Преобразование HSL на текстуре OpenGL в Delphi

Delphi , Графика и Игры , OpenGL

Если вам нужно выполнить преобразование HSL на текстуре OpenGL в Delphi, вам понадобится использовать шейдеры. Шейдеры - это небольшие программы, которые выполняются на графическом процессоре и используются для изменения цвета, текстуры и других атрибутов объектов в реальном времени.

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

Шаг 1: Создание шейдера

Первый шаг - создать шейдер, который будет выполнять преобразование HSL. Для этого нам понадобится использовать язык программирования, такой как GLSL (OpenGL Shading Language). Вот пример шейдера, который принимает текстуру, сдвиг оттенка, множители насыщенности и яркости и возвращает преобразованную текстуру:

#version 330 core

in vec2 TexCoord;
out vec4 FragColor;

uniform sampler2D inputTexture;
uniform float hShift;
uniform float sMult;
uniform float lMult;

void main(){
    vec4 color = texture(inputTexture, TexCoord);

    // Convert RGB to HSL
    float h = (color.r + color.g + color.b) / 3.0;
    float s = (max(color.r, max(color.g, color.b)) - min(color.r, min(color.g, color.b))) / (max(color.r, max(color.g, color.b)) + min(color.r, min(color.g, color.b)));
    float l = (color.r + color.g + color.b) / 3.0;

    // Apply HSL shift and multipliers
    h = (h + hShift) % 360.0;
    s = s * sMult;
    l = l * lMult;

    // Convert HSL back to RGB
    float r, g, b;
    if(s == 0.0){
        r = g = b = l; // achromatic
    }else{
        float temp1 = (l + s) / 2.0;
        float temp2 = (2.0 * l - temp1) * abs(h / 360.0 - 1.0);
        float temp3 = temp1 - abs((h / 360.0) - 1.0) * temp2;
        if(h < 120.0){
            r = temp2;
            g = temp3;
            b = (l - s);
        }else if(h < 240.0){
            r = (l - s);
            g = temp2;
            b = temp3;
        }else{
            r = temp3;
            g = (l - s);
            b = temp2;
        }
    }

    FragColor = vec4(r, g, b, color.a);
}

Шаг 2: Компиляция шейдера

После написания шейдера, нам нужно его скомпилировать и связать с программой. Для этого мы будем использовать OpenGL. Вот как это можно сделать в Delphi:

procedure CompileShader(const shaderSource: string; shaderType: GLenum; var shaderID: GLuint);
var
  status: GLint;
begin
  shaderID := glCreateShader(shaderType);
  with shaderID do
  begin
    glShaderSource(shaderID, 1, [shaderSource], nil);
    glCompileShader(shaderID);
    glGetShaderiv(shaderID, GL_COMPILE_STATUS, @status);
    if (status = GL_FALSE) then
      raise Exception.Create('Shader compilation failed');
  end;
end;

Эта процедура принимает исходный код шейдера, тип шейдера (GL_VERTEX_SHADER или GL_FRAGMENT_SHADER) и возвращает идентификатор скомпилированного шейдера.

Шаг 3: Связывание шейдера

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

procedure LinkShader(const vertexShaderID, fragmentShaderID: GLuint; var programID: GLuint);
var
  status: GLint;
begin
  programID := glCreateProgram();
  with programID do
  begin
    glAttachShader(programID, vertexShaderID);
    glAttachShader(programID, fragmentShaderID);
    glLinkProgram(programID);
    glGetProgramiv(programID, GL_LINK_STATUS, @status);
    if (status = GL_FALSE) then
      raise Exception.Create('Program linking failed');
  end;
end;

Эта процедура принимает идентификаторы скомпилированных вершинного и фрагментного шейдеров и возвращает идентификатор связанной программы.

Шаг 4: Применение шейдера

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

procedure HSLTransform(texture: GLuint; hShift: GLfloat; sMult, lMult: GLfloat);
var
  programID: GLuint;
  uniformLocation: GLint;
begin
  // Compile and link shaders
  CompileShader('...', GL_FRAGMENT_SHADER, fragmentShaderID);
  CompileShader('...', GL_VERTEX_SHADER, vertexShaderID);
  LinkShader(vertexShaderID, fragmentShaderID, programID);

  // Bind the program
  glUseProgram(programID);

  // Set the values of the uniform parameters
  uniformLocation := glGetUniformLocation(programID, 'inputTexture');
  glUniform1i(uniformLocation, 0);
  uniformLocation := glGetUniformLocation(programID, 'hShift');
  glUniform1f(uniformLocation, hShift);
  uniformLocation := glGetUniformLocation(programID, 'sMult');
  glUniform1f(uniformLocation, sMult);
  uniformLocation := glGetUniformLocation(programID, 'lMult');
  glUniform1f(uniformLocation, lMult);

  // Bind the source texture to read from
  glBindTexture(GL_TEXTURE_2D, texture);

  // Render a quad
  glBegin(GL_QUADS);
  glVertex2i(0, 0);
  glVertex2i(1, 0);
  glVertex2i(1, 1);
  glVertex2i(0, 1);
  glEnd();
end;

Эта функция принимает идентификатор текстуры, сдвиг оттенка, множители насыщенности и яркости и применяет шейдер к текстуре перед ее отображением.

Использование альтернативного подхода

Если вам не нужно выполнять преобразование HSL в реальном времени, вы можете использовать альтернативный подход, который заключается в получении пикселей текстуры и изменении их в коде Delphi. Вот пример кода, который демонстрирует этот подход:

procedure ModifyTexturePixels(texture: GLuint);
var
  pixels: PByte;
  width, height: GLint;
begin
  // Get texture dimensions
  glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL\_TEXTURE\_WIDTH, @width);
  glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL\_TEXTURE\_HEIGHT, @height);

  // Get copy of pixels
  GetMem(pixels, width * height * 4);
  glGetTexImage(GL\_TEXTURE\_2D, 0, GL\_RGBA, GL\_UNSIGNED\_BYTE, pixels);

  // Modify pixels here
  ...

  // Update texture with modified pixels
  glTexImage2D(GL\_TEXTURE\_2D, 0, GL\_RGBA, width, height, 0, GL\_RGBA, GL\_UNSIGNED\_BYTE, pixels);
  FreeMem(pixels);
end;

Этот подход slower

Создано по материалам из источника по ссылке.

Преобразование HSL на текстуре OpenGL в Delphi выполняется с помощью шейдеров, которые применяют сдвиг оттенка, множители насыщенности и яркости к текстуре перед ее отображением.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: OpenGL ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-02-05 18:59:39/0.0038859844207764/0