Пример #1
0
void DynamicStreamApp::createVBForDynamicStream(
    izanagi::IMemoryAllocator* allocator,
    izanagi::graph::CGraphicsDevice* device)
{
    m_vbDynamicStream = device->CreateVertexBuffer(
        sizeof(Vertex), // 描画の際に使われるので、正しい値を設定しておく.
        0,              // glBufferStorage で確保されるので、この値はゼロにしておく.
        izanagi::graph::E_GRAPH_RSC_USAGE_DYNAMIC);

    CALL_GL_API(::glGenBuffers(1, &m_glVB));

    m_vbDynamicStream->overrideNativeResource(&m_glVB);

    CALL_GL_API(::glBindBuffer(GL_ARRAY_BUFFER, m_glVB));

    const GLbitfield flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
    m_bufferSize = LIST_NUM * sizeof(Vertex) * POINT_NUM;

    CALL_GL_API(::glBufferStorage(
        GL_ARRAY_BUFFER,
        m_bufferSize,
        NULL,
        flags));

    m_mappedDataPtr = ::glMapBufferRange(GL_ARRAY_BUFFER, 0, m_bufferSize, flags);
    IZ_ASSERT(m_mappedDataPtr);
}
Пример #2
0
    /**
    * アンロック
    */
    IZ_BOOL CVertexBufferOGL::Unlock(CGraphicsDevice* device)
    {
        IZ_ASSERT(s_isLocked);

        IZ_ASSERT(m_VB > 0);

        IZ_BOOL isLocked = m_isLocked;
    
        if (isLocked) {
#if 0
            CALL_GL_API(glUnmapBuffer(GL_COPY_WRITE_BUFFER));

            CALL_GL_API(glBindBuffer(
                GL_COPY_WRITE_BUFFER,
                0));
#else
            CALL_GL_API(glUnmapNamedBuffer(m_VB));
#endif

            m_prevVB = 0;
            m_isLocked = IZ_FALSE;
        }

        s_isLocked = IZ_FALSE;

        return isLocked;
    }
