Search code examples
c++pathiostreamtga

Save file at path using iostream


I'm currently playing around with some 3D software rendering I implemented with lua and love2d. Someone in the forums showed me this link to learn even more : C++ Software Renderer

This is a tutorial for a software renderer written in C++ where no additional libraries are used. So I thought this would be a good start.

However I'm kinda new to C++ though I have experience with C, Objective-C, Swift, Java and Lua.

To start I loaded 3 files into an Command Line C++ Xcode project.

  • main.cpp
  • tgaimage.h
  • tgaimage.cpp

When I build run the application I'm supposed to get an .tga file which is located in User/Libraries/Developer/Xcode/projectname/Build/Products/Debug/output.tga I could change the path to my working directory located in User/Developer/Xcode Projects/tinyRenderer/ or I could do it in code. However that is exactly I don't know how to do.

In main.cpp:

image.write_tga_file("output.tga");

is called.

In tgaimage.h:

bool write_tga_file(const char *filename, bool rle=true);

And the implementation file:

bool TGAImage::write_tga_file(const char *filename, bool rle) {
    unsigned char developer_area_ref[4] = {0, 0, 0, 0};
    unsigned char extension_area_ref[4] = {0, 0, 0, 0};
    unsigned char footer[18] = {'T','R','U','E','V','I','S','I','O','N','-','X','F','I','L','E','.','\0'};
    std::ofstream out;
    out.open (filename, std::ios::binary);
    if (!out.is_open()) {
        std::cerr << "can't open file " << filename << "\n";
        out.close();
        return false;
    }
    TGA_Header header;
    memset((void *)&header, 0, sizeof(header));
    header.bitsperpixel = bytespp<<3;
    header.width  = width;
    header.height = height;
    header.datatypecode = (bytespp==GRAYSCALE?(rle?11:3):(rle?10:2));
    header.imagedescriptor = 0x20; // top-left origin
    out.write((char *)&header, sizeof(header));
    if (!out.good()) {
        out.close();
        std::cerr << "can't dump the tga file\n";
        return false;
    }
    if (!rle) {
        out.write((char *)data, width*height*bytespp);
        if (!out.good()) {
            std::cerr << "can't unload raw data\n";
            out.close();
            return false;
        }
    } else {
        if (!unload_rle_data(out)) {
            out.close();
            std::cerr << "can't unload rle data\n";
            return false;
        }
    }
    out.write((char *)developer_area_ref, sizeof(developer_area_ref));
    if (!out.good()) {
        std::cerr << "can't dump the tga file\n";
        out.close();
        return false;
    }
    out.write((char *)extension_area_ref, sizeof(extension_area_ref));
    if (!out.good()) {
        std::cerr << "can't dump the tga file\n";
        out.close();
        return false;
    }
    out.write((char *)footer, sizeof(footer));
    if (!out.good()) {
        std::cerr << "can't dump the tga file\n";
        out.close();
        return false;
    }
    out.close();
    return true;
}

How do I make it save the file at a distinct path?


Solution

  • You can create a file at a given path via:

    const char* out_file_path = "C:/User/Name/Documents/filename.txt";
    std::ofstream out_file(out_file_path);
    

    This creates a file (on Windows) called filename.txt in the path User/Name/Documents. Of course, this will work for any path you give, so just give the necessary path-name in the const char* parameter and you're set.