Hi! Yesterday, the driver crashed after I rendered some frames, today it even doesn’t render a frame, I didn’t changed the code since yesterday. So I’ve random crashes. It only happens with my raytracer renderer, with my other renderer everything works fine. (Dereffered lighting, shadow mapping, etc…)
Here is the code of my raytracing renderer :
RaytracingRenderComponent::RaytracingRenderComponent(RenderWindow& window, int layer, std::string expression, window::ContextSettings settings) : HeavyComponent(window, math::Vec3f(window.getView().getPosition().x, window.getView().getPosition().y, layer),
math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0),
math::Vec3f(window.getView().getSize().x + window.getView().getSize().x * 0.5f, window.getView().getPosition().y + window.getView().getSize().y * 0.5f, layer)),
view(window.getView()),
expression(expression),
quad(math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, window.getSize().y * 0.5f)),
layer(layer) {
quad.move(math::Vec3f(-window.getView().getSize().x * 0.5f, -window.getView().getSize().y * 0.5f, 0));
frameBuffer.create(window.getView().getSize().x, window.getView().getSize().y, settings);
frameBufferSprite = Sprite(frameBuffer.getTexture(), math::Vec3f(0, 0, 0), math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0), sf::IntRect(0, 0, window.getView().getSize().x, window.getView().getSize().y));
frameBuffer.setView(view);
sf::Vector3i resolution ((int) window.getSize().x, (int) window.getSize().y, window.getView().getSize().z);
GLuint maxNodes = 20 * window.getView().getSize().x * window.getView().getSize().y;
GLint nodeSize = 5 * sizeof(GLfloat) + sizeof(GLuint);
glCheck(glGenBuffers(1, &atomicBuffer));
glCheck(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer));
glCheck(glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), nullptr, GL_DYNAMIC_DRAW));
glCheck(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0));
glCheck(glGenBuffers(1, &linkedListBuffer));
glCheck(glBindBuffer(GL_SHADER_STORAGE_BUFFER, linkedListBuffer));
glCheck(glBufferData(GL_SHADER_STORAGE_BUFFER, maxNodes * nodeSize, NULL, GL_DYNAMIC_DRAW));
glCheck(glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0));
glCheck(glGenTextures(1, &headPtrTex));
glCheck(glBindTexture(GL_TEXTURE_2D, headPtrTex));
glCheck(glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, window.getView().getSize().x, window.getView().getSize().y));
glCheck(glBindImageTexture(0, headPtrTex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI));
glCheck(glBindTexture(GL_TEXTURE_2D, 0));
std::vector<GLuint> headPtrClearBuf(window.getView().getSize().x*window.getView().getSize().y, 0xffffffff);
glCheck(glGenBuffers(1, &clearBuf2));
glCheck(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, clearBuf2));
glCheck(glBufferData(GL_PIXEL_UNPACK_BUFFER, headPtrClearBuf.size() * sizeof(GLuint),
&headPtrClearBuf[0], GL_STATIC_COPY));
glCheck(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
glCheck(glGenTextures(1, &frameBufferTex));
glCheck(glBindTexture(GL_TEXTURE_2D, frameBufferTex));
glCheck(glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, window.getView().getSize().x, window.getView().getSize().y));
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glCheck(glBindImageTexture(1, frameBufferTex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F));
glCheck(glBindTexture(GL_TEXTURE_2D, 0));
std::vector<GLfloat> texClearBuf(window.getView().getSize().x*window.getView().getSize().y*4, 0);
glCheck(glGenBuffers(1, &clearBuf));
glCheck(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, clearBuf));
glCheck(glBufferData(GL_PIXEL_UNPACK_BUFFER, texClearBuf.size() * sizeof(GLfloat),
&texClearBuf[0], GL_STATIC_COPY));
glCheck(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
glCheck(glGenBuffers(1, &trianglesSSBO));
glCheck(glGenBuffers(1, &lightsSSBO));
external.setNativeHandle(frameBufferTex, window.getView().getSize().x, window.getView().getSize().y);
core::FastDelegate<bool> signal (&RaytracingRenderComponent::needToUpdate, this);
core::FastDelegate<void> slot (&RaytracingRenderComponent::drawNextFrame, this);
core::Command cmd(signal, slot);
getListener().connect("UPDATE", cmd);
std::string quadVertexShader = R"(#version 460
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
layout (location = 2) in vec2 texCoords;
layout (location = 3) in vec3 normals;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 worldMat;
void main () {
gl_Position = projectionMatrix * viewMatrix * worldMat * vec4(position, 1.f);
})";
std::string quadFragmentShader = R"(#version 460
#define MAX_FRAGMENTS 20
struct NodeType {
vec4 color;
float depth;
uint next;
};
layout(binding = 0, r32ui) uniform uimage2D headPointers;
layout(rgba32f, binding = 1) uniform image2D img_output;
layout(binding = 0, std430) buffer linkedLists {
NodeType nodes[];
};
layout (location = 0) out vec4 fcolor;
void main() {
NodeType frags[MAX_FRAGMENTS];
int count = 0;
uint n = imageLoad(headPointers, ivec2(gl_FragCoord.xy)).r;
while( n != 0xffffffffu && count < MAX_FRAGMENTS) {
frags[count] = nodes[n];
n = frags[count].next;
count++;
}
//merge sort
int i, j1, j2, k;
int a, b, c;
int step = 1;
NodeType leftArray[MAX_FRAGMENTS/2]; //for merge sort
while (step <= count)
{
i = 0;
while (i < count - step)
{
////////////////////////////////////////////////////////////////////////
//merge(step, i, i + step, min(i + step + step, count));
a = i;
b = i + step;
c = (i + step + step) >= count ? count : (i + step + step);
for (k = 0; k < step; k++)
leftArray[k] = frags[a + k];
j1 = 0;
j2 = 0;
for (k = a; k < c; k++)
{
if (b + j1 >= c || (j2 < step && leftArray[j2].depth > frags[b + j1].depth))
frags[k] = leftArray[j2++];
else
frags[k] = frags[b + j1++];
}
////////////////////////////////////////////////////////////////////////
i += 2 * step;
}
step *= 2;
}
vec4 color = vec4(0, 0, 0, 0);
for( int i = 0; i < count; i++)
{
color.rgb = frags[i].color.rgb * frags[i].color.a + color.rgb * (1 - frags[i].color.a);
color.a = frags[i].color.a + color.a * (1 - frags[i].color.a);
}
fcolor = color;
}
)";
std::string raytracingShaderCode = R"(#version 460
#define MAX_FRAGMENTS 20
#extension GL_ARB_bindless_texture : enable
struct NodeType {
vec4 color;
float depth;
uint next;
//vec3 normal;
};
struct Triangle {
mat4 prevTransform;
mat4 transform;
mat4 textureMatrix;
vec4 position[3];
vec4 color[3];
vec4 texCoords[3];
vec4 normal;
uint textureIndex;
uint refractReflect;
float ratio;
float padding;
};
struct Light {
vec4 center;
vec4 color;
float radius;
};
struct Pixel {
vec3 position;
vec4 color;
vec2 texCoords;
};
struct Ray {
vec3 origin;
vec3 dir;
vec3 ext;
};
layout(local_size_x = 1, local_size_y = 1) in;
layout(std140, binding = 0) uniform ALL_TEXTURES {
sampler2D textures[200];
};
layout(std430, binding = 1) buffer trianglesBuffer {
Triangle triangles[];
};
layout(std430, binding = 2) buffer lightsBuffer {
Light lights[];
};
layout(binding = 0, offset = 0) uniform atomic_uint nextNodeCounter;
layout(binding = 0, r32ui) uniform uimage2D headPointers;
layout(binding = 1, rgba32f) uniform image2D img_output;
layout(binding = 0, std430) buffer linkedLists {
NodeType nodes[];
};
uniform uint maxNodes;
uniform uint nbLights;
uniform uint nbTriangles;
uniform vec3 cameraPos;
uniform vec3 resolution;
uniform mat4 viewMatrix;
uniform mat4 projMatrix;
uniform mat4 viewportMatrix;
uniform mat4 prevViewMatrix;
uniform mat4 prevProjMatrix;
uniform uint tindex;
uniform uint x;
uniform uint y;
bool intersects(Ray ray, vec4[3] positions, inout vec4 intersection, inout float u, inout float v) {
//Möller Trumbore.
vec3 v0v1 = (positions[1] - positions[0]).xyz;
vec3 v0v2 = (positions[2] - positions[0]).xyz;
vec3 v0 = positions[0].xyz;
float wv0 = positions[0].w;
vec3 v1 = positions[1].xyz;
float wv1 = positions[1].w;
vec3 v2 = positions[2].xyz;
float wv2 = positions[2].w;
vec3 pvec = cross(ray.dir, v0v2);
float det = dot(v0v1, pvec);
if (abs(det) < 0.000001) return false;
float invDet = 1 / det;
vec3 tvec = ray.origin - v0;
u = dot(tvec, pvec) * invDet;
if (u < 0 || u > 1) return false;
vec3 qvec = cross(tvec, v0v1);
v = dot(ray.dir, qvec) * invDet;
if (v < 0 || u + v > 1) return false;
float t = dot(v0v2, qvec) * invDet;
intersection = vec4(ray.origin + t * ray.dir, u * wv0 + v * wv1 + (1-u-v) * wv2);
return true;
}
bool intersects (Ray ray, Light light) {
vec3 omc = ray.origin - light.center.xyz;
float b = dot(ray.dir, omc);
float c = dot(omc, omc) - light.radius * light.radius;
float bsqmc = b * b - c;
if (bsqmc >= 0)
return true;
return false;
}
Pixel interpolate(Triangle triangle, vec3 p, float u, float v) {
Pixel pixel;
float w = 1 - u - v;
pixel.position = p;
vec3 r = vec3(triangle.color[0].r, triangle.color[1].r, triangle.color[2].r);
vec3 g = vec3(triangle.color[0].g, triangle.color[1].g, triangle.color[2].g);
vec3 b = vec3(triangle.color[0].b, triangle.color[1].b, triangle.color[2].b);
vec3 a = vec3(triangle.color[0].a, triangle.color[1].a, triangle.color[2].a);
vec4 color = vec4 (r.x * u + r.y * v + r.z * w,
g.x * u + g.y * v + g.z * w,
b.x * u + b.y * v + b.z * w,
a.x * u + a.y * v + a.z * w);
vec2 tc1 = (triangle.textureMatrix * triangle.texCoords[0]).xy;
vec2 tc2 = (triangle.textureMatrix * triangle.texCoords[1]).xy;
vec2 tc3 = (triangle.textureMatrix * triangle.texCoords[2]).xy;)" R"(pixel.texCoords = vec2(tc1.x * u + tc2.x * v + tc3.x * w,
tc1.y * u + tc2.y * v + tc3.y * w);
pixel.texCoords = clamp(pixel.texCoords, 0.0, 1.0);
pixel.color = (triangle.textureIndex > 0) ? color * texture(textures[triangle.textureIndex-1], pixel.texCoords) : color;
return pixel;
}
void main() {
vec4 pixel = vec4(1.0, 0.0, 0.0, 1.0);
ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy);
Ray ray;
ray.origin = vec3(pixel_coords.xy, 0.99);
ray.ext = vec3 (pixel_coords.xy, 0);
ray.dir = ray.ext - ray.origin;
Pixel depthPixels[MAX_FRAGMENTS];
Pixel currentPixel;
int count = 0;
for (unsigned int i = 0; i < nbTriangles; i++) {
Triangle tri = triangles[i];
for (uint j = 0; j < 3; j++) {
vec4 t = projMatrix * viewMatrix * triangles[i].transform * triangles[i].position[j];
if (t.w != 0) {
t /= t.w;
}
tri.position[j] = viewportMatrix * t;
}
vec4 intersection;
float u, v;
if (intersects(ray, tri.position, intersection, u, v)
&& intersection.x >= 0 && intersection.x < resolution.x
&& intersection.y >= 0 && intersection.y < resolution.y) {
currentPixel = interpolate(tri, intersection.xyz, u, v);
uint nodeIdx = atomicCounterIncrement(nextNodeCounter);
if (nodeIdx < maxNodes) {
uint prevHead = imageAtomicExchange(headPointers, pixel_coords, nodeIdx);
nodes[nodeIdx].color = currentPixel.color;
nodes[nodeIdx].depth = intersection.z;
nodes[nodeIdx].next = prevHead;
}
}
}
}
)";
if (!rayComputeShader.loadFromMemory(raytracingShaderCode, Shader::Compute)) {
throw core::Erreur(60, "failed to load raytracing compute shader!", 3);
}
if (!quadShader.loadFromMemory(quadVertexShader, quadFragmentShader)) {
throw core::Erreur(61, "failed to load quad shader!", 3);
}
rayComputeShader.setParameter("maxNodes", maxNodes);
rayComputeShader.setParameter("resolution", resolution.x, resolution.y, resolution.z);
math::Matrix4f viewMatrix = window.getDefaultView().getViewMatrix().getMatrix().transpose();
math::Matrix4f projMatrix = window.getDefaultView().getProjMatrix().getMatrix().transpose();
quadShader.setParameter("viewMatrix", viewMatrix);
quadShader.setParameter("projectionMatrix", projMatrix);
quadShader.setParameter("worldMat", quad.getTransform().getMatrix().transpose());
std::vector<Texture*> allTextures = Texture::getAllTextures();
Samplers allSamplers{};
for (unsigned int i = 0; i < allTextures.size(); i++) {
GLuint64 handle_texture = glGetTextureHandleARB(allTextures[i]->getNativeHandle());
glMakeTextureHandleResidentARB(handle_texture);
allSamplers.tex[i].handle = handle_texture;
}
glCheck(glGenBuffers(1, &ubo));
unsigned int ubid;
glCheck(ubid = glGetUniformBlockIndex(rayComputeShader.getHandle(), "ALL_TEXTURES"));
glCheck(glUniformBlockBinding(rayComputeShader.getHandle(), ubid, 0));
backgroundColor = sf::Color::Transparent;
glCheck(glBindBuffer(GL_UNIFORM_BUFFER, ubo));
glCheck(glBufferData(GL_UNIFORM_BUFFER, sizeof(allSamplers),allSamplers.tex, GL_STATIC_DRAW));
glCheck(glBindBuffer(GL_UNIFORM_BUFFER, 0));
glCheck(glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo));
glCheck(glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicBuffer));
glCheck(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, linkedListBuffer));
glCheck(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, trianglesSSBO));
glCheck(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, lightsSSBO));
dataReady = false;
firstFrame = true;
}
void RaytracingRenderComponent::setBackgroundColor(sf::Color color) {
backgroundColor = color;
}
void RaytracingRenderComponent::clear() {
frameBuffer.setActive();
frameBuffer.clear(sf::Color::Transparent);
glCheck(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, clearBuf));
glCheck(glBindTexture(GL_TEXTURE_2D, frameBufferTex));
glCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, view.getSize().x, view.getSize().y, GL_RGBA,
GL_FLOAT, NULL));
glCheck(glBindTexture(GL_TEXTURE_2D, 0));
glCheck(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
GLuint zero = 0;
glCheck(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer));
glCheck(glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), &zero));
glCheck(glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0));
glCheck(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, clearBuf2));
glCheck(glBindTexture(GL_TEXTURE_2D, headPtrTex));
glCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, view.getSize().x, view.getSize().y, GL_RED_INTEGER,
GL_UNSIGNED_INT, NULL));
glCheck(glBindTexture(GL_TEXTURE_2D, 0));
glCheck(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
frameBuffer.resetGLStates();
}
void RaytracingRenderComponent::drawNextFrame() {
if (frameBuffer.getSettings().versionMajor >= 4 && frameBuffer.getSettings().versionMinor >= 6) {
if (dataReady) {
glCheck(glBindBuffer(GL_SHADER_STORAGE_BUFFER, trianglesSSBO));
glCheck(glBufferData(GL_SHADER_STORAGE_BUFFER, triangles.size() * sizeof(Triangle), triangles.data(), GL_DYNAMIC_DRAW));
/*GLvoid* p = nullptr;
glCheck(p = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY));
memcpy(p, triangles.data(), triangles.size() * sizeof(Triangle));
glCheck(glUnmapBuffer(GL_SHADER_STORAGE_BUFFER));*/
glCheck(glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightsSSBO));
glCheck(glBufferData(GL_SHADER_STORAGE_BUFFER, lights.size() * sizeof(Light), lights.data(), GL_DYNAMIC_DRAW));
/*GLvoid* p2 = nullptr;
glCheck(p2 = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY));
memcpy(p2, lights.data(), lights.size() * sizeof(Light));
glCheck(glUnmapBuffer(GL_SHADER_STORAGE_BUFFER));
glCheck(glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0));*/
unsigned int nbTriangles = triangles.size();
unsigned int nbLights = lights.size();
rayComputeShader.setParameter("nbTriangles", nbTriangles);
rayComputeShader.setParameter("nbLights", nbLights);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
dataReady = false;
}
math::Matrix4f viewMatrix = view.getViewMatrix().getMatrix().transpose();
math::Matrix4f projMatrix = view.getProjMatrix().getMatrix().transpose();
math::Matrix4f prevViewMatrix = prevView.getViewMatrix().getMatrix().transpose();
math::Matrix4f prevProjMatrix = prevView.getProjMatrix().getMatrix().transpose();
ViewportMatrix vpm;
vpm.setViewport(math::Vec3f(view.getViewport().getPosition().x, view.getViewport().getPosition().y, 0),
math::Vec3f(view.getViewport().getWidth(), view.getViewport().getHeight(), 1));
math::Matrix4f viewportMatrix = vpm.getMatrix().transpose();
rayComputeShader.setParameter("viewMatrix", viewMatrix);
rayComputeShader.setParameter("projMatrix", projMatrix);
rayComputeShader.setParameter("viewportMatrix", viewportMatrix);
Shader::bind(&rayComputeShader);
glCheck(glDispatchCompute(view.getSize().x, view.getSize().y, 1));
glCheck(glFinish());
// make sure writing to image has finished before read
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
/*glCheck(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, clearBuf2));
glCheck(glBindTexture(GL_TEXTURE_2D, historyColorBuffer));
glCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, view.getSize().x, view.getSize().y, GL_RED_INTEGER,
GL_UNSIGNED_INT, NULL));
glCheck(glBindTexture(GL_TEXTURE_2D, historyNormalDepthBuffer));
glCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, view.getSize().x, view.getSize().y, GL_RED_INTEGER,
GL_UNSIGNED_INT, NULL));
glCheck(glBindTexture(GL_TEXTURE_2D, 0));
glCheck(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));*/
RenderStates states;
states.shader = &quadShader;
vb.clear();
vb.setPrimitiveType(sf::Quads);
Vertex v1 (sf::Vector3f(0, 0, quad.getSize().z)/*, sf::Color::White,sf::Vector2f(0, 0)*/);
Vertex v2 (sf::Vector3f(quad.getSize().x,0, quad.getSize().z)/*, sf::Color::White,sf::Vector2f(quad.getSize().x, 0)*/);
Vertex v3 (sf::Vector3f(quad.getSize().x, quad.getSize().y, quad.getSize().z)/*,sf::Color::White,sf::Vector2f(quad.getSize().x, quad.getSize().y)*/);
Vertex v4 (sf::Vector3f(0, quad.getSize().y, quad.getSize().z)/*, sf::Color::White,sf::Vector2f(0, quad.getSize().y)*/);
vb.append(v1);
vb.append(v2);
vb.append(v3);
vb.append(v4);
vb.update();
frameBuffer.drawVertexBuffer(vb, states);
glCheck(glFinish());
frameBuffer.display();
firstFrame = false;
}
}
void RaytracingRenderComponent::loadTextureIndexes() {
}
bool RaytracingRenderComponent::loadEntitiesOnComponent(std::vector<Entity*> vEntities) {
//std::cout<<"load entities on component"<<std::endl;
dataReady = false;
triangles.clear();
lights.clear();
Light ambientLight;
g2d::AmbientLight al = g2d::AmbientLight::getAmbientLight();
ambientLight.center = math::Vec3f(al.getLightCenter().x, al.getLightCenter().y, al.getLightCenter().z);
ambientLight.radius = 10000;
ambientLight.color = math::Vec3f(al.getColor().r/255.f, al.getColor().g/255.f, al.getColor().b/255.f, al.getColor().a/255.f);
lights.push_back(ambientLight);
unsigned int nbVertices =0;
for (unsigned int e = 0; e < vEntities.size(); e++) {
if ( vEntities[e] != nullptr && vEntities[e]->isLeaf()) {
if (!vEntities[e]->isLight()) {
for (unsigned int j = 0; j < vEntities[e]->getNbFaces(); j++) {
Material material = vEntities[e]->getFace(j)->getMaterial();
VertexArray va = vEntities[e]->getFace(j)->getVertexArray();
unsigned int size = 0;
if (va.getPrimitiveType() == sf::PrimitiveType::Quads) {
size = va.getVertexCount() / 4;
} else if (va.getPrimitiveType() == sf::PrimitiveType::Triangles) {
size = va.getVertexCount() / 3;
} else if (va.getPrimitiveType() == sf::PrimitiveType::TriangleStrip || va.getPrimitiveType() == sf::PrimitiveType::TriangleFan) {
size = va.getVertexCount() - 2;
}
for (unsigned int i = 0; i < size; i++) {
if (va.getPrimitiveType() == sf::PrimitiveType::Quads) {
for (unsigned int n = 0; n < 2; n++) {
if (n == 0) {
Triangle triangle;
triangle.positions[0] = math::Vec3f(va[i*4].position.x,va[i*4].position.y,va[i*4].position.z);
triangle.positions[1] = math::Vec3f(va[i*4+1].position.x,va[i*4+1].position.y,va[i*4+1].position.z);
triangle.positions[2] = math::Vec3f(va[i*4+2].position.x,va[i*4+2].position.y,va[i*4+2].position.z);
triangle.colours[0] = math::Vec3f(va[i*4].color.r / 255.f,va[i*4].color.g / 255.f,va[i*4].color.b / 255.f, va[i*4].color.a / 255.f);
triangle.colours[1] = math::Vec3f(va[i*4+1].color.r / 255.f,va[i*4+1].color.g / 255.f,va[i*4+1].color.b / 255.f, va[i*4+1].color.a / 255.f);
triangle.colours[2] = math::Vec3f(va[i*4+2].color.r / 255.f,va[i*4+2].color.g / 255.f,va[i*4+2].color.b / 255.f, va[i*4+2].color.a / 255.f);
triangle.texCoords[0] = math::Vec3f(va[i*4].texCoords.x, va[i*4].texCoords.y, 0, 0);
triangle.texCoords[1] = math::Vec3f(va[i*4+1].texCoords.x, va[i*4+1].texCoords.y, 0, 0);
triangle.texCoords[2] = math::Vec3f(va[i*4+2].texCoords.x, va[i*4+2].texCoords.y, 0, 0);
math::Vec3f v1(va[i*4].position.x, va[i*4].position.y, va[i*4].position.z);
math::Vec3f v2(va[i*4+1].position.x, va[i*4+1].position.y, va[i*4+1].position.z);
math::Vec3f v3(va[i*4+2].position.x, va[i*4+2].position.y, va[i*4+2].position.z);
math::Vec3f d1 = v2 - v1;
math::Vec3f d2 = v3 - v1;
math::Vec3f n = d1.cross(d2).normalize();
triangle.normal = math::Vec3f(n.x, n.y, n.z);
triangle.ratio = material.getRefractionFactor();
math::Matrix4f m;
triangle.textureIndex = (material.getTexture() == nullptr) ? 0 : material.getTexture()->getNativeHandle();
//std::cout<<"texture index : "<<triangle.textureIndex<<std::endl;
triangle.textureMatrix = (material.getTexture() == nullptr) ? m : material.getTexture()->getTextureMatrix();
triangle.transform = vEntities[e]->getTransform().getMatrix().transpose();
if (!material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 0;
else if (material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 1;
else if (!material.isReflectable() && material.isRefractable())
triangle.refractReflect = 2;
else
triangle.refractReflect = 3;
triangles.push_back(triangle);
} else {
Triangle triangle;
triangle.positions[0] = math::Vec3f(va[i*4].position.x,va[i*4].position.y,va[i*4].position.z);
triangle.positions[1] = math::Vec3f(va[i*4+2].position.x,va[i*4+2].position.y,va[i*4+2].position.z);
triangle.positions[2] = math::Vec3f(va[i*4+3].position.x,va[i*4+3].position.y,va[i*4+3].position.z);
triangle.colours[0] = math::Vec3f(va[i*4].color.r / 255.f,va[i*4].color.g / 255.f,va[i*4].color.b / 255.f, va[i*4].color.a / 255.f);
triangle.colours[1] = math::Vec3f(va[i*4+2].color.r / 255.f,va[i*4+2].color.g / 255.f,va[i*4+2].color.b / 255.f, va[i*4+2].color.a / 255.f);
triangle.colours[2] = math::Vec3f(va[i*4+3].color.r / 255.f,va[i*4+3].color.g / 255.f,va[i*4+3].color.b / 255.f, va[i*4+3].color.a / 255.f);
triangle.texCoords[0] = math::Vec3f(va[i*4].texCoords.x, va[i*4].texCoords.y, 0, 0);
triangle.texCoords[1] = math::Vec3f(va[i*4+2].texCoords.x, va[i*4+2].texCoords.y, 0, 0);
triangle.texCoords[2] = math::Vec3f(va[i*4+3].texCoords.x, va[i*4+3].texCoords.y, 0, 0);
/*for (unsigned int v = 0; v < 3; v++) {
std::cout<<va[i*4+v+1].position.x<<","<<va[i*4+v+1].position.y<<","<<va[i*4+v+1].position.z<<std::endl;
}*/
math::Vec3f v1(va[i*4].position.x, va[i*4].position.y, va[i*4].position.z);
math::Vec3f v2(va[i*4+2].position.x, va[i*4+2].position.y, va[i*4+2].position.z);
math::Vec3f v3(va[i*4+3].position.x, va[i*4+3].position.y, va[i*4+3].position.z);
math::Vec3f d1 = v2 - v1;
math::Vec3f d2 = v3 - v1;
math::Vec3f n = d1.cross(d2).normalize();
triangle.normal = math::Vec3f(n.x, n.y, n.z);
triangle.ratio = material.getRefractionFactor();
math::Matrix4f m;
triangle.textureIndex = (material.getTexture() == nullptr) ? 0 : material.getTexture()->getNativeHandle();
triangle.textureMatrix = (material.getTexture() == nullptr) ? m : material.getTexture()->getTextureMatrix();
triangle.transform = vEntities[e]->getTransform().getMatrix().transpose();
if (!material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 0;
else if (material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 1;
else if (!material.isReflectable() && material.isRefractable())
triangle.refractReflect = 2;
else
triangle.refractReflect = 3;
triangles.push_back(triangle);
}
}
} else if (va.getPrimitiveType() == sf::PrimitiveType::Triangles) {
Triangle triangle;
triangle.positions[0] = math::Vec3f(va[i*3].position.x,va[i*3].position.y,va[i*3].position.z);
triangle.positions[1] = math::Vec3f(va[i*3+1].position.x,va[i*3+1].position.y,va[i*3+1].position.z);
triangle.positions[2] = math::Vec3f(va[i*3+2].position.x,va[i*3+2].position.y,va[i*3+2].position.z);
triangle.colours[0] = math::Vec3f(va[i*3].color.r / 255.f,va[i*3].color.g / 255.f,va[i*3].color.b / 255.f, va[i*3].color.a / 255.f);
triangle.colours[1] = math::Vec3f(va[i*3+1].color.r / 255.f,va[i*3+1].color.g / 255.f,va[i*3+1].color.b / 255.f, va[i*3+1].color.a / 255.f);
triangle.colours[2] = math::Vec3f(va[i*3+2].color.r / 255.f,va[i*3+2].color.g / 255.f,va[i*3+2].color.b / 255.f, va[i*3+2].color.a / 255.f);
triangle.texCoords[0] = math::Vec3f(va[i*3].texCoords.x, va[i*3].texCoords.y, 0, 0);
triangle.texCoords[1] = math::Vec3f(va[i*3+1].texCoords.x, va[i*3+1].texCoords.y, 0, 0);
triangle.texCoords[2] = math::Vec3f(va[i*3+2].texCoords.x, va[i*3+2].texCoords.y, 0, 0);
math::Vec3f v1(va[i*3].position.x, va[i*3].position.y, va[i*3].position.z);
math::Vec3f v2(va[i*3+1].position.x, va[i*3+1].position.y, va[i*3+1].position.z);
math::Vec3f v3(va[i*3+2].position.x, va[i*3+2].position.y, va[i*3+2].position.z);
math::Vec3f d1 = v2 - v1;
math::Vec3f d2 = v3 - v1;
math::Vec3f n = d1.cross(d2).normalize();
triangle.normal = math::Vec3f(n.x, n.y, n.z);
triangle.ratio = material.getRefractionFactor();
math::Matrix4f m;
triangle.textureIndex = (material.getTexture() == nullptr) ? 0 : material.getTexture()->getNativeHandle();
triangle.textureMatrix = (material.getTexture() == nullptr) ? m : material.getTexture()->getTextureMatrix();
triangle.transform = vEntities[e]->getTransform().getMatrix().transpose();
if (!material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 0;
else if (material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 1;
else if (!material.isReflectable() && material.isRefractable())
triangle.refractReflect = 2;
else
triangle.refractReflect = 3;
triangles.push_back(triangle);
} else if (va.getPrimitiveType() == sf::PrimitiveType::TriangleStrip) {
std::cout<<"triangle strip"<<std::endl;
if (i == 0) {
Triangle triangle;
triangle.positions[0] = math::Vec3f(va[i*3].position.x,va[i*3].position.y,va[i*3].position.z);
triangle.positions[1] = math::Vec3f(va[i*3+1].position.x,va[i*3+1].position.y,va[i*3+1].position.z);
triangle.positions[2] = math::Vec3f(va[i*3+2].position.x,va[i*3+2].position.y,va[i*3+2].position.z);
triangle.colours[0] = math::Vec3f(va[i*3].color.r / 255.f,va[i*3].color.g / 255.f,va[i*3].color.b / 255.f, va[i*3].color.a / 255.f);
triangle.colours[1] = math::Vec3f(va[i*3+1].color.r / 255.f,va[i*3+1].color.g / 255.f,va[i*3+1].color.b / 255.f, va[i*3+1].color.a / 255.f);
triangle.colours[2] = math::Vec3f(va[i*3+2].color.r / 255.f,va[i*3+2].color.g / 255.f,va[i*3+2].color.b / 255.f, va[i*3+2].color.a / 255.f);
triangle.texCoords[0] = math::Vec3f(va[i*3].texCoords.x, va[i*3].texCoords.y, 0, 0);
triangle.texCoords[1] = math::Vec3f(va[i*3+1].texCoords.x, va[i*3+1].texCoords.y, 0, 0);
triangle.texCoords[2] = math::Vec3f(va[i*3+2].texCoords.x, va[i*3+2].texCoords.y, 0, 0);
math::Vec3f v1(va[i*3].position.x, va[i*3].position.y, va[i*3].position.z);
math::Vec3f v2(va[i*3+1].position.x, va[i*3+1].position.y, va[i*3+1].position.z);
math::Vec3f v3(va[i*3+2].position.x, va[i*3+2].position.y, va[i*3+2].position.z);
math::Vec3f d1 = v2 - v1;
math::Vec3f d2 = v3 - v1;
math::Vec3f n = d1.cross(d2).normalize();
triangle.normal = math::Vec3f(n.x, n.y, n.z);
triangle.ratio = material.getRefractionFactor();
math::Matrix4f m;
triangle.textureIndex = (material.getTexture() == nullptr) ? 0 : material.getTexture()->getNativeHandle();
triangle.textureMatrix = (material.getTexture() == nullptr) ? m : material.getTexture()->getTextureMatrix();
triangle.transform = vEntities[e]->getTransform().getMatrix().transpose();
if (!material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 0;
else if (material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 1;
else if (!material.isReflectable() && material.isRefractable())
triangle.refractReflect = 2;
else
triangle.refractReflect = 3;
triangles.push_back(triangle);
} else {
Triangle triangle;
triangle.positions[0] = math::Vec3f(va[i].position.x,va[i].position.y,va[i].position.z);;
triangle.positions[1] = math::Vec3f(va[i+1].position.x,va[i+1].position.y,va[i+1].position.z);
triangle.positions[2] = math::Vec3f(va[i+2].position.x,va[i+2].position.y,va[i+2].position.z);
triangle.colours[0] = math::Vec3f(va[i].color.r / 255.f,va[i].color.g / 255.f,va[i].color.b / 255.f, va[i].color.a / 255.f);
triangle.colours[1] = math::Vec3f(va[i+1].color.r / 255.f,va[i+1].color.g / 255.f,va[i+1].color.b / 255.f, va[i+1].color.a / 255.f);
triangle.colours[2] = math::Vec3f(va[i+2].color.r / 255.f,va[i+2].color.g / 255.f,va[i+2].color.b / 255.f, va[i+2].color.a / 255.f);
triangle.texCoords[0] = math::Vec3f(va[i].texCoords.x, va[i].texCoords.y, 0, 0);
triangle.texCoords[1] = math::Vec3f(va[i+1].texCoords.x, va[i+1].texCoords.y, 0, 0);
triangle.texCoords[2] = math::Vec3f(va[i+2].texCoords.x, va[i+2].texCoords.y, 0, 0);
math::Vec3f v1(va[i].position.x, va[i].position.y, va[i].position.z);
math::Vec3f v2(va[i+1].position.x, va[i+1].position.y, va[i+1].position.z);
math::Vec3f v3(va[i+2].position.x, va[i+2].position.y, va[i+2].position.z);
math::Vec3f d1 = v2 - v1;
math::Vec3f d2 = v3 - v1;
math::Vec3f n = d1.cross(d2).normalize();
triangle.normal = math::Vec3f(n.x, n.y, n.z);
triangle.ratio = material.getRefractionFactor();
math::Matrix4f m;
triangle.textureIndex = (material.getTexture() == nullptr) ? 0 : material.getTexture()->getNativeHandle();
triangle.textureMatrix = (material.getTexture() == nullptr) ? m : material.getTexture()->getTextureMatrix();
triangle.transform = vEntities[e]->getTransform().getMatrix().transpose();
if (!material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 0;
else if (material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 1;
else if (!material.isReflectable() && material.isRefractable())
triangle.refractReflect = 2;
else
triangle.refractReflect = 3;
triangles.push_back(triangle);
}
} else if (va.getPrimitiveType() == sf::TriangleFan) {
std::cout<<"triangle fan"<<std::endl;
if (i == 0) {
Triangle triangle;
triangle.positions[0] = math::Vec3f(va[i*3].position.x,va[i*3].position.y,va[i*3].position.z);;
triangle.positions[1] = math::Vec3f(va[i*3+1].position.x,va[i*3+1].position.y,va[i*3+1].position.z);;
triangle.positions[2] = math::Vec3f(va[i*3+2].position.x,va[i*3+2].position.y,va[i*3+2].position.z);;
triangle.colours[0] = math::Vec3f(va[i*3].color.r / 255.f,va[i*3].color.g / 255.f,va[i*3].color.b / 255.f, va[i*3].color.a / 255.f);
triangle.colours[1] = math::Vec3f(va[i*3+1].color.r / 255.f,va[i*3+1].color.g / 255.f,va[i*3+1].color.b / 255.f, va[i*3+1].color.a / 255.f);
triangle.colours[2] = math::Vec3f(va[i*3+2].color.r / 255.f,va[i*3+2].color.g / 255.f,va[i*3+2].color.b / 255.f, va[i*3+2].color.a / 255.f);
triangle.texCoords[0] = math::Vec3f(va[i*3].texCoords.x, va[i*3].texCoords.y, 0, 0);
triangle.texCoords[1] = math::Vec3f(va[i*3+1].texCoords.x, va[i*3+1].texCoords.y, 0, 0);
triangle.texCoords[2] = math::Vec3f(va[i*3+2].texCoords.x, va[i*3+2].texCoords.y, 0, 0);
math::Vec3f v1(va[i*3].position.x, va[i*3].position.y, va[i*3].position.z);
math::Vec3f v2(va[i*3+1].position.x, va[i*3+1].position.y, va[i*3+1].position.z);
math::Vec3f v3(va[i*3+2].position.x, va[i*3+2].position.y, va[i*3+2].position.z);
math::Vec3f d1 = v2 - v1;
math::Vec3f d2 = v3 - v1;
math::Vec3f n = d1.cross(d2).normalize();
triangle.normal = math::Vec3f(n.x, n.y, n.z);
triangle.ratio = material.getRefractionFactor();
math::Matrix4f m;
triangle.textureIndex = (material.getTexture() == nullptr) ? 0 : material.getTexture()->getNativeHandle();
triangle.textureMatrix = (material.getTexture() == nullptr) ? m : material.getTexture()->getTextureMatrix();
triangle.transform = vEntities[e]->getTransform().getMatrix().transpose();
if (!material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 0;
else if (material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 1;
else if (!material.isReflectable() && material.isRefractable())
triangle.refractReflect = 2;
else
triangle.refractReflect = 3;
triangles.push_back(triangle);
} else {
Triangle triangle;
triangle.positions[0] = math::Vec3f(va[0].position.x,va[0].position.y,va[0].position.z);;
triangle.positions[1] = math::Vec3f(va[i+1].position.x,va[i+1].position.y,va[i+1].position.z);;
triangle.positions[2] = math::Vec3f(va[i+2].position.x,va[i+2].position.y,va[i+2].position.z);
triangle.colours[0] = math::Vec3f(va[0].color.r / 255.f,va[0].color.g / 255.f,va[0].color.b / 255.f, va[0].color.a / 255.f);
triangle.colours[1] = math::Vec3f(va[i+1].color.r / 255.f,va[i+1].color.g / 255.f,va[i+1].color.b / 255.f, va[i+1].color.a / 255.f);
triangle.colours[2] = math::Vec3f(va[i+2].color.r / 255.f,va[i+2].color.g / 255.f,va[i+2].color.b / 255.f, va[i+2].color.a / 255.f);
triangle.texCoords[0] = math::Vec3f(va[0].texCoords.x, va[0].texCoords.y, 0, 0);
triangle.texCoords[1] = math::Vec3f(va[i+1].texCoords.x, va[i+1].texCoords.y, 0, 0);
triangle.texCoords[2] = math::Vec3f(va[i+2].texCoords.x, va[i+2].texCoords.y, 0, 0);
math::Vec3f v1(va[0].position.x, va[0].position.y, va[0].position.z);
math::Vec3f v2(va[i+1].position.x, va[i+1].position.y, va[i+1].position.z);
math::Vec3f v3(va[i+2].position.x, va[i+2].position.y, va[i+2].position.z);
math::Vec3f d1 = v2 - v1;
math::Vec3f d2 = v3 - v1;
math::Vec3f n = d1.cross(d2).normalize();
triangle.normal = math::Vec3f(n.x, n.y, n.z);
triangle.ratio = material.getRefractionFactor();
math::Matrix4f m;
triangle.textureIndex = (material.getTexture() == nullptr) ? 0 : material.getTexture()->getNativeHandle();
triangle.textureMatrix = (material.getTexture() == nullptr) ? m : material.getTexture()->getTextureMatrix();
triangle.transform = vEntities[e]->getTransform().getMatrix().transpose();
if (!material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 0;
else if (material.isReflectable() && !material.isRefractable())
triangle.refractReflect = 1;
else if (!material.isReflectable() && material.isRefractable())
triangle.refractReflect = 2;
else
triangle.refractReflect = 3;
triangles.push_back(triangle);
}
} else {
Light light;
g2d::PonctualLight* pl = static_cast<g2d::PonctualLight*>(vEntities[e]);
light.center = math::Vec3f(pl->getCenter().x, pl->getCenter().y, pl->getCenter().z);
light.radius = pl->getSize().y * 0.5f;
light.color = math::Vec3f(pl->getColor().r / 255.f,pl->getColor().g/255.f,pl->getColor().b/255.f,pl->getColor().a/255.f);
lights.push_back(light);
}
}
}
}
}
}
update = true;
dataReady = true;
return true;
}
void RaytracingRenderComponent::draw(RenderTarget& target, RenderStates states) {
frameBufferSprite.setCenter(target.getView().getPosition());
/*states.texture = &external;
states.transform = quad.getTransform();
View view = target.getView();
target.setView(target.getDefaultView());*/
target.draw(frameBufferSprite, states);
//target.setView(view);
}
bool RaytracingRenderComponent::needToUpdate() {
return update;
}
void RaytracingRenderComponent::setExpression (std::string expression) {
this->expression = expression;
}
void RaytracingRenderComponent::draw(Drawable& drawable, RenderStates states) {
//drawables.insert(std::make_pair(drawable, states));
}
void RaytracingRenderComponent::setView(View view) {
prevView = this->view;
frameBuffer.setView(view);
sf::Vector3i resolution ((int) view.getSize().x, (int) view.getSize().y, view.getSize().z);
rayComputeShader.setParameter("resolution", resolution.x, resolution.y, resolution.z);
this->view = view;
}
std::vector<Entity*> RaytracingRenderComponent::getEntities() {
return visibleEntities;
}
std::string RaytracingRenderComponent::getExpression() {
return expression;
}
View& RaytracingRenderComponent::getView() {
return view;
}
void RaytracingRenderComponent::pushEvent(window::IEvent event, RenderWindow& rw) {
if (event.type == window::IEvent::WINDOW_EVENT && event.window.type == window::IEvent::WINDOW_EVENT_RESIZED && &getWindow() == &rw && isAutoResized()) {
std::cout<<"recompute size"<<std::endl;
recomputeSize();
getListener().pushEvent(event);
getView().reset(physic::BoundingBox(getView().getViewport().getPosition().x, getView().getViewport().getPosition().y, getView().getViewport().getPosition().z, event.window.data1, event.window.data2, getView().getViewport().getDepth()));
}
}
const Texture& RaytracingRenderComponent::getFrameBufferTexture() {
return frameBuffer.getTexture();
}
RenderTexture* RaytracingRenderComponent::getFrameBuffer() {
return &frameBuffer;
}
RaytracingRenderComponent::~RaytracingRenderComponent() {
glDeleteBuffers(1, &trianglesSSBO);
glDeleteBuffers(1, &lightsSSBO);
glDeleteBuffers(1, &clearBuf);
glDeleteTextures(1, &frameBufferTex);
glDeleteBuffers(1, &atomicBuffer);
glDeleteBuffers(1, &linkedListBuffer);
glDeleteBuffers(1, &clearBuf2);
glDeleteTextures(1, &headPtrTex);
}
Thanks…