Пример #3
0
static GLuint CreateShader(const char* shaderPath, GLenum type)
{
    FILE* fp = nullptr;
    fopen_s(&fp, shaderPath, "rt");
    assert(fp != nullptr);

    char program[2048] = { 0 };
    fread(program, 1, sizeof(program), fp);

    CALL_GL_API(auto shader = ::glCreateShader(type));
    assert(shader != 0);

    const char* p = program;
    const char** pp = &p;

    CALL_GL_API(::glShaderSource(
        shader,
        1,
        pp,
        nullptr));

    CALL_GL_API(::glCompileShader(shader));

    return shader;
}
Пример #4
0
static void Init()
{
    GLenum result = glewInit();
    assert(result == GLEW_OK);

    auto version = ::glGetString(GL_VERSION);
    PRINTF("GL Version(%s)\n", version);

    CALL_GL_API(::glClipControl(
        GL_LOWER_LEFT,
        GL_ZERO_TO_ONE));

    CALL_GL_API(::glFrontFace(GL_CCW));

    CALL_GL_API(::glViewport(0, 0, WIDTH, HEIGHT));
    CALL_GL_API(::glDepthRangef(0.0f, 1.0f));


    g_vs = CreateShader("shader/vs.glsl", GL_VERTEX_SHADER);
    g_fs = CreateShader("shader/fs.glsl", GL_FRAGMENT_SHADER);

    g_program = CreateShaderProgram(g_vs, g_fs);

    g_tex = CreateTexture();
}
Пример #5
0
void DynamicStreamApp::RenderDynamicStream(izanagi::graph::CGraphicsDevice* device)
{
    CALL_GL_API(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE));
    CALL_GL_API(::glEnable(GL_POINT_SPRITE));

    device->SetShaderProgram(m_shd);

    auto& camera = GetCamera();

    izanagi::math::SMatrix44 mtxW2C;
    izanagi::math::SMatrix44::Copy(mtxW2C, camera.GetParam().mtxW2C);

    IZ_FLOAT pointSize = 100.0f;
    auto hSize = m_shd->GetHandleByName("size");
    m_shd->SetFloat(device, hSize, pointSize);

    auto hMtxW2C = m_shd->GetHandleByName("mtxW2C");
    m_shd->SetMatrixArrayAsVectorArray(device, hMtxW2C, &mtxW2C, 4);

    device->SetVertexBuffer(0, 0, sizeof(Vertex), m_vbDynamicStream);
    device->SetVertexDeclaration(m_vd);

    IZ_UINT offset = 0;
    IZ_UINT length = LIST_NUM * sizeof(Vertex) * POINT_NUM;

    // Need to wait for this area to become available. If we've sized things properly, it will always be 
    // available right away.
    //m_mgrBufferLock.WaitForLockedRange(offset, length);

    for (IZ_UINT i = 0; i < LIST_NUM; i++) {
#ifdef ENABLE_TRHEAD
        if (m_items[i].isRenderable) {
            device->DrawPrimitive(
                izanagi::graph::E_GRAPH_PRIM_TYPE_POINTLIST,
                m_items[i].offset,
                POINT_NUM);

            m_items[i].isRenderable = false;
        }
#else
        IZ_UINT8* dst = (IZ_UINT8*)m_mappedDataPtr;
        dst += offset * sizeof(Vertex);

        memcpy(dst, m_vtx[i], sizeof(m_vtx[i]));

        device->DrawPrimitive(
            izanagi::graph::E_GRAPH_PRIM_TYPE_POINTLIST,
            offset,
            POINT_NUM);

        offset += POINT_NUM;
#endif
    }

    //m_mgrBufferLock.LockRange(offset, length);
}
Пример #6
0
    // ロック
    IZ_BOOL CVertexBufferOGL::Lock(
        CGraphicsDevice* device,
        IZ_UINT offset,
        IZ_UINT size,
        void** data,
        IZ_BOOL isReadOnly,
        IZ_BOOL isDiscard/*= IZ_FALSE*/)
    {
        IZ_ASSERT(!s_isLocked);

        // NOTE
        // Just only read or write, can't both read and write.

        IZ_ASSERT(!isReadOnly);

        IZ_UINT lockSize = (size > 0
            ? size
            : GetSize());

        IZ_ASSERT(lockSize + offset <= GetSize());

        void* tmp = nullptr;

#if 0
        CALL_GL_API(::glBindBuffer(
            GL_COPY_WRITE_BUFFER,
            m_VB));

        CALL_GL_API(tmp = ::glMapBufferRange(
            GL_COPY_WRITE_BUFFER,
            offset,
            lockSize,
            GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT));
        IZ_ASSERT(tmp != nullptr);
#else
        CALL_GL_API(tmp = ::glMapNamedBufferRange(
            m_VB,
            offset,
            lockSize,
            GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT));
        IZ_ASSERT(tmp != nullptr);
#endif

        *data = tmp;

        m_isLocked = IZ_TRUE;

        s_isLocked = IZ_TRUE;

        return IZ_TRUE;
    }
Пример #7
0
static GLuint CreateTexture()
{
    GLuint tex = 0;
    CALL_GL_API(::glGenTextures(1, &tex));

    CALL_GL_API(::glBindTexture(GL_TEXTURE_2D, tex));

    CALL_GL_API(::glTexImage2D(
        GL_TEXTURE_2D,
        0,
        GL_RGBA,
        WIDTH, HEIGHT,
        0,
        GL_RGBA,
        GL_UNSIGNED_BYTE,
        NULL));

    CALL_GL_API(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    CALL_GL_API(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));

    CALL_GL_API(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP));
    CALL_GL_API(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP));

    CALL_GL_API(::glBindTexture(GL_TEXTURE_2D, 0));

    return tex;
}
Пример #8
0
    /**
    * アンロック
    */
    IZ_BOOL CVertexBufferGLES2::Unlock(CGraphicsDevice* device)
    {
        IZ_ASSERT(m_VB > 0);
    
        IZ_BOOL isLocked = (m_LockSize > 0);

        if (isLocked) {
            CVertexBuffer* curVB = m_Device->GetRenderState().curVB[0];

            if (curVB != this) {
                // もしかしたら
                Initialize(device);
            }

            VtxBufferOperator vbOp(device, m_VB);

            IZ_UINT8* tmp = reinterpret_cast<IZ_UINT8*>(m_TemporaryData);
            tmp += m_LockOffset;

            CALL_GL_API(::glBufferSubData(
                GL_ARRAY_BUFFER,
                m_LockOffset,
                m_LockSize,
                tmp));

            // 元に戻す
            if (curVB != this) {
                if (curVB == IZ_NULL) {
                    CALL_GL_API(::glBindBuffer(GL_ARRAY_BUFFER, 0));
                }
                else {
                    CALL_GL_API(::glBindBuffer(
                        GL_ARRAY_BUFFER,
                        ((CVertexBufferGLES2*)curVB)->m_VB));
                }
            }

            m_LockOffset = 0;
            m_LockSize = 0;
        }

        if (!IsDynamic()) {
            FREE(m_Allocator, m_TemporaryData);
            m_TemporaryData = IZ_NULL;
            m_AllocSize = 0;
        }

        return isLocked;
    }
