C++ 在使用片段着色器写入1D纹理后,从1D纹理读回不起作用

C++ 在使用片段着色器写入1D纹理后,从1D纹理读回不起作用,c++,opengl,C++,Opengl,我正在尝试使用imageStore()函数检索片段着色器中1D纹理中写入的值。我正在生成随机点并在片段着色器中处理,以便使用外圆生成delaunay三角剖分。当我生成一定大小的点(小于30)时,从纹理读取是有效的,但当我增加大小时,它返回零。 这是我的片段着色器中存储以下内容的部分: uniform layout(binding = 1, rgba32f) writeonly image1D tex1; … // more code if (flag) {

我正在尝试使用imageStore()函数检索片段着色器中1D纹理中写入的值。我正在生成随机点并在片段着色器中处理,以便使用外圆生成delaunay三角剖分。当我生成一定大小的点(小于30)时,从纹理读取是有效的,但当我增加大小时,它返回零。 这是我的片段着色器中存储以下内容的部分:

    uniform layout(binding = 1, rgba32f) writeonly image1D tex1;
    … // more code
    if (flag)
    {
        color = vec3(0.0, 1.0, 0.0);
        int index = 0;
        for (int i = 0; i < b; i++)
            index += (size - i - 1) * i;
        index += a * (size - b - 1) + (i_uv.x + 1) - 1;
        imageStore(tex1, index, vec4(a, b, c, 1.0));
    }
片段着色器:

#version 450 core

out vec4 FragColor;

layout(binding = 0) uniform sampler1D tex0; // Buffer storing random points
uniform layout(binding = 1, rgba32f) writeonly image1D tex1; // Buffer to store the indices of legal triangles

layout(location = 0) uniform int size;
layout(location = 1) uniform vec2 u_resolution;

vec2 circumcenter(vec2 A, vec2 B, vec2 C, out bool f)
{
vec2 P1 = (A + B) / 2.0;
vec2 P2 = (A + C) / 2.0;

float a1 = -A.x + B.x;
float b1 = A.y - B.y;
float a2 = -A.x + C.x;
float b2 = A.y - C.y;

float c1 = a1*P1.x - b1*P1.y;
float c2 = a2*P2.x - b2*P2.y;

float det = a1*b2 - a2*b1;
vec2 circum = vec2(0.0);
f = false;
if (det != 0)
{
    float x = (b2*c1 - b1*c2) / det;
    float y = (a2*c1 - a1*c2) / det;
    circum = vec2(x, y);
    f = true;
}

return circum;
}

