bool GLSLShader::activate_texture(TEXTUREglptr& tex) { // Load (if needed) and activate the texture. if (!load_texture(tex)) { bool debug=true; if (debug) { cerr << "GLSLShader::activate_texture: can't load texture: " << (tex ? tex->file() : "null pointer") << " at texture unit " << (tex ? tex->get_raw_unit() : -1) << endl; } return false; } tex->apply_texture(); if (debug) { char tmp[64]; sprintf(tmp, "%d", tex->get_raw_unit()); GL_VIEW_PRINT_GL_ERRORS( string("activating texture ") + (tex ? tex->file() : "null pointer") + " at unit " + tmp); } return true; }
void Halftone_TX::build_r_function_tex( TEXTUREglptr r_function_map, TEXTUREglptr source ) { uint* histogram_array = new uint[256 * LOD_RES]; uint sample_count = 0; //gets value from the function call below build_pattern_histogram(histogram_array,sample_count,source); // constructing the error correction table if (debug) cerr << "Halftone_TX::build_correction_tex: " << "Building the tone response map ... " << endl; // forward R texture compute_forward_R( sample_count, histogram_array, &(r_function_map->image()) ); if (debug) { r_function_map->image().write_png("test_r_function.png"); } delete[] histogram_array; }
// If this isn't declared static, it never gets called!!!!!!!!! static void init_params(TEXTUREglptr& tex) { // set parameters for 1D toon shading if (tex) { tex->set_wrap_s(GL_CLAMP_TO_EDGE); tex->set_wrap_t(GL_CLAMP_TO_EDGE); tex->set_mipmap(false); } }
inline bool load_texture(TEXTUREglptr& tex) { // Load the texture (should be already allocated TEXTUREgl // with filename set as member variable). // // Note: Does not activate the texture. // // This is a no-op of the texture was previously loaded. if (!tex) { return false; } else if (tex->is_valid()) { return true; } else if (tex->load_attempt_failed()) { // we previously tried to load this texture and failed. // no sense trying again with the same filename. return false; } return tex->load_texture(); }
void Halftone_TX::build_correction_tex( TEXTUREglptr correction_map, TEXTUREglptr source ) { stop_watch total_timer; // the histograms are fixed size of 256 buckets // and there is one for each of LOD_RES LOD values uint* histogram_array = new uint[256 * LOD_RES]; uint sample_count = 0; //gets value from the function call below build_pattern_histogram(histogram_array,sample_count,source); // constructing the error correction table if (debug) cerr << "Halftone_TX::build_correction_tex: " << "Building the tone response map ... " << endl; stop_watch inv_r_timer; // correction texture for (int i_lod=0; i_lod<LOD_RES; i_lod++) { //fills in a row of inverse R fot this lod value compute_inverse_R( i_lod, sample_count, histogram_array, &(correction_map->image()) ); } if (debug) { cerr << " Inverse R build time : " << inv_r_timer.elapsed_time() << endl; } if (debug) { cerr << "Total time ellapsed : " << total_timer.elapsed_time() << endl; } delete[] histogram_array; }
int FlatShadeTexture::draw(CVIEWptr& v) { if (_ctrl) return _ctrl->draw(v); _cb->alpha = alpha(); if (!_patch) return 0; // Don't draw w/ texture maps if there are no uv coords at all. // but don't check every frame whether there are uv coords: if (_check_uv_coords_stamp != _patch->stamp()) { _has_uv_coords = _patch->cur_faces().any_satisfy(HasUVFaceFilter()); _check_uv_coords_stamp = _patch->stamp(); } // Set gl state (lighting, shade model) glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_CURRENT_BIT); glEnable(GL_LIGHTING); // GL_ENABLE_BIT glShadeModel(GL_FLAT); // GL_LIGHTING_BIT GL_COL(_patch->color(), alpha()); // GL_CURRENT_BIT if (debug_uv()) { //assign some texture coords if no tex_coord_gen is assigned if (!_patch->tex_coord_gen()) { _patch->set_tex_coord_gen(new GLSphirTexCoordGen); } // decide what image file to use to show the uv-coords: str_ptr debug_uv_tex_name = Config::get_var_str("DEBUG_UV_TEX_MAP", "checkerboard.png",true); static str_ptr pre_path = Config::JOT_ROOT() + "nprdata/other_textures/"; str_ptr path = pre_path + debug_uv_tex_name; // we only try a given pathname once. but if it fails // and they reset DEBUG_UV_TEX_MAP while running the // program we can pick up the change and try again. if (path != _debug_tex_path) { _debug_tex_path = path; TEXTUREglptr tex = new TEXTUREgl(_debug_tex_path); bool do_mipmap = Config::get_var_bool("DEBUG_TEX_USE_MIPMAP",false); tex->set_mipmap(do_mipmap); _debug_uv_tex = tex; _debug_uv_in_dl = false; if (debug) { cerr << "Loading debug uv texture " << **path << " ..." << endl; } if (!_debug_uv_tex->load_texture()) { cerr << "Can't load debug uv texture: " << **_debug_tex_path << endl << "Set environment variable DEBUG_UV_TEX_MAP " << "to an image file in " << **pre_path << " and try again." << endl; _debug_uv_tex = 0; } } // Apply the texture if any faces have uv coordinates: if (_debug_uv_tex /*&& _has_uv_coords*/) //<- using auto UV _debug_uv_tex->apply_texture(); // GL_ENABLE_BIT } else { // XXX - dumb hack check_patch_texture_map(); // if (_has_uv_coords) <- using auto UV _patch->apply_texture(); // GL_ENABLE_BIT } // Set material parameters for OGL: GtexUtil::setup_material(_patch); // Try for the display list if it's valid if (!(_debug_uv == _debug_uv_in_dl && BasicTexture::draw(v))) { // Try to generate a display list int dl = _dl.get_dl(v, 1, _patch->stamp()); if (dl) { glNewList(dl, GL_COMPILE); _debug_uv_in_dl = _debug_uv; } // Set up face culling for closed surfaces if (!set_face_culling()) glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); // GL_LIGHTING_BIT FlatShadeStripCB *flat_cb = dynamic_cast<FlatShadeStripCB*>(_cb); if (flat_cb) { // send texture coordinates? if ((_debug_uv && _debug_uv_tex) || (_has_uv_coords && _patch->has_texture())) { flat_cb->enable_texcoords(); } else { flat_cb->disable_texcoords(); } } err_adv(debug && _debug_uv, " drawing uvs in flat shade"); // draw the triangle strips _patch->draw_tri_strips(_cb); // end the display list here if (_dl.dl(v)) { _dl.close_dl(v); // the display list is built; now execute it BasicTexture::draw(v); } } // restore GL state glPopAttrib(); // Have to move this outside the display list and gl push/pop attrib // or else it's all: /* FlatShadeTexture::draw - End ***NOTE*** OpenGL Error: [500] 'Invalid Enumerator' FlatShadeTexture::draw - End ***NOTE*** OpenGL Error: [500] 'Invalid Enumerator' FlatShadeTexture::draw - End ***NOTE*** OpenGL Error: [500] 'Invalid Enumerator' FlatShadeTexture::draw - End ***NOTE*** OpenGL Error: [500] 'Invalid Enumerator' FlatShadeTexture::draw - End ***NOTE*** OpenGL Error: [500] 'Invalid Enumerator' FlatShadeTexture::draw - End ***NOTE*** OpenGL Error: [500] 'Invalid Enumerator' FlatShadeTexture::draw - End ***NOTE*** OpenGL Error: [500] 'Invalid Enumerator' FlatShadeTexture::draw - End ***NOTE*** OpenGL Error: [500] 'Invalid Enumerator' */ if (_debug_uv) { // Build the edge strip at the current subdivision level Bedge_list edges = _patch->cur_edges(); edges.clear_flags(); // If secondary edges shouldn't be drawn, set their flags // so they won't be drawn: if (!BMESH::show_secondary_faces()) edges.secondary_edges().set_flags(1); // Draw uv-discontinuity boundaries as yellow lines. // Construct filter that accepts unreached uv-discontinuous // edges of this patch: UnreachedSimplexFilter unreached; UVDiscontinuousEdgeFilter uvdisc; PatchEdgeFilter mine(_patch->cur_patch()); EdgeStrip disc_edges(edges, unreached + uvdisc + mine); if (!disc_edges.empty()) { GtexUtil::draw_strip(disc_edges, 3, Color::yellow, 0.8); } } GL_VIEW::print_gl_errors("FlatShadeTexture::draw - End"); return _patch->num_faces(); }
void NPRSolidTexture::update_tex(void) { map<string,TEXTUREptr>::iterator ind; if (!_solid_texture_map) { _solid_texture_map = new map<string,TEXTUREptr>; assert(_solid_texture_map); _solid_texture_remap = new map<string,string>; assert(_solid_texture_remap); int i = 0; while (solid_remap_fnames[i][0] != nullptr) { (*_solid_texture_remap)[string(solid_remap_base) + solid_remap_fnames[i][0]] = string(solid_remap_base) + solid_remap_fnames[i][1]; i++; } } string tf = _tex_name; if (tf == "") { assert(_tex == nullptr); //_tex_name = ""; //_tex = nullptr; } else if (_tex == nullptr) { if ((ind = _solid_texture_map->find(tf)) != _solid_texture_map->end()) { //Finding original name in cache... //If its a failed texture... if (ind->second == nullptr) { //...see if it was remapped... map<string,string>::iterator ii = _solid_texture_remap->find(tf); //...and change to looking up the remapped name if (ii != _solid_texture_remap->end()) { string old_tf = tf; tf = ii->second; ind = _solid_texture_map->find(tf); err_mesg(ERR_LEV_SPAM, "NPRSolidTexture::set_texture() - Previously remapped --===<<[[{{ (%s) ---> (%s) }}]]>>===--", (Config::JOT_ROOT()+old_tf).c_str(), (Config::JOT_ROOT()+tf).c_str()); } } //Now see if the final name yields a good texture... if (ind->second != nullptr) { _tex = ind->second; _tex_name = tf; err_mesg(ERR_LEV_SPAM, "NPRSolidTexture::set_texture() - Using cached copy of texture."); } else { err_mesg(ERR_LEV_INFO, "NPRSolidTexture::set_texture() - **ERROR** Previous caching failure: '%s'...", tf.c_str()); _tex = nullptr; _tex_name = ""; } //Haven't seen this name before... } else { err_mesg(ERR_LEV_SPAM, "NPRSolidTexture::set_texture() - Not in cache..."); Image i(Config::JOT_ROOT()+tf); //Can't load the texture? if (i.empty()) { //...check for a remapped file... map<string,string>::iterator ii = _solid_texture_remap->find(tf); //...and use that name instead.... if (ii != _solid_texture_remap->end()) { //...but also indicate that the original name is bad... (*_solid_texture_map)[tf] = nullptr; string old_tf = tf; tf = ii->second; err_mesg(ERR_LEV_ERROR, "NPRSolidTexture::set_texture() - Remapping --===<<[[{{ (%s) ---> (%s) }}]]>>===--", (Config::JOT_ROOT()+old_tf).c_str(), (Config::JOT_ROOT()+tf).c_str()); i.load_file(Config::JOT_ROOT()+tf); } } //If the final name loads, store the cached texture... if (!i.empty()) { TEXTUREglptr t = make_shared<TEXTUREgl>(); t->set_save_img(true); t->set_image(i.copy(), i.width(), i.height(), i.bpp()); (*_solid_texture_map)[tf] = t; err_mesg(ERR_LEV_INFO, "NPRSolidTexture::set_texture() - Cached: (w=%d h=%d bpp=%u) %s", i.width(), i.height(), i.bpp(), (Config::JOT_ROOT()+tf).c_str()); _tex = t; _tex_name = tf; //Otherwise insert a failed nullptr } else { err_mesg(ERR_LEV_ERROR, "NPRSolidTexture::set_texture() - *****ERROR***** Failed loading to cache: '%s'...", (Config::JOT_ROOT()+tf).c_str()); (*_solid_texture_map)[tf] = nullptr; _tex = nullptr; _tex_name = ""; } } } if (_tex) nst_tex_flag = true; else nst_tex_flag = false; }
void SKY_BOX::test_perlin(CVIEWptr &v) { //test if (!perlin_tex) { perlin_tex = make_shared<TEXTUREgl>( Config::JOT_ROOT() + "nprdata/other_textures/" + "perlin_tex_RGB.png" ); perlin_tex->load_texture(); } assert(perlin_tex); if (perlin_tex->load_attempt_failed()) { cerr << "SKY_BOX::test_perlin: could not load file: " << perlin_tex->file() << endl; return; } // load identity for model matrix glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); // set up to draw in XY coords: glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadMatrixd(VIEW::peek()->xypt_proj().transpose().matrix()); // set opengl state: glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); // prevents depth testing AND writing to depth buffer glDisable(GL_ALPHA_TEST); //glDisable(GL_BLEND); perlin_tex->apply_texture(); // GL_ENABLE_BIT GLfloat a = 0.5f; glColor4f(0.5, 0.5, 0.5, 1); glBegin(GL_QUADS); // draw vertices in CCW order starting at bottom left: glTexCoord2f( 0, 0); glVertex2f (-a, -a); glTexCoord2f( 1, 0); glVertex2f ( a, -a); glTexCoord2f( 1, 1); glVertex2f ( a, a); glTexCoord2f( 0, 1); glVertex2f (-a, a); glEnd(); // restore state: glPopAttrib(); // restore projection matrix glMatrixMode(GL_PROJECTION); glPopMatrix(); // restore modelview matrix glMatrixMode(GL_MODELVIEW); glPopMatrix(); }
void Halftone_TX::build_pattern_histogram( uint* histogram, uint &sample_count, TEXTUREglptr source ) { // hardcoded to 256x256 array of histograms for each lod value assert(histogram); stop_watch hist_timer; if (debug) { cerr << " Constructing histogram array ... "; } for (int i=0 ; i<(256*LOD_RES); i++) histogram[i] = 0; uint X_tex; uint Y_tex; if (source) { X_tex = source->get_size()[0]; Y_tex = source->get_size()[1]; } else { //for procedural pattern we use maximum sampling resolution X_tex = 256; Y_tex = 256; } sample_count = X_tex * Y_tex; // building the regular histogram for each LOD value; for (int i_lod=0; i_lod<LOD_RES; i_lod++) { double f_lod = double(i_lod)/double(LOD_RES-1); // 0.0~1.0 for (uint x=0; x<X_tex; x++) for (uint y=0; y<Y_tex; y++) { double sample; if (source) { //sample the halftone texture double sample_hi = source->image().pixel_r((x*2)%X_tex, (y*2) % Y_tex); double sample_lo = source->image().pixel_r(x, y); sample = min(255.0, interp(sample_lo,sample_hi,f_lod)); } else { //sample procedural dots double sample_hi = procedural_dots((double(x)/double(X_tex-1)) * 2.0 , (double(y)/double(Y_tex-1)) * 2.0); double sample_lo = procedural_dots(double(x)/double(X_tex-1), double(y)/double(Y_tex-1)); sample = min(255.0, interp(sample_lo,sample_hi,f_lod)*255.0); } uint bucket = uint(sample + 0.5 ); histogram[256 * i_lod + bucket]+= 1; } } if (debug) { cerr << "Histogram built time : " << hist_timer.elapsed_time() << endl; } }