OpenSubdiv::OsdGLPtexTexture *
OpenSubdivPtexShader::loadPtex(const MString &filename)
{
    if (filename.length()) {
        printf("Load ptex %s\n", filename.asChar());
        Ptex::String ptexError;
        PtexTexture *ptex = PtexTexture::open(filename.asChar(),
                                              ptexError, true);
        if (ptex) {
            // create osdptex
            OpenSubdiv::OsdGLPtexTexture *osdptex =
                OpenSubdiv::OsdGLPtexTexture::Create(ptex, 0,
                        /*gutterWidth=*/1,
                        /*pageMargin=*/8);
            ptex->release();
            return osdptex;
        }
        printf("Load ptex failed on file: \"%s\"\n", filename.asChar());
    }
    return NULL;
}
Beispiel #2
0
bool readEnvcube(const std::string& path, Img images[6])
{
    std::string error;
    PtexTexture* ptx = PtexTexture::open(path.c_str(), error);
    if (!ptx) {
        std::cerr << error << std::endl;
        return 0;
    }
    if (ptx->numFaces() != 6) {
        std::cerr << "Error: Ptex envcube file doesn't have six faces: "<< path << "\n";
        ptx->release();
        return 0;
    }
    bool ok;
    for (int i = 0; i < 6; i++) {
        ok = PtexToImg(ptx, images[i], /*faceid*/ i, /*flip*/ false);
        if (!ok) break;
    }
    ptx->release();
    return ok;
}
Beispiel #3
0
bool readImage(const std::string& path, Img& img)
{
    if (endsWith(path, ".ptx")) {
        img.path = path;
        // read ptx face-zero image
        std::string error;
        PtexTexture* ptx = PtexTexture::open(path.c_str(), error);
        if (!ptx) {
            std::cerr << error << std::endl;
            return 0;
        }
        if (ptx->numFaces() != 1) {
            std::cerr << "Error: Ptex file has multiple faces (not yet supported)" << std::endl;
            ptx->release();
            return 0;
        }
        bool ok = PtexToImg(ptx, img, /*faceid*/ 0, /*flip*/ true);
        ptx->release();
        return ok;
    }
    else {
        return img.load(path);
    }
}
Beispiel #4
0
bool PtexWriter::applyEdits(const char* path, Ptex::String& error)
{
    // open reader for existing file
    PtexTexture* tex = PtexTexture::open(path, error);
    if (!tex) return 0;

    // see if we have any edits to apply
    if (tex->hasEdits()) {
	// create non-incremental writer
	PtexWriter* w = new PtexMainWriter(path, tex, tex->meshType(), tex->dataType(),
					   tex->numChannels(), tex->alphaChannel(), tex->numFaces(),
					   tex->hasMipMaps());
	// close to rebuild file
	if (!w->close(error)) return 0;
	w->release();
    }
    return 1;
}
Beispiel #5
0
PtexWriter* PtexWriter::edit(const char* path, bool incremental,
			     Ptex::MeshType mt, Ptex::DataType dt,
			     int nchannels, int alphachan, int nfaces,
			     Ptex::String& error, bool genmipmaps)
{
    if (!checkFormat(mt, dt, nchannels, alphachan, error))
	return 0;

    // try to open existing file (it might not exist)
    FILE* fp = fopen(path, "rb+");
    if (!fp && errno != ENOENT) {
	error = fileError("Can't open ptex file for update: ", path).c_str();
    }

    PtexWriterBase* w = 0;
    // use incremental writer iff incremental mode requested and file exists
    if (incremental && fp) {
	w = new PtexIncrWriter(path, fp, mt, dt, nchannels, alphachan, nfaces);
    }
    // otherwise use main writer
    else {
	PtexTexture* tex = 0;
	if (fp) {
	    // got an existing file, close and reopen with PtexReader
	    fclose(fp);

	    // open reader for existing file
	    tex = PtexTexture::open(path, error);
	    if (!tex) return 0;

	    // make sure header matches
	    bool headerMatch = (mt == tex->meshType() &&
				dt == tex->dataType() &&
				nchannels == tex->numChannels() &&
				alphachan == tex->alphaChannel() &&
				nfaces == tex->numFaces());
	    if (!headerMatch) {
		std::stringstream str;
		str << "PtexWriter::edit error: header doesn't match existing file, "
		    << "conversions not currently supported";
		error = str.str().c_str();
		return 0;
	    }
	}
	w = new PtexMainWriter(path, tex, mt, dt, nchannels, alphachan,
			       nfaces, genmipmaps);
    }

    if (!w->ok(error)) {
	w->release();
	return 0;
    }
    return w;
}
Beispiel #6
0
void IBLWidget::loadIBL( const char* filename )
{
    printf( "opening %s... ", filename );

    // try and load it
    Ptex::String error;
    PtexTexture* tx = PtexTexture::open(filename, error);
    if (!tx) {
        printf( "failed\n");
        return;
    }

    CKGL();

    Ptex::DataType dataType = tx->dataType();
    int numChannels = tx->numChannels();
    int numFaces=tx->numFaces();
    int faceWidth=0, faceHeight=0;

    if( dataType != Ptex::dt_float || numChannels != 3 || numFaces != 6 )
    {
        printf( "not the right kind\n" );
        return;
    }

    for( int i = 0; i < numFaces; i++ )
    {
        int face = i;


        Ptex::Res res = tx->getFaceInfo(i).res;
        if( i == 0 )
        {
            faceWidth = res.u();
            faceHeight = res.v();

            // printf( "size: %dx%d    (%dx%d)\n", faceWidth, faceHeight, faceWidth*6, faceHeight );

            envTex.create( faceWidth*6, faceHeight );
        }

        if( faceWidth != res.u() || faceHeight != res.v() )
        {
            printf( "error loading ptex file\n" );
            return;
        }

        float* faceData = (float*)malloc( faceWidth*faceHeight*numChannels*sizeof(float) );
        tx->getData( i, faceData, 0 );

        // copy the data into the envmap texture
        for( int j = 0; j < faceHeight * faceWidth; j++ )
        {
            color3 c( faceData[j*3+0], faceData[j*3+1], faceData[j*3+2] );
            envTex.setPixel( faceWidth*face + j % faceWidth, j / faceWidth, c );
        }

        free( faceData );

    }
    tx->release();
    printf( "success\n");

    // allocate texture names (if we haven't before)
    if( envTexID == 0 ) {
        glf->glGenTextures( 1, &envTexID );
        glf->glGenTextures( 1, &probTexID );
        glf->glGenTextures( 1, &marginalProbTexID );
    }

    CKGL();

    // now that the envmap tex is loaded, compute the sampling data
    computeEnvMapSamplingData();
    createGLSamplingTextures();

    CKGL();

    glf->glGenTextures(1, &envTexID);
    glf->glBindTexture( GL_TEXTURE_CUBE_MAP, envTexID );
    glf->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);


    BitmapContainer<color3> flip;
    flip.create(envTex.w, envTex.h);//get face flipped to match GL thinking!
    for (int y=0; y < envTex.h; y++){
        color3* in = &envTex.data[y*envTex.w];
        color3* out = &flip.data[(envTex.h-y-1)*envTex.w];
        for (int x=0; x < envTex.w; x++)
            out[x] = in[x];
    }

    BitmapContainer<color3> tmp;
    tmp.create(envTex.h, envTex.h);

    CKGL();

    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*0, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );


    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*1, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_X , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );

    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*2, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Y , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );

    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*3, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );

    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*4, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Z , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );


    CKGL();

    for (int y=0; y < tmp.h; y++)
        for (int x=0; x < tmp.w; x++)
            tmp.setPixel(x, y,flip.getPixel(x+tmp.w*5, y));
    glf->glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z , 0,GL_R11F_G11F_B10F, tmp.w, tmp.h, 0, GL_RGB, GL_FLOAT, tmp.getPtr() );

    CKGL();

    glf->glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
    glf->glBindTexture( GL_TEXTURE_CUBE_MAP, 0 );

    CKGL();
}
Beispiel #7
0
  OBJScene::Texture *loadPtexTexture(const FileName& filename)
  {
#if defined(USE_PTEX)
    std::string fn = filename.str();
    Ptex::String error;
    std::cout << "opening " << fn << " ... " << std::flush;
    PtexTexture* tex = PtexTexture::open(fn.c_str(),error);
    if (!tex) {
      std::cout << "[FAILED]" << std::endl;
      THROW_RUNTIME_ERROR("cannot open ptex file: "+fn);
    }
    
    PtexMetaData *metadata = tex->getMetaData();
    const int32_t *vertices_per_face = nullptr;
    int geom_faces = 0;
    metadata->getValue("PtexFaceVertCounts", vertices_per_face, geom_faces);

    OBJScene::Texture **face_textures = new OBJScene::Texture *[geom_faces];
    for (size_t i=0;i<geom_faces;i++)
      face_textures[i] = nullptr;

    OBJScene::Texture *texture = new OBJScene::Texture();
    texture->width         = 0;
    texture->height        = 0;    
    texture->format        = OBJScene::Texture::PTEX_RGBA8;
    texture->faceTextures  = geom_faces;
    texture->data          = face_textures;
    texture->width_mask    = 0;
    texture->height_mask   = 0;

    int nchan = tex->numChannels();
    if (nchan != 3 && nchan != 1) 
      {
	std::cout << "[FAILED]" << std::endl;
	THROW_RUNTIME_ERROR(fn+": ptex file with other than 1 or 3 channels found!");
      }

    if (nchan == 1)
      texture->format = OBJScene::Texture::PTEX_FLOAT32;

    float px[3];
    int ptex_face_id = 0;

    for (size_t geom_face_id=0;geom_face_id<geom_faces;geom_face_id++)
      {
	face_textures[geom_face_id] = nullptr;
	const Ptex::FaceInfo &fi = tex->getFaceInfo(ptex_face_id);

	int n = vertices_per_face[geom_face_id];
	if (n == 4) /* ptex data only for quads */
	  {
	    Ptex::Res res = fi.res;
			  
	    OBJScene::Texture *face_txt = new OBJScene::Texture();
	    face_txt->width         = res.u();
	    face_txt->height        = res.v();    
	    face_txt->width_mask    =  0;
	    face_txt->height_mask   =  0;
	    face_txt->data          = nullptr;
	    face_textures[geom_face_id] = face_txt;
	  
	    if (nchan == 3) /* rgb color data */
	      {
		face_txt->format        = OBJScene::Texture::RGBA8;
		face_txt->bytesPerTexel = 4;
		unsigned char *data     = new unsigned char[face_txt->bytesPerTexel*face_txt->width*face_txt->height];
		face_txt->data          = data;

		for (int vi = 0; vi < face_txt->height; vi++) {
		  for (int ui = 0; ui < face_txt->width; ui++) {
		    tex->getPixel(ptex_face_id, ui, vi, px, 0, nchan, res);
		    data[(vi*face_txt->width+ui)*4+0] = (unsigned char)(px[0]*255.0f);
		    data[(vi*face_txt->width+ui)*4+1] = (unsigned char)(px[1]*255.0f);
		    data[(vi*face_txt->width+ui)*4+2] = (unsigned char)(px[2]*255.0f);
		  }
		}
	      }
	    else if (nchan == 1) /* displacement data */
	      {
		face_txt->format        = OBJScene::Texture::FLOAT32;
		face_txt->bytesPerTexel = 4;
		float*data              = new float[face_txt->width*face_txt->height];
		face_txt->data          = data;

		for (int vi = 0; vi < face_txt->height; vi++) {
		  for (int ui = 0; ui < face_txt->width; ui++) {
		    tex->getPixel(ptex_face_id, ui, vi, px, 0, nchan, res);
		    if (!isfinite(px[0]))
		      px[0] = 0.0f;
		    data[vi*face_txt->width+ui] = px[0];
		  }
		}
	      }
	    ptex_face_id++;
	  }
	else 
	    ptex_face_id += 3;
      }
    std::cout << "done" << std::endl << std::flush;
    return texture;	
#else
    return nullptr;
#endif
  }
