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); }
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; } }
/*! 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; } }