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