2013-12-15 6 views
10

में एक tga/bmp फ़ाइल लोड हो रहा है मैं एक tga/bmp फ़ाइल लोड करने का प्रयास कर रहा हूं। यह ठीक काम करता है, लेकिन अंतिम परिणाम इस प्रकार है:सी ++/ओपनजीएल

enter image description here

छवि मैं लोड करने के लिए कोशिश कर रहा हूँ इस तरह दिखता है:

enter image description here

कोड में से कुछ मैं उपयोग कर रहा हूँ :

GLuint texture; 
const char* filename = "/Users/Admin/Documents/Visual Studio 2013/Projects/OpenGL/OpenGL/image.tga"; 

unsigned char* data; 
data = (unsigned char *) malloc(128 * 128 * 3); 
FILE* f; 
fopen_s(&f, filename, "rb"); 
fread(data, 128 * 128 * 3, 1, f); 

glGenTextures(1, &texture); 
glBindTexture(GL_TEXTURE_2D, texture); 

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, data); 

क्या किसी को पता है कि मैं क्या गलत कर रहा हूं?

+4

TGA फ़ाइलें एक हैडर कि वे नहीं है? ऐसा लगता है कि आप इसे 128x128 पिक्सेल कच्चे होने की उम्मीद कर रहे हैं। मुझे नहीं पता कि आप काम करने की अपेक्षा क्यों करेंगे। –

+0

बस सोच रहा है, लेकिन यदि आप सी ++ का उपयोग कर रहे हैं तो आप 'malloc()' का उपयोग क्यों कर रहे हैं? – Vallentin

+0

मैंने देखा कि एक और ट्यूटोरियल पर। मैंने अलग-अलग चीजों की कोशिश की, उदाहरण के लिए malloc() का उपयोग करके, लेकिन परिणाम – user3075425

उत्तर

15

आप एक बिटमैप और एक TGA फ़ाइल इन ..

#include <vector> 
#include <fstream> 

#ifdef __APPLE__ 
#include <OpenGL/gl.h> 
#include <OpenGL/glu.h> 
#endif 


#ifdef _WIN32 
#include <GL/gl.h> 
#include <GL/glu.h> 
#endif 


typedef union PixelInfo 
{ 
    std::uint32_t Colour; 
    struct 
    { 
     std::uint8_t B, G, R, A; 
    }; 
} *PPixelInfo; 


class BMP 
{ 
private: 
    std::uint32_t width, height; 
    std::uint16_t BitsPerPixel; 
    std::vector<std::uint8_t> Pixels; 

public: 
    BMP(const char* FilePath); 
    std::vector<std::uint8_t> GetPixels() const {return this->Pixels;} 
    std::uint32_t GetWidth() const {return this->width;} 
    std::uint32_t GetHeight() const {return this->height;} 
    bool HasAlphaChannel() {return BitsPerPixel == 32;} 
}; 

BMP::BMP(const char* FilePath) 
{ 
    std::fstream hFile(FilePath, std::ios::in | std::ios::binary); 
    if (!hFile.is_open()) throw std::invalid_argument("Error: File Not Found."); 

    hFile.seekg(0, std::ios::end); 
    std::size_t Length = hFile.tellg(); 
    hFile.seekg(0, std::ios::beg); 
    std::vector<std::uint8_t> FileInfo(Length); 
    hFile.read(reinterpret_cast<char*>(FileInfo.data()), 54); 

    if(FileInfo[0] != 'B' && FileInfo[1] != 'M') 
    { 
     hFile.close(); 
     throw std::invalid_argument("Error: Invalid File Format. Bitmap Required."); 
    } 

    if (FileInfo[28] != 24 && FileInfo[28] != 32) 
    { 
     hFile.close(); 
     throw std::invalid_argument("Error: Invalid File Format. 24 or 32 bit Image Required."); 
    } 

    BitsPerPixel = FileInfo[28]; 
    width = FileInfo[18] + (FileInfo[19] << 8); 
    height = FileInfo[22] + (FileInfo[23] << 8); 
    std::uint32_t PixelsOffset = FileInfo[10] + (FileInfo[11] << 8); 
    std::uint32_t size = ((width * BitsPerPixel + 31)/32) * 4 * height; 
    Pixels.resize(size); 

    hFile.seekg (PixelsOffset, std::ios::beg); 
    hFile.read(reinterpret_cast<char*>(Pixels.data()), size); 
    hFile.close(); 
} 

