aboutsummaryrefslogtreecommitdiff
path: root/source/Texture.cpp
blob: 968c4bcc5ed59c8ec039f77bf0d851dc97dfb6e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "Texture.hpp"

#include "PodVector.hpp"

#include <stb_image.h>
#include <stb_rect_pack.h>
#include <cstdint>
#include <cstring>
#include <deque>
#include <filesystem>
#include <fstream>
#include <stdexcept>
#include <utility>

Texture::~Texture() {
	glDeleteTextures(1, &mHandle);
}

static GLenum MapTextureFilteringToGL(Texture::Filtering option) {
	switch (option) {
		case Texture::LinearFilter: return GL_LINEAR;
		case Texture::NearestFilter: return GL_NEAREST;
	}
	return 0;
}

bool Texture::InitFromFile(const char* filePath, const TextureProperties& props, bool flipVertically) {
	int width, height;
	int channels;

	stbi_set_flip_vertically_on_load(flipVertically);
	auto result = (uint8_t*)stbi_load(filePath, &width, &height, &channels, 4);
	if (!result) {
		return false;
	}

	glDeleteTextures(1, &mHandle); // In case the caller gave us
	glGenTextures(1, &mHandle);
	glBindTexture(GL_TEXTURE_2D, mHandle);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ::MapTextureFilteringToGL(props.minifyingFilter));
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ::MapTextureFilteringToGL(props.magnifyingFilter));
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, result);

	mInfo.size = { width, height };
	mInfo.isAtlas = false;
	return true;
}

// bool Texture::InitFromImage(const Image& image, const TextureProperties& props, bool flipVertically) {
// 	GLenum sourceFormat;
// 	switch (image.GetChannels()) {
// 		case 1: sourceFormat = GL_RED; break;
// 		case 2: sourceFormat = GL_RG; break;
// 		case 3: sourceFormat = GL_RGB; break;
// 		case 4: sourceFormat = GL_RGBA; break;
// 		default: return false;
// 	}

// 	auto size = image.GetSize();

// 	std::unique_ptr<uint8_t[]> dataStorage;
// 	uint8_t* dataPtr;
// 	if (flipVertically) {
// 		dataStorage = std::make_unique<uint8_t[]>(image.GetDataLength());
// 		dataPtr = dataStorage.get();

// 		size_t rowStride = size.width * image.GetChannels() * sizeof(uint8_t);
// 		for (size_t y = 0; y < size.height; ++y) {
// 			size_t invY = (size.height - 1) - y;
// 			std::memcpy(dataPtr + invY * rowStride, image.GetDataPtr() + y * rowStride, rowStride);
// 		}
// 	} else {
// 		// dataStorage is unused, we read pixels directly from `image`
// 		dataPtr = image.GetDataPtr();
// 	}

// 	glDeleteTextures(1, &mHandle);
// 	glGenTextures(1, &mHandle);
// 	glBindTexture(GL_TEXTURE_2D, mHandle);
// 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ::MapTextureFilteringToGL(props.minifyingFilter));
// 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ::MapTextureFilteringToGL(props.magnifyingFilter));
// 	glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, size.width, size.height, 0, sourceFormat, GL_UNSIGNED_BYTE, dataPtr);

// 	mInfo.size = size;
// 	mInfo.isAtlas = false;
// 	return true;
// }

const TextureInfo& Texture::GetInfo() const {
	return mInfo;
}

GLuint Texture::GetHandle() const {
	return mHandle;
}

bool Texture::IsValid() const {
	return mHandle != 0;
}