void main()
{
vec2 st = gl_FragCoord.xy / u_resolution;
ivec2 i_st = ivec2(floor(st * size));
vec2 f_st = fract(st * size);

vec3 color = vec3(0.0);

if (i_st.y > i_st.x && i_st.y < size - 1)
{
    // Positions of the random points buffer (a, b, c)
    int a = i_st.x;
    int b = i_st.y;
    ivec2 i_uv = ivec2(floor(f_st * (size - b - 1)));
    int c = i_uv.x + b + 1;

    // Points of the triangle
    vec2 A = texelFetch(tex0, a, 0).xy;
    vec2 B = texelFetch(tex0, b, 0).xy;
    vec2 C = texelFetch(tex0, c, 0).xy;

    bool flag;
    vec2 cir = circumcenter(A, B, C, flag);
    if (flag)
    {
        float radius = distance(cir, A);
        // Checking if any other point is inside of the circumscribe circle
        for (int i = 0; i < size; i++)
        {
            if (i == a || i == b || i == c)
                continue;
            vec2 P = texelFetch(tex0, i, 0).xy;
            float dist = distance(cir, P);
            if (dist < radius)
            {
                flag = false;
                break;
            }
        }

        if (flag)
        {
            color = vec3(0.0, 1.0, 0.0); // Painting the fargments that correspond to legal triangles
            int index = 0;
            for (int i = 0; i < b; i++)
                index += (size - i - 1) * i;
            index += a * (size - b - 1) + (i_uv.x + 1) - 1;
            memoryBarrier();
            imageStore(tex1, index, vec4(a, b, c, 1.0)); // Storing indices of legal triangles

        }
    }
}
else 
    color += 1.0;
FragColor = vec4(color, 0.0);
}
#版本450核心
out vec4 FragColor;
布局(绑定=0)统一采样器1D tex0;//存储随机点的缓冲区
统一布局(绑定=1,rgba32f)可写图像1D tex1;//用于存储合法三角形索引的缓冲区
布局(位置=0)统一整数大小;
布局(位置=1)统一的vec2 u_分辨率;
vec2外圆中心(vec2 A、vec2 B、vec2 C、外边界f)
{
vec2 P1=(A+B)/2.0;
vec2p2=(A+C)/2.0;
浮动a1=-A.x+B.x;
浮球b1=A.y-B.y;
浮动a2=-A.x+C.x;
浮动b2=A.y-C.y;
浮点数c1=a1*P1.x-b1*P1.y;
浮点数c2=a2*P2.x-b2*P2.y;
浮点数=a1*b2-a2*b1;
vec2环=vec2(0.0);
f=假;
如果(det!=0)
{
浮点数x=(b2*c1-b1*c2)/det;
浮动y=(a2*c1-a1*c2)/det;
环=vec2(x,y);
f=真;
}
返回环;
}
void main()
{
vec2 st=gl_FragCoord.xy/u_分辨率;
ivec2 i_st=ivec2(地板(标准尺寸));
vec2 f_st=分形(st*尺寸);
vec3颜色=vec3(0.0);
如果(i_st.y>i_st.x&&i_st.y
申请代码:

#include "../../Classes/Renderer/Core.h"
#include "../../Classes/Renderer/Shader.h"
#include "../../Classes/Renderer/Input.h"

#include <iostream>
#include <cstdlib>
#include <ctime>

class DT
    : public Core
{
public:
    virtual void Start() override
    {
        srand(time(nullptr));

        shader.addShader("C:/dev/RendererOpenGL/RendererOpenGL/src/Tesis/simpleTri.vert", ShaderType::VERTEX_SHADER);
        shader.addShader("C:/dev/RendererOpenGL/RendererOpenGL/src/Tesis/simpleTri.frag", ShaderType::FRAGMENT_SHADER);

        // Compute Buffer size to store indices of legal triangles
        imageSize = 0;
        int stride{ size - 1 };
        for (size_t i{ 0 }; i < size - 1; i++)
            imageSize += (stride - i) * i;

        glCreateTextures(GL_TEXTURE_1D, 1, &image);
        glTextureStorage1D(image, 1, GL_RGBA32F, imageSize);

        pixels = new vec4[imageSize];

        glCreateTextures(GL_TEXTURE_1D, 1, &texture1D);
        glTextureStorage1D(texture1D, 1, GL_RG32F, size);

        data = new vec2[size];
        // Genereating random points
        for (size_t i{ 0 }; i < size; i++)
        {
            float x = static_cast<float>(rand()) / RAND_MAX;
            float y = static_cast<float>(rand()) / RAND_MAX;
            data[i] = vec2(x, y);
            //std::cout << i << ": " << data[i] << std::endl;
        }

        glTextureSubImage1D(texture1D, 0, 0, size, GL_RG, GL_FLOAT, data);
        glBindTextureUnit(0, texture1D);

        glBindTexture(GL_TEXTURE_1D, texture1D);
        glBindImageTexture(1, image, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);

        // Rendering once to compute legal triangles
        shader.use();
        shader.setUniformi(ShaderType::FRAGMENT_SHADER, 0, size);
        shader.setUniform2v(ShaderType::FRAGMENT_SHADER, 1, vec2(Window::current->getWidth(), Window::current->getHeight()));
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);

        glBindTexture(GL_TEXTURE_1D, image);
        glGetTexImage(GL_TEXTURE_1D, 0, GL_RGBA, GL_FLOAT, pixels);


        std::cout << "\nTexture values\n";
        size_t count = 0;
        for (size_t i{ 0 }; i < imageSize; i++)
        {
            if (pixels[i].a != 0)
            {
                std::cout << pixels[i] << std::endl;
                count++;
            }
        }
        std::cout << count << std::endl;
    }

    virtual void Update() override
    {

    }

    virtual void End() override
    {
        shader.delete_shader();

        glDeleteTextures(1, &texture1D);
        glDeleteTextures(1, &imageSize);

        delete[] data;
        delete[] pixels;
    }

private:
    Shader shader;
    vec2* data;
    const int size{ 20 };

    GLuint texture1D;
    GLuint image;

    size_t imageSize;
    vec4 *pixels;
};

#if 1
CORE_MAIN(DT)
#endif
#包括“../../Classes/Renderer/Core.h”
#包括“../../Classes/Renderer/Shader.h”
#包括“../../Classes/Renderer/Input.h”
#包括
#包括
#包括
DT类
:公共核心
{
公众:
虚拟void Start()覆盖
{
srand(时间(nullptr));
addShader(“C:/dev/renderopengl/renderopengl/src/Tesis/simpleTri.vert”,ShaderType::VERTEX_着色器);
addShader(“C:/dev/renderopengl/renderopengl/src/Tesis/simpleTri.frag”,ShaderType::FRAGMENT_shader);
//计算缓冲区大小以存储合法三角形的索引
图像大小=0;
int跨步{size-1};
对于(size_t i{0};i//std::cout您使用了错误的内存屏障。您必须指定在使用屏障后打算如何使用内存

您正在使用
glGetTexImage
访问数据,因此根据第7.13节“着色器内存访问”,您必须使用(强调我的):

纹理\u更新\u屏障\u位
:写入 通过
Tex(子)图像*
ClearTex*图像
CopyTex*
,或
CompressedTex*
,创建纹理, 并在屏障不执行后通过
GetTexImage
读取 直到所有着色器写入在屏障完成之前启动


我已更改为纹理更新屏障位,但仍然不起作用。我已经解决了它,问题不仅在于屏障(感谢@derhass)而是我创建的纹理大小,我的图形卡中纹理1d的最大大小为16384 texel(我想是texel),我创建的纹理1d大于16384 texel
#version 450 core

out vec4 FragColor;

layout(binding = 0) uniform sampler1D tex0; // Buffer storing random points
uniform layout(binding = 1, rgba32f) writeonly image1D tex1; // Buffer to store the indices of legal triangles

layout(location = 0) uniform int size;
layout(location = 1) uniform vec2 u_resolution;

vec2 circumcenter(vec2 A, vec2 B, vec2 C, out bool f)
{
vec2 P1 = (A + B) / 2.0;
vec2 P2 = (A + C) / 2.0;

float a1 = -A.x + B.x;
float b1 = A.y - B.y;
float a2 = -A.x + C.x;
float b2 = A.y - C.y;

float c1 = a1*P1.x - b1*P1.y;
float c2 = a2*P2.x - b2*P2.y;

float det = a1*b2 - a2*b1;
vec2 circum = vec2(0.0);
f = false;
if (det != 0)
{
    float x = (b2*c1 - b1*c2) / det;
    float y = (a2*c1 - a1*c2) / det;
    circum = vec2(x, y);
    f = true;
}

return circum;
}

void main()
{
vec2 st = gl_FragCoord.xy / u_resolution;
ivec2 i_st = ivec2(floor(st * size));
vec2 f_st = fract(st * size);

vec3 color = vec3(0.0);

if (i_st.y > i_st.x && i_st.y < size - 1)
{
    // Positions of the random points buffer (a, b, c)
    int a = i_st.x;
    int b = i_st.y;
    ivec2 i_uv = ivec2(floor(f_st * (size - b - 1)));
    int c = i_uv.x + b + 1;

    // Points of the triangle
    vec2 A = texelFetch(tex0, a, 0).xy;
    vec2 B = texelFetch(tex0, b, 0).xy;
    vec2 C = texelFetch(tex0, c, 0).xy;

    bool flag;
    vec2 cir = circumcenter(A, B, C, flag);
    if (flag)
    {
        float radius = distance(cir, A);
        // Checking if any other point is inside of the circumscribe circle
        for (int i = 0; i < size; i++)
        {
            if (i == a || i == b || i == c)
                continue;
            vec2 P = texelFetch(tex0, i, 0).xy;
            float dist = distance(cir, P);
            if (dist < radius)
            {
                flag = false;
                break;
            }
        }

        if (flag)
        {
            color = vec3(0.0, 1.0, 0.0); // Painting the fargments that correspond to legal triangles
            int index = 0;
            for (int i = 0; i < b; i++)
                index += (size - i - 1) * i;
            index += a * (size - b - 1) + (i_uv.x + 1) - 1;
            memoryBarrier();
            imageStore(tex1, index, vec4(a, b, c, 1.0)); // Storing indices of legal triangles

        }
    }
}
else 
    color += 1.0;
FragColor = vec4(color, 0.0);
}
#include "../../Classes/Renderer/Core.h"
#include "../../Classes/Renderer/Shader.h"
#include "../../Classes/Renderer/Input.h"

#include <iostream>
#include <cstdlib>
#include <ctime>

class DT
    : public Core
{
public:
    virtual void Start() override
    {
        srand(time(nullptr));

        shader.addShader("C:/dev/RendererOpenGL/RendererOpenGL/src/Tesis/simpleTri.vert", ShaderType::VERTEX_SHADER);
        shader.addShader("C:/dev/RendererOpenGL/RendererOpenGL/src/Tesis/simpleTri.frag", ShaderType::FRAGMENT_SHADER);

        // Compute Buffer size to store indices of legal triangles
        imageSize = 0;
        int stride{ size - 1 };
        for (size_t i{ 0 }; i < size - 1; i++)
            imageSize += (stride - i) * i;

        glCreateTextures(GL_TEXTURE_1D, 1, &image);
        glTextureStorage1D(image, 1, GL_RGBA32F, imageSize);

        pixels = new vec4[imageSize];

        glCreateTextures(GL_TEXTURE_1D, 1, &texture1D);
        glTextureStorage1D(texture1D, 1, GL_RG32F, size);

        data = new vec2[size];
        // Genereating random points
        for (size_t i{ 0 }; i < size; i++)
        {
            float x = static_cast<float>(rand()) / RAND_MAX;
            float y = static_cast<float>(rand()) / RAND_MAX;
            data[i] = vec2(x, y);
            //std::cout << i << ": " << data[i] << std::endl;
        }

        glTextureSubImage1D(texture1D, 0, 0, size, GL_RG, GL_FLOAT, data);
        glBindTextureUnit(0, texture1D);

        glBindTexture(GL_TEXTURE_1D, texture1D);
        glBindImageTexture(1, image, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);

        // Rendering once to compute legal triangles
        shader.use();
        shader.setUniformi(ShaderType::FRAGMENT_SHADER, 0, size);
        shader.setUniform2v(ShaderType::FRAGMENT_SHADER, 1, vec2(Window::current->getWidth(), Window::current->getHeight()));
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);

        glBindTexture(GL_TEXTURE_1D, image);
        glGetTexImage(GL_TEXTURE_1D, 0, GL_RGBA, GL_FLOAT, pixels);


        std::cout << "\nTexture values\n";
        size_t count = 0;
        for (size_t i{ 0 }; i < imageSize; i++)
        {
            if (pixels[i].a != 0)
            {
                std::cout << pixels[i] << std::endl;
                count++;
            }
        }
        std::cout << count << std::endl;
    }

    virtual void Update() override
    {

    }

    virtual void End() override
    {
        shader.delete_shader();

        glDeleteTextures(1, &texture1D);
        glDeleteTextures(1, &imageSize);

        delete[] data;
        delete[] pixels;
    }

private:
    Shader shader;
    vec2* data;
    const int size{ 20 };

    GLuint texture1D;
    GLuint image;

    size_t imageSize;
    vec4 *pixels;
};

#if 1
CORE_MAIN(DT)
#endif