Пример #9
0
    IZ_BOOL CTextureOGL::Write(
        IZ_UINT level,
        void* data,
        IZ_UINT x, IZ_UINT y,
        IZ_UINT width, IZ_UINT height)
    {
        IZ_ASSERT(m_Texture != 0);

        // Check not locked.
        IZ_ASSERT(m_LockedSize == 0);

        IZ_ASSERT(x < width);
        IZ_ASSERT(y < height);

        IZ_UINT w = GetWidth(level);
        IZ_UINT h = GetHeight(level);

        VRETURN(width <= w);
        VRETURN(height <= h);

        CALL_GL_API(::glTextureSubImage2D(
            m_Texture,
            level,
            x, y,
            width, height,
            m_GLFormat,
            m_GLType,
            data));

        return IZ_TRUE;
    }
Пример #10
0
static GLuint CreateShaderProgram(GLuint vs, GLuint fs)
{
    auto program = ::glCreateProgram();
    assert(program != 0);

    CALL_GL_API(::glAttachShader(program, vs));
    CALL_GL_API(::glAttachShader(program, fs));

    CALL_GL_API(::glLinkProgram(program));

    GLint isLinked = 0;
    CALL_GL_API(::glGetProgramiv(program, GL_LINK_STATUS, &isLinked));
    assert(isLinked != 0);

    return program;
}
Пример #11
0
        VtxBufferOperator(CGraphicsDevice* device, GLuint targetVB)
        {
            auto vb = (CVertexBufferGLES2*)device->GetRenderState().curVB[0];

            m_prevVB = (vb != IZ_NULL ? vb->m_VB : 0);

            CALL_GL_API(::glBindBuffer(GL_ARRAY_BUFFER, targetVB));
        }
Пример #12
0
    // デストラクタ
    CVertexBufferGLES2::~CVertexBufferGLES2()
    {
        SAFE_RELEASE(m_Device);

        if (m_VB > 0) {
            CALL_GL_API(::glDeleteBuffers(1, &m_VB));
        }
        
        FREE(m_Allocator, m_TemporaryData);
    }
Пример #13
0
void DynamicStreamApp::RenderMapUnmap(izanagi::graph::CGraphicsDevice* device)
{
    CALL_GL_API(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE));
    CALL_GL_API(::glEnable(GL_POINT_SPRITE));

    device->SetShaderProgram(m_shd);

    auto& camera = GetCamera();

    izanagi::math::SMatrix44 mtxW2C;
    izanagi::math::SMatrix44::Copy(mtxW2C, camera.GetParam().mtxW2C);

    IZ_FLOAT pointSize = 100.0f;
    auto hSize = m_shd->GetHandleByName("size");
    m_shd->SetFloat(device, hSize, pointSize);

    auto hMtxW2C = m_shd->GetHandleByName("mtxW2C");
    m_shd->SetMatrixArrayAsVectorArray(device, hMtxW2C, &mtxW2C, 4);

    device->SetVertexBuffer(0, 0, sizeof(Vertex), m_vbMapUnmap);
    device->SetVertexDeclaration(m_vd);

    for (IZ_UINT i = 0; i < LIST_NUM; i++) {
        void* dst = nullptr;
        m_vbMapUnmap->Lock(
            device,
            0,
            0,
            (void**)&dst,
            IZ_FALSE);

        memcpy(dst, m_vtx[i], sizeof(m_vtx[i]));

        m_vbMapUnmap->Unlock(device);

        device->DrawPrimitive(
            izanagi::graph::E_GRAPH_PRIM_TYPE_POINTLIST,
            0,
            POINT_NUM);
    }
}
Пример #14
0
    void CVertexBufferOGL::overrideNativeResource(void* rsc)
    {
        GLuint vb = (rsc ? *(GLuint*)rsc : 0);

        if (vb > 0) {
            if (m_VB > 0) {
                CALL_GL_API(::glDeleteBuffers(1, &m_VB));
            }
        }

        m_VB = vb;
    }
