TGA and RGB image loading

This commit is contained in:
trotFunky 2019-09-25 00:36:57 +02:00
parent ff59df8e28
commit e83cdba55b
7 changed files with 169 additions and 3 deletions

View file

@ -11,7 +11,7 @@ if(NOT ${OPENGL_GLU_FOUND})
endif()
add_executable(tests_opengl
src/main.cpp src/displayers.h src/displayers.cpp)
src/main.cpp src/displayers.h src/displayers.cpp src/Texture.cpp src/Texture.h)
target_link_libraries(tests_opengl
${OPENGL_LIBRARIES}

BIN
resources/arbre.tga Normal file

Binary file not shown.

80
src/Texture.cpp Normal file
View file

@ -0,0 +1,80 @@
//
// Created by trotfunky on 24/09/2019.
//
#include "Texture.h"
Texture::Texture() : width(0), height(0), color_bits(0), image_data(nullptr), opengl_id{(uint32_t)-1}
{}
Texture::~Texture()
{
if (opengl_id[0] != (uint32_t)-1)
{
delete(image_data);
glDeleteTextures(1,opengl_id);
}
}
bool Texture::load_tga(const std::string& filename, uint8_t*& data_array)
{
std::fstream file_stream(filename,std::ios_base::in|std::ios_base::binary);
if (file_stream.fail())
{
std::cerr << "Error while opening " << filename << std::endl;
return false;
}
// Length of the image ID
uint8_t id_length = 0;
file_stream >> id_length;
file_stream.seekg(1,std::ios_base::cur);
uint8_t tga_data_type = 0;
file_stream >> tga_data_type;
// Only supported type : Raw RGB data
if (tga_data_type != 2)
{
std::cerr << "Error loading file " << filename << ": Unsupported format " << tga_data_type << std::endl;
file_stream.close();
return false;
}
// Place the cursor to the position of the width header data
file_stream.seekg(12,std::ios_base::beg);
file_stream.read((char*)&width,2);
file_stream.read((char*)&height,2);
file_stream >> color_bits;
if (color_bits != 24 && color_bits != 32)
{
std::cerr << "Error loading file " << filename << ": Unsupported " << color_bits << " bits colors" << std::endl;
file_stream.close();
return false;
}
// Move cursor to the end to get file size
file_stream.seekg(0,std::ios_base::end);
// Size of the file minus header length minus ID length
int data_length = width*height*(color_bits/8);
// Move cursor to the start of the data.
file_stream.seekg(18+id_length,std::ios_base::beg);
data_array = new uint8_t[data_length];
file_stream.read((char*)data_array,data_length);
return true;
}
bool Texture::load_rgb_tga(const std::string& rgb_filename)
{
return load_tga(rgb_filename,image_data);
}
bool Texture::load_rgba_tga(const std::string& rgb_filename,const std::string& mask_filename)
{
return false;
}

38
src/Texture.h Normal file
View file

@ -0,0 +1,38 @@
//
// Created by trotfunky on 24/09/2019.
//
#ifndef TESTS_OPENGL_TEXTURE_H
#define TESTS_OPENGL_TEXTURE_H
#include <GL/glut.h>
#include <string>
#include <fstream>
#include <iostream>
class Texture {
public:
uint16_t width;
uint16_t height;
/// Number of bits describing the colors : 24 (RGB) or 32 (RGBA)
uint8_t color_bits;
uint8_t* image_data;
uint32_t opengl_id[1];
Texture();
~Texture();
/// Load an RGBA image from an RGB TGA file
bool load_rgb_tga(const std::string& rgb_filename);
/// Load an RGBA image from an rgb and an alpha tga file
bool load_rgba_tga(const std::string& rgb_filename,const std::string& mask_filename);
private:
/// Load TGA image file to an array
bool load_tga(const std::string& filename, uint8_t*& data_array);
};
#endif //TESTS_OPENGL_TEXTURE_H

View file

@ -60,17 +60,39 @@ void display_rotating_pyramid(float x, float y, float z, float c, float h, float
glPopMatrix();
}
void display_tree(float x, float y, float z, float h, float w)
void display_tree(float x, float y, float z, float h, float w, const Texture& tree_texture)
{
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glBindTexture(GL_TEXTURE_2D,tree_texture.opengl_id[0]);
glColor4f(1.0f, 1.0f, 1.0f,1.00);
glBegin(GL_QUADS);
// First rectangle
glTexCoord2f(1,0);
glVertex3f(x+w/2,y,z);
glTexCoord2f(0,0);
glVertex3f(x-w/2,y,z);
glTexCoord2f(0,1);
glVertex3f(x-w/2,y+h,z);
glTexCoord2f(1,1);
glVertex3f(x+w/2,y+h,z);
// Second rectangle
glTexCoord2f(1,0);
glVertex3f(x,y,z+w/2);
glTexCoord2f(0,0);
glVertex3f(x,y,z-w/2);
glTexCoord2f(0,1);
glVertex3f(x,y+h,z-w/2);
glTexCoord2f(1,1);
glVertex3f(x,y+h,z+w/2);
glEnd();
}

View file

@ -7,6 +7,8 @@
#include <GL/glut.h>
#include "Texture.h"
/// Displays a square based pyramid from a base position, height and side length
/// \param x X coordinate of the center
/// \param y Y coordinate of the center
@ -19,6 +21,6 @@ void display_pyramid(float x, float y, float z, float c, float h);
void display_rotating_pyramid(float x, float y, float z, float c, float h, float alpha);
/// Draw a tree with two quadrilaterals
void display_tree(float x, float y, float z, float h, float w);
void display_tree(float x, float y, float z, float h, float w, const Texture& tree_texture);
#endif //TESTS_OPENGL_DISPLAYERS_H

View file

@ -1,8 +1,12 @@
#include "GL/glut.h"
#include "GL/gl.h"
#include "displayers.h"
#include "Texture.h"
volatile unsigned long long int timer_ticks = 0;
static Texture tree_texture;
void display()
{
@ -25,6 +29,8 @@ void display()
display_rotating_pyramid(5,-2,0,1,5,angleY);
display_rotating_pyramid(-2,-2,4,3,2,angleY);
display_tree(0,-5,0,3,5,tree_texture);
glutSwapBuffers();
}
@ -48,6 +54,24 @@ int main(int argc, char** argv)
// glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
// Setup OPenGL to use textures
glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5);
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_REPEAT/GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT/GL_CLAMP);
glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// Load and generate tree texture
tree_texture.load_rgb_tga("resources/arbre.tga");
glGenTextures(1,tree_texture.opengl_id);
glBindTexture(GL_TEXTURE_2D,tree_texture.opengl_id[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, tree_texture.width,tree_texture.height,0,GL_RGB,GL_UNSIGNED_BYTE,tree_texture.image_data);
gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGB8,tree_texture.width,tree_texture.height,GL_RGB,GL_UNSIGNED_BYTE,tree_texture.image_data);
glViewport(0,0,glutGet(GLUT_WINDOW_WIDTH),glutGet(GLUT_WINDOW_HEIGHT));
glutIdleFunc(display);