Пример #1
0
void GPUTileStorage::init(int tileSize, int nTiles,
    TextureInternalFormat internalf, TextureFormat f, PixelType t,
    const Texture::Parameters &params, bool useTileMap)
{
    TileStorage::init(tileSize, nTiles);

    int maxLayers = Texture2DArray::getMaxLayers();
    int nTextures = nTiles / maxLayers + (nTiles % maxLayers == 0 ? 0 : 1);
    needMipmaps = false;

    for (int i = 0; i < nTextures; ++i) {
        int nLayers = i == nTextures - 1 && nTiles % maxLayers != 0 ? nTiles % maxLayers : maxLayers;
        ptr<Texture2DArray> tex = new Texture2DArray(tileSize, tileSize, nLayers,
            internalf, f, t, params, Buffer::Parameters(), CPUBuffer());
        needMipmaps = needMipmaps || (tex->hasMipmaps());
        textures.push_back(tex);
        tex->generateMipMap();
        for (int j = 0; j < nLayers; ++j) {
            freeSlots.push_back(new GPUSlot(this, i, textures[i], j));
        }
    }

    if (needMipmaps) {
        assert(nTextures <= 8);
        dirtySlots = new set<GPUSlot*>[nTextures];
        fbo = new FrameBuffer();
        fbo->setReadBuffer(BufferId(0));
        fbo->setDrawBuffers(BufferId(COLOR0 | COLOR1));
        mipmapProg = new Program(new Module(330, mipmapShader));
        ptr<Sampler> s = new Sampler(Sampler::Parameters().min(NEAREST).mag(NEAREST).wrapS(CLAMP_TO_EDGE).wrapT(CLAMP_TO_EDGE));
        for (int i = 0; i < nTextures; ++i) {
            char buf[256];
            sprintf(buf, "input_[%d]", i);
            mipmapProg->getUniformSampler(string(buf))->set(textures[i]);
            mipmapProg->getUniformSampler(string(buf))->setSampler(s);
        }
        mipmapParams = mipmapProg->getUniform4i("bufferLayerLevelWidth");
    } else {
        dirtySlots = NULL;
    }

    changes = false;
    if (useTileMap) {
        assert(nTextures == 1);
        tileMap = new Texture2D(4096, 8, RG8, RG, UNSIGNED_BYTE,
            Texture::Parameters().wrapS(CLAMP_TO_EDGE).wrapT(CLAMP_TO_EDGE).min(NEAREST).mag(NEAREST),
            Buffer::Parameters(), CPUBuffer());
    }
}
Пример #2
0
 Texture2DResource(ptr<ResourceManager> manager, const string &name, ptr<ResourceDescriptor> desc, const TiXmlElement *e = NULL) :
     ResourceTemplate<0, Texture2D>(manager, name, desc)
 {
     e = e == NULL ? desc->descriptor : e;
     TextureInternalFormat tf;
     TextureFormat f;
     PixelType t;
     Texture::Parameters params;
     Buffer::Parameters s;
     int w;
     int h;
     try {
         checkParameters(desc, e, "name,source,internalformat,format,type,min,mag,wraps,wrapt,minLod,maxLod,compare,borderType,borderr,borderg,borderb,bordera,maxAniso,width,height,");
         getIntParameter(desc, e, "width", &w);
         getIntParameter(desc, e, "height", &h);
         getParameters(desc, e, tf, f, t);
         getParameters(desc, e, params);
         s.compressedSize(desc->getSize());
         init(w, h, tf, f, t, params, s, CPUBuffer(desc->getData()));
         desc->clearData();
     } catch (...) {
         desc->clearData();
         throw exception();
     }
 }
Пример #3
0
 Texture3DResource(ptr<ResourceManager> manager, const string &name, ptr<ResourceDescriptor> desc, const TiXmlElement *e = NULL) :
     ResourceTemplate<0, Texture3D>(manager, name, desc)
 {
     e = e == NULL ? desc->descriptor : e;
     TextureInternalFormat tf;
     TextureFormat f;
     PixelType t;
     Texture::Parameters params;
     Buffer::Parameters s;
     int w;
     int h;
     int d;
     try {
         checkParameters(desc, e, "name,source,internalformat,format,type,min,mag,wraps,wrapt,wrapr,minLod,maxLod,width,height,depth,");
         getIntParameter(desc, e, "width", &w);
         getIntParameter(desc, e, "height", &h);
         getIntParameter(desc, e, "depth", &d);
         if (h % d != 0) {
             if (Logger::ERROR_LOGGER != NULL) {
                 log(Logger::ERROR_LOGGER, desc, e, "Inconsistent 'height' and 'depth' attributes");
             }
             throw exception();
         }
         getParameters(desc, e, tf, f, t);
         getParameters(desc, e, params);
         s.compressedSize(desc->getSize());
         init(w, h / d, d, tf, f, t, params, s, CPUBuffer(desc->getData()));
         desc->clearData();
     } catch (...) {
         desc->clearData();
         throw exception();
     }
 }