Пример #15
0
void DxtEncoder::draw(izanagi::graph::CGraphicsDevice* device)
{
    device->SaveRenderState();

    device->SetRenderState(
        izanagi::graph::E_GRAPH_RS_ZENABLE,
        IZ_FALSE);
    device->SetRenderState(
        izanagi::graph::E_GRAPH_RS_CULLMODE,
        izanagi::graph::E_GRAPH_CULL_NONE);

    device->SetShaderProgram(m_shdDraw);

    {
        CALL_GL_API(::glActiveTexture(GL_TEXTURE0));

        GLuint handle = m_texDxt->GetTexHandle();

        CALL_GL_API(::glBindTexture(GL_TEXTURE_2D, handle));
    }

    auto hImage = m_shdDraw->GetHandleByName("image");
    auto hMode = m_shdDraw->GetHandleByName("mode");
    auto hToSRGB = m_shdDraw->GetHandleByName("to_srgb");

    CALL_GL_API(glUniform1i(hImage, 0));
    CALL_GL_API(glUniform1i(hMode, 3));
    CALL_GL_API(glUniform1i(hToSRGB, 0));

    // NOTE
    // 頂点バッファを使わず全画面に描画する頂点シェーダ.
    CALL_GL_API(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));

    device->LoadRenderState();
}
Пример #16
0
    void CVertexBufferGLES2::Initialize(CGraphicsDevice* device)
    {
        if (!m_IsInitialized) {
            VtxBufferOperator vbOp(device, m_VB);

            GLenum glUsage = (m_CreateType == E_GRAPH_RSC_USAGE_STATIC
                ? GL_STATIC_DRAW
                : GL_DYNAMIC_DRAW);

            CALL_GL_API(::glBufferData(
                GL_ARRAY_BUFFER,
                m_Size,
                NULL,
                glUsage));

            m_IsInitialized = IZ_TRUE;
        }
    }
Пример #17
0
// 解放.
void DynamicStreamApp::ReleaseInternal()
{
#ifdef ENABLE_TRHEAD
    m_isRunThread = false;
    if (m_thread.joinable()) {
        m_thread.join();
    }
#endif

    m_vbDynamicStream->overrideNativeResource(nullptr);
    CALL_GL_API(::glDeleteBuffers(1, &m_glVB));

    SAFE_RELEASE(m_vbDynamicStream);
    SAFE_RELEASE(m_vbMapUnmap);

    SAFE_RELEASE(m_vd);

    SAFE_RELEASE(m_vs);
    SAFE_RELEASE(m_ps);
    SAFE_RELEASE(m_shd);
}
Пример #18
0
    // 本体作成
    IZ_BOOL CVertexBufferGLES2::CreateBody(
        CGraphicsDevice* device,
        IZ_UINT stride,
        IZ_UINT vtxNum,
        E_GRAPH_RSC_USAGE usage)
    {
        CALL_GL_API(::glGenBuffers(1, &m_VB));
        VRETURN(m_VB > 0);

        IZ_BOOL ret = (m_VB > 0);

        GLsizeiptr size = vtxNum * stride;

        m_Stride = stride;
        m_VtxNum = vtxNum;

        m_Size = size;
    
        m_CreateType = usage;

        Initialize(device);

        return ret;
    }
Пример #19
0
 IZ_BOOL CVertexBufferGLES2::Disable()
 {
     CALL_GL_API(::glDeleteBuffers(1, &m_VB));
     return IZ_TRUE;
 }
Пример #20
0
 ~VtxBufferOperator()
 {
     CALL_GL_API(::glBindBuffer(GL_ARRAY_BUFFER, m_prevVB));
 }
