Hello, I tried to do a things like the per pixels linked list but with an older opengl version but it’s very slow, the problem is that I need to know the number of layers in the CPU, so I nead to read the values of the depth Texture in the CPU :
[code=cpp]
#include “…/…/…/include/odfaeg/Graphics/oitRenderComponent.h”
#include “glCheck.h”
#include <memory.h>
using namespace sf;
using namespace std;
namespace odfaeg {
namespace graphic {
OITRenderComponent::OITRenderComponent (RenderWindow& window, int layer, std::string expression, sf::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) {
update = false;
sf::Vector3i resolution ((int) window.getSize().x, (int) window.getSize().y, window.getView().getSize().z);
settings.depthBits = 0;
settings.stencilBits = 0;
frameBuffer.create(resolution.x, resolution.y,settings);
settings.depthBits = 32;
frontBuffer.create(resolution.x, resolution.y,settings);
depthBuffer.create(resolution.x, resolution.y,settings);
//frameBuffer.setAlphaTestEnabled(false);
frontBuffer.setView(window.getView());
depthBuffer.setView(window.getView());
frameBuffer.setView(window.getView());
//averageBlendEqPart2.setAlphaTestEnabled(false);
frontBufferSprite = Sprite (frontBuffer.getTexture(), math::Vec3f(0, 0, 0), math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0), IntRect(0, 0, window.getView().getSize().x, window.getView().getSize().y));
depthBufferSprite = Sprite (depthBuffer.getTexture(), math::Vec3f(0, 0, 0), math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0), IntRect(0, 0, window.getView().getSize().x, window.getView().getSize().y));
frameBufferSprite = Sprite(frameBuffer.getTexture(), math::Vec3f(0, 0, 0), math::Vec3f(window.getView().getSize().x, window.getView().getSize().y, 0), IntRect(0, 0, window.getView().getSize().x, window.getView().getSize().y));
core::FastDelegate<bool> signal (&OITRenderComponent::needToUpdate, this);
core::FastDelegate<void> slot (&OITRenderComponent::drawNextFrame, this);
core::Command cmd(signal, slot);
getListener().connect(“UPDATE”, cmd);
if (Shader::isAvailable()) {
const std::string vertexShader =
"#version 130
"
“out mat4 projMat;”
“void main () {”
“gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;”
“gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;”
“gl_FrontColor = gl_Color;”
“projMat = gl_ProjectionMatrix;”
“}”;
const std::string simpleVertexShader =
"#version 130
"
“void main () {”
“gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;”
“gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;”
“gl_FrontColor = gl_Color;”
“}”;
const std::string depthGenFragShader =
"#version 130
"
“in mat4 projMat;”
“uniform sampler2D texture;”
“uniform float haveTexture;”
“void main () {”
“vec4 texel = texture2D(texture, gl_TexCoord[0].xy);”
“vec4 colors[2];”
“colors[1] = texel * gl_Color;”
“colors[0] = gl_Color;”
“bool b = (haveTexture > 0.9);”
“vec4 color = colors[int(b)];”
“float z = (gl_FragCoord.w != 1.f) ? (inverse(projMat) * vec4(0, 0, 0, gl_FragCoord.w)).w : gl_FragCoord.z;”
“gl_FragColor = vec4(0, 0, z, color.a);”
“}”;
const std::string frameBufferGenFragShader =
"#version 130
"
“uniform sampler2D depthBuffer;”
“uniform sampler2D texture;”
“uniform vec3 resolution;”
“uniform float haveTexture;”
“in mat4 projMat;”
“void main () {”
“vec2 position = ( gl_FragCoord.xy / resolution.xy );”
“float max_z = texture2D(depthBuffer, position).z;”
“vec4 texel = texture2D(texture, gl_TexCoord[0].xy);”
“vec4 colors[2];”
“colors[1] = texel * gl_Color;”
“colors[0] = gl_Color;”
“bool b = (haveTexture > 0.9);”
“vec4 color = colors[int(b)];”
“float z = (gl_FragCoord.w != 1.f) ? (inverse(projMat) * vec4(0, 0, 0, gl_FragCoord.w)).w : gl_FragCoord.z;”
“colors[1] = color;”
“colors[0] = vec4(0, 0, 0, 0);”
“b = (z < max_z);”
“gl_FragColor = colors[int(b)];”
“}”;
if (!depthBufferGenerator.loadFromMemory(vertexShader, depthGenFragShader))
throw core::Erreur(50, “Failed to load depth buffer generator shader”, 0);
if (!frameBufferGenerator.loadFromMemory(vertexShader, frameBufferGenFragShader))
throw core::Erreur(51, “Failed to load frame buffer generator shader”, 0);
//throw core::Erreur(52, “Failed to load specular texture generator shader”, 0);
/if (!bumpTextureGenerator->loadFromMemory(vertexShader, bumpGenFragShader))
throw core::Erreur(53, “Failed to load bump texture generator shader”, 0);
if (!refractionTextureGenerator->loadFromMemory(vertexShader, refractionGenFragShader))
throw core::Erreur(54, “Failed to load refraction texture generator shader”, 0);/
frameBufferGenerator.setParameter(“resolution”,resolution.x, resolution.y, resolution.z);
frameBufferGenerator.setParameter(“depthBuffer”, depthBuffer.getTexture());
frameBufferGenerator.setParameter(“texture”, Shader::CurrentTexture);
depthBufferGenerator.setParameter(“texture”, Shader::CurrentTexture);
//specularTextureGenerator->setParameter(“specularTexture”,specularTexture->getTexture());
backgroundColor = sf::Color::Transparent;
} else {
throw core::Erreur(55, “Shader not supported!”, 0);
}
}
void OITRenderComponent::pushEvent(sf::Event event, RenderWindow& rw) {
if (event.type == sf::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.size.width, event.size.height, getView().getViewport().getDepth()));
}
}
bool OITRenderComponent::needToUpdate() {
return update;
}
void OITRenderComponent::changeVisibleEntities(Entity* toRemove, Entity* toAdd, EntityManager* em) {
bool removed;
em->removeAnimatedVisibleEntity(toRemove, visibleEntities, view, removed);
if (removed) {
em->insertAnimatedVisibleEntity(toAdd, visibleEntities, view);
loadEntitiesOnComponent(visibleEntities);
update = true;
}
}
std::string OITRenderComponent::getExpression() {
return expression;
}
void OITRenderComponent::setBackgroundColor(sf::Color color) {
this->backgroundColor = color;
}
void OITRenderComponent::clear() {
frameBuffer.clear(backgroundColor);
depthBuffer.clear(sf::Color::Transparent);
frontBuffer.clear(sf::Color::Transparent);
}
Sprite& OITRenderComponent::getFrameBufferSprite () {
return frameBufferSprite;
}
Sprite& OITRenderComponent::getDepthBufferSprite() {
return depthBufferSprite;
}
Sprite& OITRenderComponent::getFrontBufferSprite() {
return frontBufferSprite;
}
const Texture& OITRenderComponent::getDepthBufferTexture() {
return depthBuffer.getTexture();
}
const Texture& OITRenderComponent::getFrameBufferTexture() {
return frameBuffer.getTexture();
}
const Texture& OITRenderComponent::getFrontBufferTexture() {
return frontBuffer.getTexture();
}
bool OITRenderComponent::loadEntitiesOnComponent(std::vector<Entity*> vEntities)
{
batcher.clear();
for (unsigned int i = 0; i < vEntities.size(); i++) {
if ( vEntities[i]->isLeaf()) {
for (unsigned int j = 0; j < vEntities[i]->getFaces().size(); j++) {
batcher.addFace( vEntities[i]->getFaces()[j]);
}
}
}
m_instances = batcher.getInstances();
visibleEntities = vEntities;
update = true;
return true;
}
void OITRenderComponent::setView(View view) {
this->view = view;
frameBuffer.setView(view);
depthBuffer.setView(view);
frontBuffer.setView(view);
}
void OITRenderComponent::setExpression(std::string expression) {
update = true;
this->expression = expression;
}
void OITRenderComponent::drawNextFrame() {
update = false;
currentStates.blendMode = sf::BlendNone;
for (unsigned int i = 0; i < m_instances.size(); i++) {
if (m_instances[i].getMaterial().getTexture() == nullptr) {
depthBufferGenerator.setParameter("haveTexture", 0);
} else {
depthBufferGenerator.setParameter("haveTexture", 1);
}
currentStates.shader=&depthBufferGenerator;
currentStates.texture=m_instances[i].getMaterial().getTexture();
depthBuffer.draw(m_instances[i].getAllVertices(),currentStates);
currentStates.shader = nullptr;
frontBuffer.draw(m_instances[i].getAllVertices(), currentStates);
}
frontBuffer.display();
frontBufferSprite.setCenter(view.getPosition());
currentStates.blendMode = sf::BlendAlpha;
frameBuffer.draw(frontBufferSprite, currentStates);
/*getWindow().draw(depthBufferSprite, currentStates);
getWindow().display();
currentStates.shader=&frameBufferGenerator;
currentStates.blendMode=sf::BlendMode(sf::BlendMode::Factor::OneMinusDstAlpha, sf::BlendMode::Factor::DstAlpha, sf::BlendMode::Equation::Add, sf::BlendMode::Factor::OneMinusDstAlpha, sf::BlendMode::Factor::One, sf::BlendMode::Equation::Add);
for (unsigned int i = 0; i < m_instances.size(); i++) {
if (m_instances[i].getMaterial().getTexture() == nullptr)
frameBufferGenerator.setParameter("haveTexture", 0);
else
frameBufferGenerator.setParameter("haveTexture", 1);
currentStates.texture = m_instances[i].getMaterial().getTexture();
frameBuffer.draw(m_instances[i].getAllVertices(), currentStates);
}*/
unsigned int size = view.getSize().x * view.getSize().y * 4;
const sf::Uint8 * data = new unsigned char[size];
depthBuffer.display();
sf::Image img = depthBuffer.getTexture().copyToImage();
data = img.getPixelsPtr();
unsigned int nbLayers = 0;
for (unsigned int i = 0; i < size / 4; i++) {
if ((float)(data[i*4+2]) > nbLayers) {
nbLayers++;
}
//std:cout<<"depthBufferdata "<<" i : "<<((float)(data[i*4]))<<","<<((float)(data[i*4+1]))<<","<<((float)(data[i*4+2]))<<","<<((float)(data[i*3]))<<std::endl;
}
//std::cout<<"nbLayers : "<<nbLayers<<std::endl;
for (unsigned int i = 0; i < nbLayers; i++) {
currentStates.shader = &frameBufferGenerator;
currentStates.blendMode = sf::BlendNone;
frontBuffer.clear(sf::Color::Transparent);
for (unsigned int i = 0; i < m_instances.size(); i++) {
if (m_instances[i].getMaterial().getTexture() == nullptr) {
frameBufferGenerator.setParameter("haveTexture", 0);
} else {
frameBufferGenerator.setParameter("haveTexture", 1);
}
currentStates.texture=m_instances[i].getMaterial().getTexture();
frontBuffer.draw(m_instances[i].getAllVertices(), currentStates);
}
frameBufferGenerator.setParameter("haveTexture", 1);
for (unsigned int i = 0; i < m_instances.size(); i++) {
currentStates.texture = &depthBuffer.getTexture();
depthBuffer.draw(m_instances[i].getAllVertices(),currentStates);
}
depthBuffer.display();
frontBuffer.display();
frontBufferSprite.setCenter(view.getPosition());
currentStates.shader = nullptr;
currentStates.blendMode = sf::BlendMode(sf::BlendMode::Factor::OneMinusDstAlpha, sf::BlendMode::Factor::DstAlpha, sf::BlendMode::Add, sf::BlendMode::Factor::OneMinusDstAlpha, sf::BlendMode::Factor::One, sf::BlendMode::Equation::Add);
frameBuffer.draw(frontBufferSprite, currentStates);
}
for (unsigned int i = 0; i < drawables.size(); i++) {
frameBuffer.draw(drawables[i].first.get(), drawables[i].second);
}
frameBuffer.display();
}
std::vector<Entity*> OITRenderComponent::getEntities() {
return visibleEntities;
}
void OITRenderComponent::draw(Drawable& drawable, RenderStates states) {
update = true;
drawables.push_back(std::make_pair(std::ref(drawable), states));
}
void OITRenderComponent::draw(RenderTarget& target, RenderStates states) {
frameBufferSprite.setCenter(target.getView().getPosition());
target.draw(frameBufferSprite, states);
drawables.clear();
}
View& OITRenderComponent::getView() {
return view;
}
int OITRenderComponent::getLayer() {
return getPosition().z;
}
void OITRenderComponent::updateParticleSystems() {
for (unsigned int i = 0; i < visibleEntities.size(); i++) {
if (dynamic_cast<physic::ParticleSystem*>(visibleEntities[i]) != nullptr) {
static_cast<physic::ParticleSystem*>(visibleEntities[i])->update();
}
}
loadEntitiesOnComponent(visibleEntities);
update = true;
}
}
}
So I'm searching another way of doing this.
Isn't there a way to pass a pointer to the GPU and then the GPU'll update the CPU variable. I don't think so because it seems that GPU and CPU doens't share the same memory...