Пример #4
0
void EventRecorder::saveFrame(char *tga)
{
    ptr<FrameBuffer> fb = FrameBuffer::getDefault();

    vec4<GLint> vp = fb->getViewport();
    int w = vp.z;
    int h = vp.w;
    char *buf = new char[w * h * 3];

    fb->readPixels(0, 0, w, h, BGR, UNSIGNED_BYTE, Buffer::Parameters(), CPUBuffer(buf));
    FILE *g = fopen(tga, "wb");
    for (int i = 0; i < 12; ++i) {
        fputc(i == 2 ? 2 : 0, g);
    }
    fputc(w % 256, g);
    fputc(w / 256, g);
    fputc(h % 256, g);
    fputc(h / 256, g);
    fputc(24, g);
    fputc(0, g);
    fwrite(buf, w * h * 3, 1, g);
    fclose(g);

    delete[] buf;
}
Пример #5
0
ptr<Texture2D> ParticleProducer::copyToTexture(ptr<Texture2D> t, int paramCount, getParticleParams getParams, bool useFuncRes)
{
    int width = (int) ceil(paramCount / 4.0f);
    int height = getStorage()->getCapacity();
    if (t == NULL || t->getWidth() != width || t->getHeight() != height) {
        t = new Texture2D(width, height, RGBA16F,
            RGBA, FLOAT, Texture::Parameters().wrapS(CLAMP_TO_BORDER).wrapT(CLAMP_TO_BORDER).min(NEAREST).mag(NEAREST), Buffer::Parameters(), CPUBuffer(NULL));
    }
    if (params == NULL || paramSize < 4 * width * height) {
        if (params != NULL) {
            delete[] params;
        }
        params = new float[4 * width * height];
    }
    int maxHeight = 0;
    vector<ParticleStorage::Particle*>::iterator i = storage->getParticles();
    vector<ParticleStorage::Particle*>::iterator end = storage->end();
    int h = 0;
    while (i != end) {
        ParticleStorage::Particle *p = *i++;
        if (useFuncRes) {
            h += getParams(this, p, params + 4 * width * h);
        } else {
            h = storage->getParticleIndex(p);
            getParams(this, p, params + 4 * width * h);
            ++h;
        }
        maxHeight = max(maxHeight, h);
    }

    if (maxHeight > 0) {
        t->setSubImage(0, 0, 0, width, maxHeight, RGBA, FLOAT, Buffer::Parameters(), CPUBuffer(params));
    }
    return t;
}
Пример #6
0
ptr<Texture2D> ParticleGrid::copyToTexture(ptr<ScreenParticleLayer> l, ptr<Texture2D> t, int &pixelsPerCell)
{
    assert(cellSizes != NULL);
    pixelsPerCell = (int) ceil(float(maxParticlesPerCell) / 4.0f);

    int width = gridSize.x * pixelsPerCell;
    int height = gridSize.y;
    if (t == NULL || t->getWidth() != width || t->getHeight() != height) {
        t = new Texture2D(width, height, RGBA32F,
            RGBA, FLOAT, Texture::Parameters().wrapS(CLAMP_TO_BORDER).wrapT(CLAMP_TO_BORDER).min(NEAREST).mag(NEAREST), Buffer::Parameters(), CPUBuffer(NULL));
    }

    ptr<ParticleStorage> storage = l->getOwner()->getStorage();
    for (int j = 0; j < gridSize.y; ++j) {
        for (int i = 0; i < gridSize.x; i++) {
            int index = i + j * gridSize.x;
            int pindex = index * maxParticlesPerCell;
            int size = cellSizes[index];
            for (int k = 0; k < size; ++k, ++pindex) {
                cellIndexes[pindex] = storage->getParticleIndex(l->getParticle(cellContents[pindex]));
            }
            if (size < maxParticlesPerCell) {
                cellIndexes[pindex] = -1;
            }
        }
    }
    t->setSubImage(0, 0, 0, width, height, RGBA, FLOAT, Buffer::Parameters(), CPUBuffer(cellIndexes));
    return t;
}
Пример #7
0
vec3d SceneManager::getWorldCoordinates(int x, int y)
{
    float winx, winy, winz;
    ptr<FrameBuffer> fb = FrameBuffer::getDefault();
    vec4<GLint> vp = fb->getViewport();
    float width = (float) vp.z;
    float height = (float) vp.w;
    fb->readPixels(x, vp.w - y, 1, 1, DEPTH_COMPONENT, FLOAT, Buffer::Parameters(), CPUBuffer(&winz));

    winx = (x * 2.0f) / width - 1.0f;
    winy = 1.0f - (y * 2.0f) / height;
    winz = 2.0f * winz - 1.0f;
    mat4d screenToWorld = getWorldToScreen().inverse();
    vec4d p = screenToWorld * vec4d(winx, winy, winz, 1);

    return vec3d(p.x / p.w, p.y / p.w, p.z / p.w);
}
Пример #8
0
 Texture2DArrayResource(ptr<ResourceManager> manager, const string &name, ptr<ResourceDescriptor> desc, const TiXmlElement *e = NULL) :
     ResourceTemplate<0, Texture2DArray>(manager, name, desc)
 {
     e = e == NULL ? desc->descriptor : e;
     TextureInternalFormat tf;
     TextureFormat f;
     PixelType t;
     Texture::Parameters params;
     Buffer::Parameters s;
     int w;
     int h;
     int l;
     try {
         checkParameters(desc, e, "name,source,internalformat,format,type,min,mag,wraps,wrapt,minLod,maxLod,compare,borderType,borderr,borderg,borderb,bordera,maxAniso,width,height,depth,layers,");
         getIntParameter(desc, e, "width", &w);
         getIntParameter(desc, e, "height", &h);
         if (e->Attribute("depth") != NULL) {
             getIntParameter(desc, e, "depth", &l);
         } else {
             getIntParameter(desc, e, "layers", &l);
         }
         if (h % l != 0) {
             if (Logger::ERROR_LOGGER != NULL) {
                 log(Logger::ERROR_LOGGER, desc, e, "Inconsistent 'height' and 'layers' attributes");
             }
             throw exception();
         }
         getParameters(desc, e, tf, f, t);
         getParameters(desc, e, params);
         s.compressedSize(desc->getSize());
         init(w, h / l, l, tf, f, t, params, s, CPUBuffer(desc->getData()));
         desc->clearData();
     } catch (...) {
         desc->clearData();
         throw exception();
     }
 }