Пример #21
0
void DxtEncoder::encode(
    izanagi::graph::CGraphicsDevice* device,
    izanagi::graph::CTexture* texture)
{
    izanagi::sys::CTimer timer;

    device->SaveRenderState();

    device->SetRenderState(
        izanagi::graph::E_GRAPH_RS_ZENABLE,
        IZ_FALSE);

    // For rendering full screen quad without vertex buffer.
    device->SetRenderState(
        izanagi::graph::E_GRAPH_RS_CULLMODE,
        izanagi::graph::E_GRAPH_CULL_NONE);

    auto texHandle = m_tex->GetTexHandle();

    // Set FBO.
    CALL_GL_API(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo));
    CALL_GL_API(glFramebufferTexture2D(
        GL_FRAMEBUFFER,
        GL_COLOR_ATTACHMENT0,
        GL_TEXTURE_2D,
        texHandle,
        0));

    GLenum attachedColor[] = {
        GL_COLOR_ATTACHMENT0,
    };

    CALL_GL_API(::glDrawBuffers(1, attachedColor));

    CALL_GL_API(glDisable(GL_FRAMEBUFFER_SRGB));

    device->SetShaderProgram(m_shd);

    {
        CALL_GL_API(::glActiveTexture(GL_TEXTURE0));

        GLuint handle = texture->GetTexHandle();

        CALL_GL_API(::glBindTexture(GL_TEXTURE_2D, handle));
    }

    auto hImage = m_shd->GetHandleByName("image");
    auto hMode = m_shd->GetHandleByName("mode");

    CALL_GL_API(glUniform1i(hImage, 0));
    CALL_GL_API(glUniform1i(hMode, 3));

    device->SetViewport(
        izanagi::graph::SViewport(0, 0, m_width/4, m_height/4));

    // NOTE
    // 頂点バッファを使わず全画面に描画する頂点シェーダ.
    CALL_GL_API(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

#if 1
    // Copy to PBO.
    {
        timer.Begin();

        // NOTE
        // PBO は STREAM_COPY で作成されている.

        CALL_GL_API(glReadBuffer(GL_COLOR_ATTACHMENT0));
        CALL_GL_API(glBindBuffer(GL_PIXEL_PACK_BUFFER, m_pbo));

        // Copy from GL_COLOR_ATTACHMENT0 to PBO.
        CALL_GL_API(glReadPixels(
            0, 0,
            m_width / 4, m_height / 4,
            GL_RGBA_INTEGER,
            GL_UNSIGNED_INT,
            0));

        CALL_GL_API(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));

        auto time = timer.End();
        IZ_PRINTF("ReadToPBO [%f]\n", time);
    }

    CALL_GL_API(glBindFramebuffer(GL_FRAMEBUFFER, 0));

    // Copy to texture memory.
    {
        timer.Begin();

        auto texdxt = m_texDxt->GetTexHandle();

        CALL_GL_API(glBindTexture(GL_TEXTURE_2D, texdxt));
        CALL_GL_API(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pbo));

        // Copy from PBO to texture(DXT5) memory.
        CALL_GL_API(glCompressedTexSubImage2D(
            GL_TEXTURE_2D,
            0,
            0, 0,
            m_width, m_height,
            GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
            m_width * m_height,
            0));

        CALL_GL_API(glBindTexture(GL_TEXTURE_2D, 0));
        CALL_GL_API(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));

        auto time = timer.End();
        IZ_PRINTF("CopyToDXT [%f]\n", time);
    }

    // Readback to memory.
    {
        timer.Begin();

        auto texdxt = m_texDxt->GetTexHandle();

        CALL_GL_API(glBindTexture(GL_TEXTURE_2D, texdxt));

        CALL_GL_API(glGetCompressedTexImage(
            GL_TEXTURE_2D,
            0,
            m_pixels));

        CALL_GL_API(glBindTexture(GL_TEXTURE_2D, 0));

        auto time = timer.End();
        IZ_PRINTF("ReadToMem [%f]\n", time);
    }