int main() 
{ 
    BMP info = BMP("C:/Users/....../Desktop/SomeBmp.bmp"); 

    GLuint texture = 0; 
    glGenTextures(1, &texture); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexImage2D(GL_TEXTURE_2D, 0, info.HasAlphaChannel() ? GL_RGBA : GL_RGB, info.GetWidth(), info.GetWidth(), 0, info.HasAlphaChannel() ? GL_BGRA : GL_BGR, GL_UNSIGNED_BYTE, info.GetPixels().data()); 
} 

TGA का उपयोग लोड कर सकते हैं:

#include <vector> 
#include <fstream> 

#ifdef __APPLE__ 
#include <OpenGL/gl.h> 
#include <OpenGL/glu.h> 
#endif 


#ifdef _WIN32 
#include <GL/gl.h> 
#include <GL/glu.h> 
#endif 

typedef union PixelInfo 
{ 
    std::uint32_t Colour; 
    struct 
    { 
     std::uint8_t R, G, B, A; 
    }; 
} *PPixelInfo; 

class Tga 
{ 
private: 
    std::vector<std::uint8_t> Pixels; 
    bool ImageCompressed; 
    std::uint32_t width, height, size, BitsPerPixel; 

public: 
    Tga(const char* FilePath); 
    std::vector<std::uint8_t> GetPixels() {return this->Pixels;} 
    std::uint32_t GetWidth() const {return this->width;} 
    std::uint32_t GetHeight() const {return this->height;} 
    bool HasAlphaChannel() {return BitsPerPixel == 32;} 
}; 