Beispiel #8
0
//------------------------------------------------------------------------------
void
createOsdMesh(int level, int kernel) {

    Ptex::String ptexError;
    PtexTexture *ptexColor = PtexTexture::open(g_ptexColorFile, ptexError, true);

    // generate Hbr representation from ptex
    OpenSubdiv::OsdHbrMesh * hmesh = createPTexGeo<OpenSubdiv::OsdVertex>(ptexColor);
    if(hmesh == NULL) return;

    g_normals.resize(g_positions.size(),0.0f);
    calcNormals( hmesh, g_positions, g_normals );

    // generate Osd mesh from Hbr mesh
    if (g_osdmesh) delete g_osdmesh;
    g_osdmesh = new OpenSubdiv::OsdMesh();
    g_osdmesh->Create(hmesh, level, kernel);
    if (g_vertexBuffer) {
        delete g_vertexBuffer;
        g_vertexBuffer = NULL;
    }

    // Hbr mesh can be deleted
    delete hmesh;

    // generate oOsdPTexture
    if (g_osdPTexDisplacement) delete g_osdPTexDisplacement;
    if (g_osdPTexOcclusion) delete g_osdPTexOcclusion;
    g_osdPTexDisplacement = NULL;
    g_osdPTexOcclusion = NULL;

    OpenSubdiv::OsdPTexture::SetGutterWidth(g_gutterWidth);
    OpenSubdiv::OsdPTexture::SetPageMargin(g_gutterWidth*8);
    OpenSubdiv::OsdPTexture::SetGutterDebug(g_gutterDebug);

    if (g_osdPTexImage) delete g_osdPTexImage;
    g_osdPTexImage = OpenSubdiv::OsdPTexture::Create(ptexColor, 0 /*targetmemory*/);
    ptexColor->release();

    if (g_ptexDisplacementFile) {
        PtexTexture *ptexDisplacement = PtexTexture::open(g_ptexDisplacementFile, ptexError, true);
        g_osdPTexDisplacement = OpenSubdiv::OsdPTexture::Create(ptexDisplacement, 0);
        ptexDisplacement->release();
    }
    if (g_ptexOcclusionFile) {
        PtexTexture *ptexOcclusion = PtexTexture::open(g_ptexOcclusionFile, ptexError, true);
        g_osdPTexOcclusion = OpenSubdiv::OsdPTexture::Create(ptexOcclusion, 0);
        ptexOcclusion->release();
    }

    // create element array buffer
    if (g_elementArrayBuffer) delete g_elementArrayBuffer;
    g_elementArrayBuffer = g_osdmesh->CreateElementArrayBuffer(level);

    // create ptex coordinates buffer
    if (g_ptexCoordinatesTextureBuffer) delete g_ptexCoordinatesTextureBuffer;
    g_ptexCoordinatesTextureBuffer = g_osdmesh->CreatePtexCoordinatesTextureBuffer(level);
    
    updateGeom();

    linkProgram();
    linkDebugProgram();
}
Beispiel #9
0
//------------------------------------------------------------------------------
void
createOsdMesh(int level, int kernel) {

    Ptex::String ptexError;
    PtexTexture *ptexColor = PtexTexture::open(g_ptexColorFile, ptexError, true);

    // generate Hbr representation from ptex
    OpenSubdiv::OsdHbrMesh * hmesh = createPTexGeo<OpenSubdiv::OsdVertex>(ptexColor);
    if(hmesh == NULL) return;

    g_normals.resize(g_positions.size(),0.0f);
    calcNormals( hmesh, g_positions, g_normals );

    // generate Osd mesh from Hbr mesh
    if (g_osdmesh) delete g_osdmesh;
    g_osdmesh = new OpenSubdiv::OsdMesh();
    g_osdmesh->Create(hmesh, level, kernel);
    if (g_vertexBuffer) {
        delete g_vertexBuffer;
        g_vertexBuffer = NULL;
    }

    // Hbr mesh can be deleted
    delete hmesh;

    // update element array buffer
    const std::vector<int> &indices = g_osdmesh->GetFarMesh()->GetFaceVertices(level);

    // generate oOsdPTexture
    if (g_osdPTexDisplacement) delete g_osdPTexDisplacement;
    if (g_osdPTexOcclusion) delete g_osdPTexOcclusion;
    g_osdPTexDisplacement = NULL;
    g_osdPTexOcclusion = NULL;

    OpenSubdiv::OsdPTexture::SetGutterWidth(g_gutterWidth);
    OpenSubdiv::OsdPTexture::SetPageMargin(g_gutterWidth*8);
    OpenSubdiv::OsdPTexture::SetGutterDebug(g_gutterDebug);

    if (g_osdPTexImage) delete g_osdPTexImage;
    g_osdPTexImage = OpenSubdiv::OsdPTexture::Create(ptexColor, 0 /*targetmemory*/);
    ptexColor->release();

    if (g_ptexDisplacementFile) {
        PtexTexture *ptexDisplacement = PtexTexture::open(g_ptexDisplacementFile, ptexError, true);
        g_osdPTexDisplacement = OpenSubdiv::OsdPTexture::Create(ptexDisplacement, 0);
        ptexDisplacement->release();
    }
    if (g_ptexOcclusionFile) {
        PtexTexture *ptexOcclusion = PtexTexture::open(g_ptexOcclusionFile, ptexError, true);
        g_osdPTexOcclusion = OpenSubdiv::OsdPTexture::Create(ptexOcclusion, 0);
        ptexOcclusion->release();
    }

    // bind index buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indexBuffer);

    g_numIndices = (int)indices.size();
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*g_numIndices, &(indices[0]), GL_STATIC_DRAW);

    updateGeom();

    linkProgram();
    linkDebugProgram();
}