#endif

    // 元に戻す.
    device->SetViewport(
        izanagi::graph::SViewport(0, 0, m_width, m_height));

    device->LoadRenderState();
}
Пример #22
0
void FoveatedRenderingApp::FoveatedRender(izanagi::graph::CGraphicsDevice* device)
{
    izanagi::sample::CSampleCamera& camera = GetCamera();

    device->BeginScene(
        &m_mask, 1,
        izanagi::graph::E_GRAPH_CLEAR_FLAG_ALL);
    {
        // For rendering full screen quad without vertex buffer.
        device->SetRenderState(
            izanagi::graph::E_GRAPH_RS_CULLMODE,
            izanagi::graph::E_GRAPH_CULL_NONE);

        auto shd = m_shdMakeMask.m_shd;

        device->SetShaderProgram(shd);

        auto hInvScr = shd->GetHandleByName("invScreen");
        izanagi::math::CVector4 invScr(1.0f / SCREEN_WIDTH, 1.0f / SCREEN_HEIGHT, 0, 0);
        shd->SetVector(device, hInvScr, invScr);

        auto hCenter = shd->GetHandleByName("center");
        izanagi::math::CVector4 center(SCREEN_WIDTH * 0.5f, SCREEN_HEIGHT * 0.5f, 0, 0);
        shd->SetVector(device, hCenter, center);

        CALL_GL_API(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
    }
    device->EndScene();

    device->BeginScene(
        &m_rt, 1,
        m_depth,
        izanagi::graph::E_GRAPH_CLEAR_FLAG_ALL);
    {
        device->SetTexture(0, m_Img->GetTexture(m_Idx));
        device->SetTexture(1, m_mask);

        auto shd = m_shdDrawCube.m_shd;

        device->SetShaderProgram(shd);

        auto hL2W = shd->GetHandleByName("g_mL2W");
        shd->SetMatrix(device, hL2W, m_L2W);

        auto mtxW2C = camera.GetParam().mtxW2C;

        auto hW2C = shd->GetHandleByName("g_mW2C");
        shd->SetMatrix(device, hW2C, mtxW2C);

        auto hEye = shd->GetHandleByName("g_vEye");
        shd->SetVector(device, hEye, camera.GetParam().pos);

        auto hInvScr = shd->GetHandleByName("invScreen");
        izanagi::math::CVector4 invScr(1.0f / SCREEN_WIDTH, 1.0f / SCREEN_HEIGHT, 0, 0);
        shd->SetVector(device, hInvScr, invScr);

        auto hCanFoveated = shd->GetHandleByName("canFoveated");
        shd->SetBool(device, hCanFoveated, true);

        m_Cube->Render(device);
    }
    device->EndScene();

    device->SetRenderState(
        izanagi::graph::E_GRAPH_RS_ZWRITEENABLE,
        IZ_FALSE);
    device->SetRenderState(
        izanagi::graph::E_GRAPH_RS_ZENABLE,
        IZ_FALSE);

    {
        auto shd = m_shdFilter.m_shd;

        device->SetShaderProgram(shd);

        m_rt->SetFilter(
            izanagi::graph::E_GRAPH_TEX_FILTER_POINT,
            izanagi::graph::E_GRAPH_TEX_FILTER_POINT,
            izanagi::graph::E_GRAPH_TEX_FILTER_NONE);
        m_rt->SetAddress(
            izanagi::graph::E_GRAPH_TEX_ADDRESS_CLAMP,
            izanagi::graph::E_GRAPH_TEX_ADDRESS_CLAMP);

        device->SetTexture(0, m_rt);
        auto hTex0 = shd->GetHandleByName("s0");
        CALL_GL_API(glUniform1i(hTex0, 0));

        device->SetTexture(1, m_mask);
        auto hTex1 = shd->GetHandleByName("s1");
        CALL_GL_API(glUniform1i(hTex1, 1));

        auto hInvScr = shd->GetHandleByName("invScreen");
        izanagi::math::CVector4 invScr(1.0f / SCREEN_WIDTH, 1.0f / SCREEN_HEIGHT, 0, 0);
        shd->SetVector(device, hInvScr, invScr);

        CALL_GL_API(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
    }
}
Пример #23
0
void display(hitable* world, camera& cam)
{
    CALL_GL_API(::glClearColor(0.0f, 0.5f, 1.0f, 1.0f));
    CALL_GL_API(::glClearDepthf(1.0f));
    CALL_GL_API(::glClearStencil(0));
    CALL_GL_API(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));

    CALL_GL_API(::glUseProgram(g_program));

    GLfloat invScreen[4] = { 1.0f / WIDTH, 1.0f / HEIGHT, 0.0f, 0.0f };
    auto hInvScreen = GetHandle(g_program, "invScreen");
    CALL_GL_API(::glUniform4fv(hInvScreen, 1, invScreen));

    CALL_GL_API(::glActiveTexture(GL_TEXTURE0));

    CALL_GL_API(::glBindTexture(GL_TEXTURE_2D, g_tex));

    auto hImage = GetHandle(g_program, "image");
    CALL_GL_API(glUniform1i(hImage, 0));

    float lum = 0.0f;
    float maxlum = 0.0f;

    timer time;
    time.begin();

#ifdef ENABLE_MULTI_THREAD
    int step = ny / thread_num;
    int begin = 0;

    for (int i = 0; i < thread_num; i++) {
        g_threadData[i].idx = i;
        g_threadData[i].begin = begin;
        begin += step;
        
        g_threadData[i].end = begin + step;
        g_threadData[i].end = (g_threadData[i].end > HEIGHT ? HEIGHT : g_threadData[i].end);

        g_threadData[i].world = world;
        g_threadData[i].cam = &cam;

        g_eventWorker[i].Set();

        g_threads[i].Start([&](void* userData, bool running) {
            ThreadData* data = (ThreadData*)userData;
            onDisplay(data, running);
        }, &g_threadData[i]);
    }

    for (int i = 0; i < thread_num; i++) {
        g_eventMain[i].Wait();
        g_eventMain[i].Reset();
    }

    for (int i = 0; i < thread_num; i++) {
        lum += g_sumY[i];
        maxlum = math::CMath::Max(g_maxLum[i], maxlum);
    }

    lum /= thread_num;
#else
    onDisplay(world, &cam, 0, 0, ny, true);

    lum = g_sumY[0];
    maxlum = g_maxLum[0];
#endif

    auto elapsed = time.end();
    printf("Elapsed[%f]\n", elapsed);

    static uint8_t s_color[HEIGHT][WIDTH][4];
    static float fMiddleGrey = 0.18f;

    static const vec3 RGB2Y(+0.29900f, +0.58700f, +0.11400f);
    static const vec3 RGB2Cb(-0.16874f, -0.33126f, +0.50000f);
    static const vec3 RGB2Cr(+0.50000f, -0.41869f, -0.08131f);
    static const vec3 YCbCr2R(+1.00000f, +0.00000f, +1.40200f);
    static const vec3 YCbCr2G(+1.00000f, -0.34414f, -0.71414f);
    static const vec3 YCbCr2B(+1.00000f, +1.77200f, +0.00000f);

    // NOTE
    // HDR
    // http://t-pot.com/program/123_ToneMapping/index.html

    float coeff = 0.18f / exp(lum);
    float l_max = coeff * maxlum;

    for (int j = 0; j < ny; j++) {
        for (int i = 0; i < nx; i++) {
#if 1
            vec3 col(g_color[j][i][0], g_color[j][i][1], g_color[j][i][2]);

            float y = dot(RGB2Y, col);
            float cb = dot(RGB2Cb, col);
            float cr = dot(RGB2Cr, col);

            y = coeff * y;
            y = y * (1.0f + y / (l_max * l_max)) / (1.0f + y);

            vec3 ycbcr(y, cb, cr);

            float r = dot(YCbCr2R, ycbcr);
            float g = dot(YCbCr2G, ycbcr);
            float b = dot(YCbCr2B, ycbcr);

            int ir = int(255.9f * r);
            int ig = int(255.9f * g);
            int ib = int(255.9f * b);

            s_color[j][i][0] = math::CMath::Clamp(ir, 0, 255);
            s_color[j][i][1] = math::CMath::Clamp(ig, 0, 255);
            s_color[j][i][2] = math::CMath::Clamp(ib, 0, 255);
#else
            auto r = 2 * int(255.9f * g_color[j][i][0] * div[0]);
            auto g = 2 * int(255.9f * g_color[j][i][1] * div[1]);
            auto b = 2 * int(255.9f * g_color[j][i][2] * div[2]);

            s_color[j][i][0] = math::CMath::Clamp(r, 0, 255);
            s_color[j][i][1] = math::CMath::Clamp(g, 0, 255);
            s_color[j][i][2] = math::CMath::Clamp(b, 0, 255);
#endif
        }
    }

    CALL_GL_API(::glTexSubImage2D(
        GL_TEXTURE_2D,
        0,
        0, 0,
        WIDTH, HEIGHT,
        GL_RGBA,
        GL_UNSIGNED_BYTE,
        s_color));

    CALL_GL_API(::glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
}
Пример #24
0
IZ_BOOL DxtEncoder::init(
    izanagi::IMemoryAllocator* allocator,
    izanagi::graph::CGraphicsDevice* device,
    IZ_UINT width, IZ_UINT height,
    const char* vtxShader,
    const char* dxtShader,
    const char* pixelShader)
{
    m_width = width;
    m_height = height;

    char* buf = nullptr;
    IZ_UINT allocatedSize = 0;

    {
        izanagi::CFileInputStream in;
        VRETURN(in.Open(dxtShader));

        allocatedSize = in.GetSize();
        buf = (char*)ALLOC(allocator, allocatedSize);

        in.Read(buf, 0, allocatedSize);
        buf[allocatedSize] = 0;

        m_dxt = device->CreatePixelShader(buf);
        VRETURN(m_dxt);
    }

    {
        izanagi::CFileInputStream in;
        VRETURN(in.Open(vtxShader));

        auto size = in.GetSize();
        IZ_ASSERT(allocatedSize >= size);

        in.Read(buf, 0, size);
        buf[size] = 0;

        m_vs = device->CreateVertexShader(buf);
        VRETURN(m_vs);
    }

    {
        izanagi::CFileInputStream in;
        VRETURN(in.Open(pixelShader));

        auto size = in.GetSize();
        IZ_ASSERT(allocatedSize >= size);

        in.Read(buf, 0, size);
        buf[size] = 0;

        m_ps = device->CreatePixelShader(buf);
        VRETURN(m_ps);
    }

    FREE(allocator, buf);
    {
        m_shd = device->CreateShaderProgram();
        VRETURN(m_shd);

        VRETURN(m_shd->AttachVertexShader(m_vs));
        VRETURN(m_shd->AttachPixelShader(m_dxt));
    }

    {
        m_shdDraw = device->CreateShaderProgram();
        VRETURN(m_shdDraw);

        VRETURN(m_shdDraw->AttachVertexShader(m_vs));
        VRETURN(m_shdDraw->AttachPixelShader(m_ps));
    }

    {
        // NOTE
        // DXTは 4x4 ブロックで、128bit/block.
        // GL_RGBA32UI は 128bit/texel.
        // すると、1texel が DXTのブロックのサイズと同じになるので、fragment shaderの1pixel出力がそのままDXTの1ブロックになる.
        m_tex = device->CreateTexture(
            width / 4, height / 4,
            1,
            izanagi::graph::E_GRAPH_PIXEL_FMT_RGBA32UI,
            izanagi::graph::E_GRAPH_RSC_USAGE_STATIC);
        VRETURN(m_tex);

        CALL_GL_API(glGenFramebuffers(1, &m_fbo));

        glGenBuffers(1, &m_pbo);
        glBindBuffer(GL_PIXEL_PACK_BUFFER, m_pbo);
        glBufferData(GL_PIXEL_PACK_BUFFER, width * height, 0, GL_STREAM_COPY);
        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

        m_texDxt = device->CreateTexture(
            width, height,
            1,
            izanagi::graph::E_GRAPH_PIXEL_FMT_DXT5,
            izanagi::graph::E_GRAPH_RSC_USAGE_STATIC);
        VRETURN(m_tex);
    }

    {
        m_allocator = allocator;

        // NOTE
        // RGBA : w * h * 4;
        // DXT5 : RGBA / 4 = (w * h * 4) / 4 = w * h
        auto size = width * height;
        m_pixels = ALLOC_ZERO(m_allocator, size);
    }

    return IZ_TRUE;
}
Пример #25
0
void display(hitable* world, camera& cam)
{
    CALL_GL_API(::glClearColor(0.0f, 0.5f, 1.0f, 1.0f));
    CALL_GL_API(::glClearDepthf(1.0f));
    CALL_GL_API(::glClearStencil(0));
    CALL_GL_API(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));

    CALL_GL_API(::glUseProgram(g_program));

    GLfloat invScreen[4] = { 1.0f / WIDTH, 1.0f / HEIGHT, 0.0f, 0.0f };
    auto hInvScreen = GetHandle(g_program, "invScreen");
    CALL_GL_API(::glUniform4fv(hInvScreen, 1, invScreen));

    CALL_GL_API(::glActiveTexture(GL_TEXTURE0));

    CALL_GL_API(::glBindTexture(GL_TEXTURE_2D, g_tex));

    auto hImage = GetHandle(g_program, "image");
    CALL_GL_API(glUniform1i(hImage, 0));

    {
        int ns = 10;

#pragma omp for
        for (int j = ny - 1; j >= 0; j--) {
            for (int i = 0; i < nx; i++) {
                vec3 col(0, 0, 0);
                for (int s = 0; s < ns; s++) {
                    float u = float(i + drand48()) / float(nx);
                    float v = float(j + drand48()) / float(ny);

                    ray r = cam.get_ray(u, v);
                    col += color(r, world, 0);
                }

                col /= float(ns);

                col = vec3(
                    sqrt(col[0]), 
                    sqrt(col[1]), 
                    sqrt(col[2]));

                g_color[j][i][0] = int(255.99*col[0]);
                g_color[j][i][1] = int(255.99*col[1]);
                g_color[j][i][2] = int(255.99*col[2]);
                g_color[j][i][3] = 255;
            }
        }
    }

    CALL_GL_API(::glTexSubImage2D(
        GL_TEXTURE_2D,
        0,
        0, 0,
        WIDTH, HEIGHT,
        GL_RGBA,
        GL_UNSIGNED_BYTE,
        g_color));

    CALL_GL_API(::glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
}