Пример #1
0
void app_update_and_render(App *app)
{
    GL_CHECK(glEnable(GL_DEPTH_TEST));
    GL_CHECK(glDepthFunc(GL_LEQUAL));
    GL_CHECK(glDepthMask(GL_TRUE));
    GL_CHECK(glDepthRangef(0.0, 1.0));

    GL_CHECK(glClearDepthf(1.0f));
    GL_CHECK(glClearColor(0.15f, 0.17f, 0.2f, 1.0f));

    ////////////////////////////
    // Cube shader

    GL_CHECK(glUseProgram(app->program_cube));
    GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, app->vbo_cube));
    attribfv(cube, position, 3, 6, 0);
    attribfv(cube, normal, 3, 6, 3);

    float camera_z = Centimeter(500.0f);
    float camera_y = Centimeter(70.0f);

    mat4 mat_view[Num_Views];
    mat_view[0] = translate(+Eye_IPD / 2.0f, -camera_y, -camera_z);
    mat_view[1] = translate(-Eye_IPD / 2.0f, -camera_y, -camera_z);
    mat_view[2] = translate(+Eye_IPD / 2.0f, -camera_y, -camera_z);
    mat_view[3] = translate(-Eye_IPD / 2.0f, -camera_y, -camera_z);

    // The scene is rendered twice for each eye position, once with a wide field of view, and
    // once with a narrower field of view in order to render the midpoint of the screen with
    // a higher resolution than the rest. 
    mat4 mat_projection[Num_Views];
    mat_projection[0] = make_frustum_screen_viewer(
                        Eye_Display_Distance,
                        -(Screen_Size_X - Eye_IPD) / 2.0f,
                        +(Eye_IPD / 2.0f),
                        -Screen_Size_Y / 2.0f,
                        +Screen_Size_Y / 2.0f,
                        Z_Near, Z_Far);
    mat_projection[1] = make_frustum_screen_viewer(
                        Eye_Display_Distance,
                        -(Eye_IPD / 2.0f),
                        +(Screen_Size_X - Eye_IPD) / 2.0f,
                        -Screen_Size_Y / 2.0f,
                        +Screen_Size_Y / 2.0f,
                        Z_Near, Z_Far);

    float right_midpoint = -((Screen_Size_X/4.0f) - (Eye_IPD / 2.0f));
    float left_midpoint = (Screen_Size_X/4.0f) - (Eye_IPD / 2.0f);
    mat_projection[2] = make_frustum_screen_viewer(
                        Eye_Display_Distance,
                        right_midpoint - (Screen_Size_X/8.0f),
                        right_midpoint + (Screen_Size_X/8.0f),
                        -Screen_Size_Y / 4.0f,
                        +Screen_Size_Y / 4.0f,
                        Z_Near, Z_Far);
    mat_projection[3] = make_frustum_screen_viewer(
                        Eye_Display_Distance,
                        left_midpoint - (Screen_Size_X/8.0f),
                        left_midpoint + (Screen_Size_X/8.0f),
                        -Screen_Size_Y / 4.0f,
                        +Screen_Size_Y / 4.0f,
                        Z_Near, Z_Far);

    GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, app->fb.framebuffer));
    GL_CHECK(glViewport(0, 0, app->fb.width, app->fb.height));
    GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
    uniformm4array(cube, projection, mat_projection[0], Num_Views);
    uniformm4array(cube, view, mat_view[0], Num_Views);
    draw_scene(app);

    ////////////////////////////
    // Distortion shader

    GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));

    GL_CHECK(glDisable(GL_DEPTH_TEST));
    GL_CHECK(glDepthMask(GL_FALSE));
    GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
    GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

    GL_CHECK(glUseProgram(app->program_distort));
    GL_CHECK(glActiveTexture(GL_TEXTURE0));
    uniform1i(distort, framebuffer, 0);

    // Left eye
    GL_CHECK(glViewport(0, 0, View_Resolution_X, View_Resolution_Y));
    GL_CHECK(glBindTexture(GL_TEXTURE_2D_ARRAY, app->fb.colorbuffer));
    uniform1i(distort, layer_index, 0);
    GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, app->warp_mesh[0]));
    attribfv(distort, position,          2, 14, 0);
    attribfv(distort, uv_red_low_res,    2, 14, 2);
    attribfv(distort, uv_green_low_res,  2, 14, 4);
    attribfv(distort, uv_blue_low_res,   2, 14, 6);
    attribfv(distort, uv_red_high_res,   2, 14, 8);
    attribfv(distort, uv_green_high_res, 2, 14, 10);
    attribfv(distort, uv_blue_high_res,  2, 14, 12);
    GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, Warp_Mesh_Resolution_X * Warp_Mesh_Resolution_Y * 6));

    // Right eye
    GL_CHECK(glViewport(View_Resolution_X, 0, View_Resolution_X, View_Resolution_Y));
    uniform1i(distort, layer_index, 1);
    GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, app->warp_mesh[1]));
    attribfv(distort, position,          2, 14, 0);
    attribfv(distort, uv_red_low_res,    2, 14, 2);
    attribfv(distort, uv_green_low_res,  2, 14, 4);
    attribfv(distort, uv_blue_low_res,   2, 14, 6);
    attribfv(distort, uv_red_high_res,   2, 14, 8);
    attribfv(distort, uv_green_high_res, 2, 14, 10);
    attribfv(distort, uv_blue_high_res,  2, 14, 12);
    GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, Warp_Mesh_Resolution_X * Warp_Mesh_Resolution_Y * 6));
}
void app_update_and_render(App *app)
{
    app->current_scene = (int)(app->elapsed_time / 20.0f) % NUM_SCENES;
    Scene scene = app->scenes[app->current_scene];

    float model_scale = animate_model_scale(app->elapsed_time);

    float aspect_ratio = app->window_width / (float)app->window_height;
    mat4 mat_projection = perspective(scene.fov, aspect_ratio, scene.z_near, scene.z_far);
    mat4 mat_cube_model = rotateX(PI / 2.0f) * scale(model_scale);
    mat4 mat_view = animate_camera(app->elapsed_time);

    glEnable(GL_CULL_FACE);
    glFrontFace(GL_CCW);
    glCullFace(GL_BACK);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthRangef(0.0, 1.0);

    glClearDepthf(1.0f);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glBlendEquation(GL_FUNC_ADD);

    ////////////////
    // Draw backdrop
    glDepthMask(GL_FALSE);
    glUseProgram(app->program_backdrop);
    glBindBuffer(GL_ARRAY_BUFFER, app->vbo_quad);
    attribfv(backdrop, position, 2, 0);
    uniform3fv(backdrop,    sun_dir,        scene.sun_dir);
    uniform2f(backdrop,     screen_size,    app->window_width, app->window_height);
    uniform1f(backdrop,     inv_tan_fov,    1.0f / (scene.fov / 2.0f));
    uniformm4(backdrop,     view,           mat_view);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glDepthMask(GL_TRUE);

    //////////////////////////
    // Draw tessellated sphere
    glUseProgram(app->program_mapping);
    glBindBuffer(GL_ARRAY_BUFFER, app->vbo_cube);
    attribfv(mapping, position, 3, 0);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_CUBE_MAP, scene.heightmap);
    uniform1i(mapping, heightmap, 0);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_CUBE_MAP, scene.diffusemap);
    uniform1i(mapping, diffusemap, 1);

    uniform1f(mapping, height_scale,        scene.height_scale);
    uniform1f(mapping, use_mip,             scene.use_mip ? 1.0f : 0.0f);
    uniform1f(mapping, max_lod_coverage,    scene.max_lod_coverage);
    uniform2f(mapping, screen_size,         app->window_width, app->window_height);
    uniformm4(mapping, model,               mat_cube_model);
    uniformm4(mapping, view,                mat_view);
    uniformm4(mapping, projection,          mat_projection);
    glPatchParameteri(GL_PATCH_VERTICES, VERTICES_PER_PATCH);
    glDrawArrays(GL_PATCHES, 0, NUM_PATCHES * VERTICES_PER_PATCH);
}
Пример #3
0
void djvOpenGlImage::draw(
    const djvPixelData &          data,
    const djvOpenGlImageOptions & options,
    djvOpenGlImageState *         state) throw (djvError)
{
    //DJV_DEBUG("djvOpenGlImage::draw");
    //DJV_DEBUG_PRINT("data = " << data);
    //DJV_DEBUG_PRINT("color profile = " << options.colorProfile);
    
    RestoreState restoreState;

    djvOpenGlImageState defaultState;

    if (! state)
    {
        state = &defaultState;
    }

    const djvPixelDataInfo & info = data.info();

    const int proxyScale =
        options.proxyScale ?
        djvPixelDataUtil::proxyScale(info.proxy) :
        1;

    const djvVector2i scale = djvVectorUtil::ceil<double, int>(
        options.xform.scale * djvVector2f(info.size * proxyScale));

    const djvVector2i scaleTmp(scale.x, data.h());

    //DJV_DEBUG_PRINT("scale = " << scale);
    //DJV_DEBUG_PRINT("scale tmp = " << scaleTmp);

    // Initialize.

    const djvOpenGlImageFilter::FILTER filter =
        info.size == scale ? djvOpenGlImageFilter::NEAREST :
        (djvVectorUtil::area(scale) < djvVectorUtil::area(info.size) ?
         options.filter.min : options.filter.mag);

    //DJV_DEBUG_PRINT("filter min = " << options.filter.min);
    //DJV_DEBUG_PRINT("filter mag = " << options.filter.mag);
    //DJV_DEBUG_PRINT("filter = " << filter);

    if (! state->_init || state->_info != info || state->_options != options)
    {
        switch (filter)
        {
            case djvOpenGlImageFilter::NEAREST:
            case djvOpenGlImageFilter::LINEAR:
            {
                //DJV_DEBUG_PRINT("init single pass");

                state->_texture->init(
                    data.info(),
                    djvOpenGlImageFilter::toGl(filter),
                    djvOpenGlImageFilter::toGl(filter));

                state->_shader->init(
                    sourceVertex,
                    sourceFragment(
                        options.colorProfile.type,
                        options.displayProfile,
                        options.channel,
                        false,
                        0,
                        false));
            }
            break;

            case djvOpenGlImageFilter::BOX:
            case djvOpenGlImageFilter::TRIANGLE:
            case djvOpenGlImageFilter::BELL:
            case djvOpenGlImageFilter::BSPLINE:
            case djvOpenGlImageFilter::LANCZOS3:
            case djvOpenGlImageFilter::CUBIC:
            case djvOpenGlImageFilter::MITCHELL:
            {
                //DJV_DEBUG_PRINT("init two pass");

                state->_texture->init(
                    data.info(),
                    GL_NEAREST,
                    GL_NEAREST);

                // Initialize horizontal pass.

                djvPixelData contrib;

                scaleContrib(
                    data.w(),
                    scale.x,
                    filter,
                    contrib);

                state->_scaleXContrib->init(
                    contrib,
                    GL_NEAREST,
                    GL_NEAREST);

                state->_scaleXShader->init(
                    sourceVertex,
                    sourceFragment(
                        options.colorProfile.type,
                        djvOpenGlImageDisplayProfile(),
                        static_cast<djvOpenGlImageOptions::CHANNEL>(0),
                        true,
                        contrib.h(),
                        true));

                // Initialize vertical pass.

                scaleContrib(
                    data.h(),
                    scale.y,
                    filter,
                    contrib);

                state->_scaleYContrib->init(
                    contrib,
                    GL_NEAREST,
                    GL_NEAREST);

                state->_scaleYShader->init(
                    sourceVertex,
                    sourceFragment(
                        static_cast<djvColorProfile::PROFILE>(0),
                        options.displayProfile,
                        options.channel,
                        true,
                        contrib.h(),
                        false));
            }
            break;

            default: break;
        }

        state->_init    = true;
        state->_info    = info;
        state->_options = options;
    }

    // Render.

    const djvPixelDataInfo::Mirror mirror(
        info.mirror.x ? (! options.xform.mirror.x) : options.xform.mirror.x,
        info.mirror.y ? (! options.xform.mirror.y) : options.xform.mirror.y);

    //DJV_DEBUG_PRINT("mirror = " << mirror.x << " " << mirror.y);

    switch (filter)
    {
        case djvOpenGlImageFilter::NEAREST:
        case djvOpenGlImageFilter::LINEAR:
        {
            //DJV_DEBUG_PRINT("draw single pass");

            state->_shader->bind();

            // Initialize color and display profiles.

            colorProfileInit(
                options,
                state->_shader->program(),
                *state->_lutColorProfile);

            displayProfileInit(
                options,
                state->_shader->program(),
                *state->_lutDisplayProfile);

            // Draw.

            activeTexture(GL_TEXTURE0);

            uniform1i(state->_shader->program(), "inTexture", 0);

            state->_texture->copy(data);
            state->_texture->bind();

            DJV_DEBUG_OPEN_GL(glPushMatrix());
            const djvMatrix3f m = djvOpenGlImageXform::xformMatrix(options.xform);
            //DJV_DEBUG_PRINT("m = " << m);
            DJV_DEBUG_OPEN_GL(glLoadMatrixd(djvMatrixUtil::matrix4(m).e));

            quad(info.size, mirror, proxyScale);

            DJV_DEBUG_OPEN_GL(glPopMatrix());
        }
        break;

        case djvOpenGlImageFilter::BOX:
        case djvOpenGlImageFilter::TRIANGLE:
        case djvOpenGlImageFilter::BELL:
        case djvOpenGlImageFilter::BSPLINE:
        case djvOpenGlImageFilter::LANCZOS3:
        case djvOpenGlImageFilter::CUBIC:
        case djvOpenGlImageFilter::MITCHELL:
        {
            //DJV_DEBUG_PRINT("draw two pass");

            // Horizontal pass.

            djvOpenGlOffscreenBuffer buffer(
                djvPixelDataInfo(scaleTmp, data.pixel()));

            {
                djvOpenGlOffscreenBufferScope bufferScope(&buffer);

                state->_scaleXShader->bind();

                colorProfileInit(
                    options,
                    state->_scaleXShader->program(),
                    *state->_lutColorProfile);

                activeTexture(GL_TEXTURE0);

                uniform1i(state->_scaleXShader->program(), "inTexture", 0);

                state->_texture->copy(data);
                state->_texture->bind();

                activeTexture(GL_TEXTURE1);

                uniform1i(
                    state->_scaleXShader->program(), "inScaleContrib", 1);

                state->_scaleXContrib->bind();

                glPushAttrib(GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
                glMatrixMode(GL_PROJECTION);
                glPushMatrix();
                glMatrixMode(GL_MODELVIEW);
                glPushMatrix();

                djvOpenGlUtil::ortho(scaleTmp);
                glViewport(0, 0, scaleTmp.x, scaleTmp.y);
                quad(scaleTmp, mirror);

                glMatrixMode(GL_PROJECTION);
                glPopMatrix();
                glMatrixMode(GL_MODELVIEW);
                glPopMatrix();
                glPopAttrib();
            }

            // Vertical pass.

            state->_scaleYShader->bind();

            displayProfileInit(
                options,
                state->_scaleYShader->program(),
                *state->_lutDisplayProfile);

            activeTexture(GL_TEXTURE0);

            uniform1i(state->_scaleYShader->program(), "inTexture", 0);

            DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_2D, buffer.texture()));

            activeTexture(GL_TEXTURE1);

            uniform1i(state->_scaleYShader->program(), "inScaleContrib", 1);

            state->_scaleYContrib->bind();

            djvOpenGlImageXform xform = options.xform;
            xform.scale = djvVector2f(1.0);
            const djvMatrix3f m = djvOpenGlImageXform::xformMatrix(xform);

            DJV_DEBUG_OPEN_GL(glPushMatrix());
            DJV_DEBUG_OPEN_GL(glLoadMatrixd(djvMatrixUtil::matrix4(m).e));

            quad(scale);

            DJV_DEBUG_OPEN_GL(glPopMatrix());
        }
        break;

        default: break;
    }
}
Пример #4
0
/*! SLGLShaderProg::beginUse starts using the shaderprogram and transfers the 
the standard light and material parameter as uniform variables. It also passes 
the custom uniform variables of the _uniform1fList as well as the texture names.
*/
void SLGLShaderProg::beginUse(SLMaterial* mat)
{  
   if (_programObjectGL==0 && _shaderList.size()>0) init();

   if (_isLinked)
   {  
      // 1: Activate the shader program object
      _stateGL->useProgram(_programObjectGL);
            
      // 2: Pass light & material parameters
      _stateGL->globalAmbientLight = SLScene::current->globalAmbiLight();
      SLint loc = uniform4fv("u_globalAmbient",  1,  (SLfloat*) _stateGL->globalAmbient());
      loc = uniform1i("u_numLightsUsed", _stateGL->numLightsUsed);

      if (_stateGL->numLightsUsed > 0)
      {  SLint nL = SL_MAX_LIGHTS;
         _stateGL->calcLightPosVS(_stateGL->numLightsUsed);
         _stateGL->calcLightDirVS(_stateGL->numLightsUsed);
         loc = uniform1iv("u_lightIsOn",      nL, (SLint*)   _stateGL->lightIsOn);
         loc = uniform4fv("u_lightPosVS",     nL, (SLfloat*) _stateGL->lightPosVS);
         loc = uniform4fv("u_lightAmbient",   nL, (SLfloat*) _stateGL->lightAmbient);
         loc = uniform4fv("u_lightDiffuse",   nL, (SLfloat*) _stateGL->lightDiffuse);
         loc = uniform4fv("u_lightSpecular",  nL, (SLfloat*) _stateGL->lightSpecular);
         loc = uniform3fv("u_lightDirVS",     nL, (SLfloat*) _stateGL->lightDirVS);
         loc = uniform1fv("u_lightSpotCutoff",nL, (SLfloat*) _stateGL->lightSpotCutoff);
         loc = uniform1fv("u_lightSpotCosCut",nL, (SLfloat*) _stateGL->lightSpotCosCut);
         loc = uniform1fv("u_lightSpotExp",   nL, (SLfloat*) _stateGL->lightSpotExp);
         loc = uniform3fv("u_lightAtt",       nL, (SLfloat*) _stateGL->lightAtt);
         loc = uniform1iv("u_lightDoAtt",     nL, (SLint*)   _stateGL->lightDoAtt);
         loc = uniform4fv("u_matAmbient",     1,  (SLfloat*)&_stateGL->matAmbient);
         loc = uniform4fv("u_matDiffuse",     1,  (SLfloat*)&_stateGL->matDiffuse);
         loc = uniform4fv("u_matSpecular",    1,  (SLfloat*)&_stateGL->matSpecular);
         loc = uniform4fv("u_matEmissive",    1,  (SLfloat*)&_stateGL->matEmissive);
         loc = uniform1f ("u_matShininess",                  _stateGL->matShininess);
      }
      
      // 2b: Set stereo states
      loc = uniform1i ("u_projection", _stateGL->projection);
      loc = uniform1i ("u_stereoEye",  _stateGL->stereoEye);
      loc = uniformMatrix3fv("u_stereoColorFilter", 1, 
                             (SLfloat*)&_stateGL->stereoColorFilter);

      // 3: Pass the custom uniform1f variables of the list
      for (SLuint i=0; i<_uniform1fList.size(); i++)
      {  loc = uniform1f(_uniform1fList[i]->name(), _uniform1fList[i]->value());
      }
      for (SLuint i=0; i<_uniform1iList.size(); i++)
      {  loc = uniform1i(_uniform1iList[i]->name(), _uniform1iList[i]->value());
      }
      
      // 4: Send texture units as uniforms texture samplers
      if (mat)
      {  for (SLint i=0; i<(SLint)mat->textures().size(); ++i)
         {  SLchar name[100];
            sprintf(name,"u_texture%d", i);
            loc = uniform1i(name, i);
         }
      }
      GET_GL_ERROR;
   }
}