2016-04-04 2 views
0

J'essaie simplement de charger une image 2D avec openGL et de l'assigner à un carré. J'ai regardé beaucoup de quatre en ligne et ai essayé beaucoup de manières différentes de faire ceci, ai essayé charger beaucoup de différents dossiers à charger mais chaque tentative obtient une erreur différente. Je préférerais ne pas utiliser une bibliothèque externe.Chargement d'un BMP et mappage à Square avec OpenGL C++

Les charges d'image incorrecte:

program output

image essayant de charger:

source image

#include <SFML/Graphics.hpp> 
#include <SFML/OpenGL.hpp> 
#include <math.h> 
#include <string> 
#include <fstream> 
#include <sstream> 
#include <vector> 
#include <iostream> 
#include <stdint.h> 

using namespace std; 

#define size 200 
#define other 100 

int main() 
{ 
    GLuint _vertexBufferID; 

    GLfloat objects[] = { 
     other,other,0.0f, 
     size, other,0.0f, 
     size,size,0.0f, 
     other,size,0.0f 
    }; 
    GLfloat texture[] = { 
     0.0f,0.0f, 
     1.0f,0.0f, 
     1.0f,1.0f, 
     0.0f,1.0f 
    }; 

    sf::Window window(sf::VideoMode(1000, 800, 32), "SFML OpenGL");//!<  Create the main window 

    glEnable(GL_DEPTH_TEST);//!< Enable Z-buffer read and write 
    glDepthMask(GL_TRUE); 

    glClearColor(1.0f,1.0f,1.0f,1.0f); 
    glViewport(0.0f,0.0f,1000,800); 

    glMatrixMode(GL_PROJECTION); 
    gluOrtho2D(0,1000,0,800); 
    glMatrixMode(GL_MODELVIEW); 

    glEnable(GL_TEXTURE_2D); 

    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

    glVertexPointer(3,GL_FLOAT,0,objects); 
    glTexCoordPointer(2, GL_FLOAT, 0, texture); 

    unsigned char* datBuff[2] = {nullptr, nullptr}; // Header buffers 

    unsigned char* pixels = nullptr; // Pixels 

    BITMAPFILEHEADER* bmpHeader = nullptr; // Header 
    BITMAPINFOHEADER* bmpInfo = nullptr; // Info 

    // The file... We open it with it's constructor 
    std::ifstream file("other.bmp", std::ios::binary); 

    // Allocate byte memory that will hold the two headers 
    datBuff[0] = new unsigned char[sizeof(BITMAPFILEHEADER)]; 
    datBuff[1] = new unsigned char[sizeof(BITMAPINFOHEADER)]; 

    file.read((char*)datBuff[0], sizeof(BITMAPFILEHEADER)); 
    file.read((char*)datBuff[1], sizeof(BITMAPINFOHEADER)); 

    // Construct the values from the buffers 
    bmpHeader = (BITMAPFILEHEADER*) datBuff[0]; 
    bmpInfo = (BITMAPINFOHEADER*) datBuff[1]; 

    // First allocate pixel memory 
    pixels = new unsigned char[bmpInfo->biSizeImage]; 

    // Go to where image data starts, then read in image data 
    file.seekg(bmpHeader->bfOffBits); 
    file.read((char*)pixels, bmpInfo->biSizeImage); 

    unsigned char tmpRGB = 0; // Swap buffer 
    for (unsigned long i = 0; i < bmpInfo->biSizeImage; i += 3) 
    { 
     tmpRGB  = pixels[i]; 
     pixels[i]  = pixels[i + 2]; 
     pixels[i + 2] = tmpRGB; 
    } 

    GLuint textureBuf; 
    glGenTextures(1, &textureBuf);    // Generate a texture 
    glBindTexture(GL_TEXTURE_2D, textureBuf); // Bind that texture temporarily 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bmpInfo->biWidth, bmpInfo->biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels); 

    while (window.isOpen())//!< Start game loop 
    { 

     sf::Event Event;//!< Process events 
     while (window.pollEvent(Event)) 
     { } 

     window.setActive(); 

     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//!< Clear colour and depth buffer 
     glClear(GL_COLOR_BUFFER_BIT); 

     glDrawArrays(GL_QUADS,0,4);//sizeof(vertexData)); 

     window.display(); 
    } 

    return EXIT_SUCCESS; 
} 
+0

Bien que le format de fichier BMP soit relativement simple, vous ne devriez toujours pas essayer de le charger vous-même. Il existe de nombreuses bibliothèques qui peuvent charger de nombreux types de formats d'image, certaines grandes bibliothèques, certaines petites et minces, essayent d'en trouver une à la place parce qu'à long terme cela vous facilitera la vie. –

+0

Meilleure estimation: 'BITMAPFILEHEADER' et/ou' BITMAPINFOHEADER' ne sont pas bien emballés, le compilateur ayant inséré un peu de remplissage. Un fichier binaire lu dans une structure produit un résultat indéfini car les structures ne doivent pas forcément être compactées (ainsi, le compilateur aligne généralement les membres pour un accès plus rapide ou plus facile). Pouvez-vous montrer leur définition et donner une indication de la plate-forme cible? – Tommy

Répondre

0

Pour donner suite à mon estimation de commentaires, et en supposant que vous ne pouvez pas seulement utilisez un chargeur BMP standard pour quelque raison que ce soit, essayez de remplacer votre tentative actuelle de chargement des en-têtes complets par:

uint32_t data_offset; 
file.seekg(10); 
file.read((char *)&data_offset, 4); 

uint32_t image_width, image_height; 
file.seekg(18); 
file.read((char *)&image_width, 4); 
file.read((char *)&image_height, 4); 

uint32_t image_size; 
file.seekg(34); 
file.read((char *)&image_size, 4); 

file.seekg(data_offset); 
file.read((char*)pixels, image_size); 

Couplé avec le reste de votre code, cela suppose encore, entre autres péchés:

  • la machine que vous utilisez sur est peu endian; Le BMP est une image BGR 24 bits non compressée (par échange d'octets plus tard);
  • l'en-tête d'informations est celui qui est ou est une extension de BITMAPINFOHEADER.

... mais si elle résout le problème immédiat alors que confirmerait que la question est simplement une fausse hypothèse sur la façon dont votre compilateur mise en page struct s en mémoire.