Tga::Tga(const char* FilePath) 
{ 
    std::fstream hFile(FilePath, std::ios::in | std::ios::binary); 
    if (!hFile.is_open()){throw std::invalid_argument("File Not Found.");} 

    std::uint8_t Header[18] = {0}; 
    std::vector<std::uint8_t> ImageData; 
    static std::uint8_t DeCompressed[12] = {0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; 
    static std::uint8_t IsCompressed[12] = {0x0, 0x0, 0xA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; 

    hFile.read(reinterpret_cast<char*>(&Header), sizeof(Header)); 

    if (!std::memcmp(DeCompressed, &Header, sizeof(DeCompressed))) 
    { 
     BitsPerPixel = Header[16]; 
     width = Header[13] * 256 + Header[12]; 
     height = Header[15] * 256 + Header[14]; 
     size = ((width * BitsPerPixel + 31)/32) * 4 * height; 

     if ((BitsPerPixel != 24) && (BitsPerPixel != 32)) 
     { 
      hFile.close(); 
      throw std::invalid_argument("Invalid File Format. Required: 24 or 32 Bit Image."); 
     } 

     ImageData.resize(size); 
     ImageCompressed = false; 
     hFile.read(reinterpret_cast<char*>(ImageData.data()), size); 
    } 
    else if (!std::memcmp(IsCompressed, &Header, sizeof(IsCompressed))) 
    { 
     BitsPerPixel = Header[16]; 
     width = Header[13] * 256 + Header[12]; 
     height = Header[15] * 256 + Header[14]; 
     size = ((width * BitsPerPixel + 31)/32) * 4 * height; 

     if ((BitsPerPixel != 24) && (BitsPerPixel != 32)) 
     { 
      hFile.close(); 
      throw std::invalid_argument("Invalid File Format. Required: 24 or 32 Bit Image."); 
     } 

     PixelInfo Pixel = {0}; 
     int CurrentByte = 0; 
     std::size_t CurrentPixel = 0; 
     ImageCompressed = true; 
     std::uint8_t ChunkHeader = {0}; 
     int BytesPerPixel = (BitsPerPixel/8); 
     ImageData.resize(width * height * sizeof(PixelInfo)); 

     do 
     { 
      hFile.read(reinterpret_cast<char*>(&ChunkHeader), sizeof(ChunkHeader)); 

      if(ChunkHeader < 128) 
      { 
       ++ChunkHeader; 
       for(int I = 0; I < ChunkHeader; ++I, ++CurrentPixel) 
       { 
        hFile.read(reinterpret_cast<char*>(&Pixel), BytesPerPixel); 

        ImageData[CurrentByte++] = Pixel.B; 
        ImageData[CurrentByte++] = Pixel.G; 
        ImageData[CurrentByte++] = Pixel.R; 
        if (BitsPerPixel > 24) ImageData[CurrentByte++] = Pixel.A; 
       } 
      } 
      else 
      { 
       ChunkHeader -= 127; 
       hFile.read(reinterpret_cast<char*>(&Pixel), BytesPerPixel); 

       for(int I = 0; I < ChunkHeader; ++I, ++CurrentPixel) 
       { 
        ImageData[CurrentByte++] = Pixel.B; 
        ImageData[CurrentByte++] = Pixel.G; 
        ImageData[CurrentByte++] = Pixel.R; 
        if (BitsPerPixel > 24) ImageData[CurrentByte++] = Pixel.A; 
       } 
      } 
     } while(CurrentPixel < (width * height)); 
    } 
    else 
    { 
     hFile.close(); 
     throw std::invalid_argument("Invalid File Format. Required: 24 or 32 Bit TGA File."); 
    } 

    hFile.close(); 
    this->Pixels = ImageData; 
} 


int main() 
{ 
    Tga info = Tga("C:/Users/...../Desktop/SomeTGA.tga"); 

    GLuint texture = 0; 
    glGenTextures(1, &texture); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexImage2D(GL_TEXTURE_2D, 0, info.HasAlphaChannel() ? GL_RGBA : GL_RGB, info.GetWidth(), info.GetWidth(), 0, info.HasAlphaChannel() ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, info.GetPixels().data()); 

} 
+0

आपके कोड के लिए धन्यवाद, लेकिन आरजीबी का अर्थ आरजीबी पिक्सेल = {0} में क्या है; क्या आप आरजीबीए संरचना का मतलब था? क्या आप अधिक कक्षा की सहायता के लिए पूरी कक्षा फाइल को गिटुप में प्रदान कर सकते हैं? – wangdq

+0

@wangdq फिक्स्ड। हेडर भी जोड़ा गया। – Brandon

+0

टीजीए एक चौड़ाई और ऊंचाई के लिए बंद है।इसे 256 से 255 (0xFF) चौड़ाई = शीर्षलेख [13] * 256 + शीर्षलेख [12] से गुणा करना चाहिए; ऊंचाई = शीर्षलेख [15] * 256 + शीर्षलेख [14]; – GambitSunob

6

मैंने इस प्रश्न का अर्थ इस प्रकार बताया: "मैं एक टीजीए फाइल कैसे लोड करूं? मैंने जो कोशिश की वह काम नहीं कर सका।"

99% सही समय उत्तर नहीं दिया जा रहा है "इस कार्य को कॉपी और पेस्ट करें जो मैंने लिखा था टीजीए फाइलों को लोड करता है"। यह दृष्टिकोण है कि स्वीकृत उत्तर ले रहा है। लेकिन अगर आप ऐसा समाधान चाहते हैं जो न केवल काम करता है, लेकिन अधिक रखरखाव योग्य होगा और इसमें बग होने पर अधिक निश्चित होने की संभावना है, तो लाइब्रेरी का उपयोग करना बेहतर है। अपना खुद का समाधान रोल करना सीखने का एक अच्छा तरीका है और प्रोत्साहित किया जाना चाहिए, लेकिन यह आमतौर पर कुछ करने का सबसे अच्छा या आसान तरीका नहीं है।

उन्हें पढ़ने के लिए अपना स्वयं का फ़ंक्शन रोल करने की बजाय वास्तविक छवि लाइब्रेरी का उपयोग करें। डेटा प्रारूप पर आपकी धारणाएं सही नहीं हैं, इसलिए जो डेटा आप प्राप्त कर रहे हैं वह बंक है। आप मानते हैं कि डेटा एक 128x128 पिक्सेल कच्चा है।

http://tgalib.sourceforge.net/ टीजीए फ़ाइलों को पढ़ने के लिए एक ओपन सोर्स लाइब्रेरी है। उदाहरण के लिए इसका इस्तेमाल करें।

https://github.com/nothings/stb एक अधिक उदार (सार्वजनिक डोमेन) लाइसेंस TGA फ़ाइलें लोड के अलावा अन्य चीजें हैं जो ओपन कार्यक्रमों के लिए काम में आते हैं की एक बहुत कुछ है कि के साथ एक और विकल्प नहीं है।

दोनों पुस्तकालय आपको ऑनलाइन मिले कॉपी-पेस्टिंग कोड की तुलना में बेहतर विकल्प हैं।