Пример #9
0
vec3d EditorHandler::getPosition(int x, int y)
{
    float winx, winy, winz;

    ptr<FrameBuffer> fb = SceneManager::getCurrentFrameBuffer();
    vec4<GLint> vp = fb->getViewport();
    float width = (float) vp.z;
    float height = (float) vp.w;
    if (depthBuffer == NULL) {
        fb->readPixels(x, vp.w - y, 1, 1, DEPTH_COMPONENT, FLOAT, Buffer::Parameters(), CPUBuffer(&winz));
    } else {
        winz = depthBuffer[x + (vp.w - y) * vp.z];
    }

    winx = (x * 2.0f) / width - 1.0f;
    winy = 1.0f - (y * 2.0f) / height;
    winz = 2.0f * winz - 1.0f;

    ptr<SceneManager> manager = editors[0]->getTerrain()->getOwner();
    mat4d screenToWorld = manager->getWorldToScreen().inverse();
    vec4d p = screenToWorld * vec4d(winx, winy, winz, 1);

    double px = p.x / p.w;
    double py = p.y / p.w;
    double pz = p.z / p.w;
    return vec3d(px, py, pz);
}
Пример #10
0
bool EditorHandler::mouseClick(button b, state s, modifier m, int x, int y)
{
    if (editors.empty()) {
        return false;
    }
    if (b == LEFT_BUTTON && (m & SHIFT) != 0 && s == DOWN) {
        ptr<FrameBuffer> fb = SceneManager::getCurrentFrameBuffer();
        vec4<GLint> vp = fb->getViewport();
        depthBuffer = new float[vp.z * vp.w];
        fb->readPixels(vp.x, vp.y, vp.z, vp.w, DEPTH_COMPONENT, FLOAT, Buffer::Parameters(), CPUBuffer(depthBuffer));

        paint = true;
        vec3d p = getPosition(x, y);
        strokes.clear();
        strokes.push_back(vec4d(p.x, p.y, p.z, radius));
        newStrokes++;
        return true;
    }
    if (b == LEFT_BUTTON && s == UP && paint) {
        update = true;
        if (depthBuffer != NULL) {
            delete[] depthBuffer;
            depthBuffer = NULL;
        }
        strokes.clear();
        paint = false;
    }
    return false;
}
Пример #11
0
void DrawOceanTask::generateWaves()
{
    long seed = 1234567;
    float min = log(lambdaMin) / log(2.0f);
    float max = log(lambdaMax) / log(2.0f);

    vec4f *waves = new vec4f[nbWaves];

    sigmaXsq = 0.0;
    sigmaYsq = 0.0;
    meanHeight = 0.0;
    heightVariance = 0.0;
    amplitudeMax = 0.0;

#define nbAngles 5 // impair
#define angle(i)  (1.5*(((i)%nbAngles)/(float)(nbAngles/2)-1))
#define dangle()   (1.5/(float)(nbAngles/2))
    float Wa[nbAngles]; // normalised gaussian samples
    int index[nbAngles]; // to hash angle order
    float s=0;
    for (int i=0; i<nbAngles; i++) {
        index[i]=i;
        float a = angle(i); // (i/(float)(nbAngle/2)-1)*1.5;
        s += Wa[i] = exp(-.5*a*a);
    }
    for (int i=0; i<nbAngles; i++) {
        Wa[i] /= s;
    }

    const float waveDispersion = 0.9f;//6;
    const float U0 = 10.0f;
    const int spectrumType = 2;

    for (int i = 0; i < nbWaves; ++i) {
        float x = i / (nbWaves - 1.0f);

        float lambda = pow(2.0f, (1.0f - x) * min + x * max);
        float ktheta = grandom(0.0f, 1.0f, &seed) * waveDispersion;
        float knorm = 2.0f * M_PI_F / lambda;
        float omega = sqrt(9.81f * knorm);
        float amplitude;

        if (spectrumType == 1) {
            amplitude = heightMax * grandom(0.5f, 0.15f, &seed) / (knorm * lambdaMax / (2.0f * M_PI));
        } else if (spectrumType == 2) {
            float step = (max-min)/(nbWaves-1); // dlambda/di
            float omega0 = 9.81f / U0; // 100.0;
            if ((i%(nbAngles))==0) { // scramble angle ordre
                for (int k=0; k<nbAngles; k++) {   // do N swap in indices
                    int n1=lrandom(&seed)%nbAngles, n2=lrandom(&seed)%nbAngles,n;
                    n=index[n1]; index[n1]=index[n2]; index[n2]=n;
                }
            }
            ktheta = waveDispersion*(angle(index[(i)%nbAngles])+.4*srnd()*dangle());
            ktheta *= 1/(1+40*pow(omega0/omega,4));
            amplitude = (8.1e-3*9.81*9.81) / pow(omega,5) * exp(-0.74*pow(omega0/omega,4));
            amplitude *= .5*sqrt(2*3.14*9.81/lambda)*nbAngles*step; // (2/step-step/2);
            amplitude = 3*heightMax*sqrt(amplitude);
        }

        // cull breaking trochoids ( d(x+Acos(kx))=1-Akcos(); must be >0 )
        if (amplitude > 1.0f / knorm) {
            amplitude = 1.0f / knorm;
        } else if (amplitude < -1.0f / knorm) {
            amplitude = -1.0f / knorm;
        }

        waves[i].x = amplitude;
        waves[i].y = omega;
        waves[i].z = knorm * cos(ktheta);
        waves[i].w = knorm * sin(ktheta);
        sigmaXsq += pow(cos(ktheta), 2.0f) * (1.0f - sqrt(1.0f - knorm * knorm * amplitude * amplitude));
        sigmaYsq += pow(sin(ktheta), 2.0f) * (1.0f - sqrt(1.0f - knorm * knorm * amplitude * amplitude));
        meanHeight -= knorm * amplitude * amplitude * 0.5f;
        heightVariance += amplitude * amplitude * (2.0f - knorm * knorm * amplitude * amplitude) * 0.25f;
        amplitudeMax += fabs(amplitude);
    }

    float var = 4.0f;
    float h0 = meanHeight - var * sqrt(heightVariance);
    float h1 = meanHeight + var * sqrt(heightVariance);
    amplitudeMax = h1 - h0;

    ptr<Texture1D> wavesTexture = new Texture1D(nbWaves, RGBA32F, RGBA,
            FLOAT, Texture::Parameters().wrapS(CLAMP_TO_BORDER).min(NEAREST).mag(NEAREST),
            Buffer::Parameters(), CPUBuffer(waves));
    delete[] waves;

    nbWavesU->set(nbWaves);
    wavesU->set(wavesTexture);

    if (brdfShader != NULL) {
        assert(!brdfShader->getUsers().empty());
        Program *prog = *(brdfShader->getUsers().begin());
        prog->getUniform1f("seaRoughness")->set(sigmaXsq);
        prog->getUniform3f("seaColor")->set(seaColor);
    }
}