TGA and RGB image loading
This commit is contained in:
parent
ff59df8e28
commit
e83cdba55b
7 changed files with 169 additions and 3 deletions
|
@ -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
BIN
resources/arbre.tga
Normal file
Binary file not shown.
80
src/Texture.cpp
Normal file
80
src/Texture.cpp
Normal 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
38
src/Texture.h
Normal 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
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
24
src/main.cpp
24
src/main.cpp
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue