Add renderer stuff
This commit is contained in:
@@ -137,10 +137,22 @@ SOURCE=.\render\renderdevice.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\render\rendertarget.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\filesystem\stream.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\render\texture2d.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\render\texturesmanager.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\render\vertexbuffer.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
@@ -193,10 +205,22 @@ SOURCE=.\render\renderdevice.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\render\rendertarget.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\filesystem\stream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\render\texture2d.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\render\texturesmanager.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\render\vertexbuffer.h
|
||||
# End Source File
|
||||
# End Group
|
||||
|
||||
@@ -44,6 +44,10 @@ void GL_CheckErrorFunction(const char* expression, const char* filename, int lin
|
||||
Msg( "OpenGL Error: %s (%s) at %s:%i", expression, GL_ErrorString( err ), filename, line );// Msg("OpenGL Error: %s [%s]\n", GL_ErrorString(err), GL_TargetToString(tex->target));
|
||||
}
|
||||
|
||||
void GL_SetTexture( int slot, uint texture )
|
||||
{
|
||||
}
|
||||
|
||||
uint GetGLBlendFactor(BlendFactor factor)
|
||||
{
|
||||
switch (factor)
|
||||
|
||||
@@ -13,6 +13,8 @@ void GL_CheckError();
|
||||
void GL_CheckErrorEx(const char* filename, int line);
|
||||
void GL_CheckErrorFunction(const char* expression, const char* filename, int line);
|
||||
|
||||
void GL_SetTexture( int slot, uint texture );
|
||||
|
||||
#define GL_CHECK_ERROR() \
|
||||
GL_CheckErrorEx(__FILE__, __LINE__)
|
||||
|
||||
@@ -20,6 +22,9 @@ void GL_CheckErrorFunction(const char* expression, const char* filename, int lin
|
||||
expr; \
|
||||
GL_CheckErrorFunction(#expr, __FILE__, __LINE__)
|
||||
|
||||
// OpenGL 1.3 Functional
|
||||
|
||||
|
||||
// OpenGL 1.5 Functional
|
||||
extern PFNGLGENQUERIESPROC glGenQueries;
|
||||
extern PFNGLDELETEQUERIESPROC glDeleteQueries;
|
||||
|
||||
@@ -57,6 +57,24 @@ enum PrimitiveType
|
||||
PT_TRIANGLES
|
||||
};
|
||||
|
||||
enum TextureWrap
|
||||
{
|
||||
TW_REPEAT,
|
||||
TW_MIRROREDREPEAT,
|
||||
TW_CLAMPTOEDGE,
|
||||
TW_CLAMPTOBORDER
|
||||
};
|
||||
|
||||
enum TextureFilter
|
||||
{
|
||||
TF_NEAREST,
|
||||
TF_LINEAR,
|
||||
TF_NEARESTMIPMAPNEAREST,
|
||||
TF_LINEARMIPMAPNEAREST,
|
||||
TF_NEARESTMIPMAPLINEAR,
|
||||
TF_LINEARMIPMAPLINEAR
|
||||
};
|
||||
|
||||
// Base structure for render view (view and projection matrices, viewport settings)
|
||||
struct View
|
||||
{
|
||||
|
||||
@@ -136,11 +136,11 @@ void RenderDevice::SetReadRenderTarget(RenderTarget* renderTarget)
|
||||
if (renderTarget) {
|
||||
if (m_activeReadRT != renderTarget) {
|
||||
m_activeReadRT = renderTarget;
|
||||
//glBindFramebuffer(GL_READ_FRAMEBUFFER, renderTarget->m_framebuffer);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, renderTarget->m_framebuffer);
|
||||
}
|
||||
}
|
||||
else { // set default rt
|
||||
// glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,11 +149,11 @@ void RenderDevice::SetWriteRenderTarget(RenderTarget* renderTarget)
|
||||
if (renderTarget) {
|
||||
if (m_activeWriteRT != renderTarget) {
|
||||
m_activeWriteRT = renderTarget;
|
||||
//glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderTarget->m_framebuffer);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderTarget->m_framebuffer);
|
||||
}
|
||||
}
|
||||
else { // set default rt
|
||||
//glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "render/texturesmanager.h"
|
||||
#include "render/texture2d.h"
|
||||
|
||||
#include "glad/glad.h"
|
||||
|
||||
void RenderTarget::setDefaultFramebuffer()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
255
engine/render/texture2d.cpp
Normal file
255
engine/render/texture2d.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
#include <assert.h>
|
||||
#include "render/texture2d.h"
|
||||
#include "render/texturesmanager.h"
|
||||
#include "render/gl_shared.h"
|
||||
|
||||
GLint GetGlWrap(TextureWrap wrap);
|
||||
GLint GetGlTexFilter(TextureFilter filter);
|
||||
|
||||
Texture2D* Texture2D::Create()
|
||||
{
|
||||
return new Texture2D;
|
||||
}
|
||||
|
||||
Texture2D::Texture2D()
|
||||
{
|
||||
m_pf = PF_UNKNOWN;
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
m_channels = 0;
|
||||
m_handle = -1;
|
||||
}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
{
|
||||
m_pf = PF_UNKNOWN;
|
||||
m_width = 0;
|
||||
m_height = 0;
|
||||
m_channels = 0;
|
||||
m_handle = -1;
|
||||
}
|
||||
|
||||
void Texture2D::CreateBlackTexture(int width, int height, int channels)
|
||||
{
|
||||
size_t textureSize = width * height * channels;
|
||||
byte* data = new byte[textureSize];
|
||||
assert(data);
|
||||
|
||||
for (int i = 0; i < (int)textureSize; i++) {
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
CreateFromExistedData(data, width, height, channels);
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void Texture2D::CreateWhiteTexture(int width, int height, int channels)
|
||||
{
|
||||
size_t textureSize = width * height * channels;
|
||||
byte* data = new byte[textureSize];
|
||||
assert(data);
|
||||
|
||||
for (int i = 0; i < (int)textureSize; i++) {
|
||||
data[i] = 255;
|
||||
}
|
||||
|
||||
CreateFromExistedData(data, width, height, channels);
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void Texture2D::CreateGrayTexture(int width, int height, int channels)
|
||||
{
|
||||
size_t textureSize = width * height * channels;
|
||||
byte* data = new byte[textureSize];
|
||||
assert(data);
|
||||
|
||||
for (int i = 0; i < (int)textureSize; i++) {
|
||||
data[i] = 255 / 2;
|
||||
}
|
||||
|
||||
CreateFromExistedData(data, width, height, channels);
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void Texture2D::CreateTexture_Generator(int width, int height, int channels, int color)
|
||||
{
|
||||
size_t textureSize = width * height * channels;
|
||||
byte* data = new byte[textureSize];
|
||||
assert(data);
|
||||
|
||||
m_textureFileName = "$generator_texture$";
|
||||
|
||||
for (int i = 0; i < (int)textureSize; i++) {
|
||||
data[i] = color;
|
||||
}
|
||||
|
||||
CreateFromExistedData(data, width, height, channels);
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void Texture2D::CreateFromExistedData(void* data, int width, int height, int channels)
|
||||
{
|
||||
//assert(data);
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_channels = channels;
|
||||
|
||||
glGenTextures(1, &m_handle);
|
||||
glBindTexture(GL_TEXTURE_2D, m_handle);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, (channels == 3) ? GL_RGB : GL_RGBA, width, height, 0, (channels == 3) ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void Texture2D::CreateRaw(void* data, int width, int height, PixelFormat pf)
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_channels = (pf == PF_R8G8B8) ? 3 : 4;
|
||||
m_pf = pf;
|
||||
|
||||
glGenTextures(1, &m_handle);
|
||||
glBindTexture(GL_TEXTURE_2D, m_handle);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, getGLInternalPF(pf), width, height, 0, getGLInternalPF(pf), GL_UNSIGNED_BYTE, data);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
|
||||
|
||||
void Texture2D::GenerateMipmaps()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, m_handle);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
//if (g_texAnisoFilter.getValueB()) {
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, g_texAnisoLevel.getValueI());
|
||||
//}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void Texture2D::Bind()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, m_handle);
|
||||
}
|
||||
|
||||
void Texture2D::SetWrapS(TextureWrap wrap)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getGlWrap(wrap));
|
||||
}
|
||||
|
||||
void Texture2D::SetWrapT(TextureWrap wrap)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getGlWrap(wrap));
|
||||
}
|
||||
|
||||
void Texture2D::SetMin(TextureFilter filter)
|
||||
{
|
||||
GLint param = 0;
|
||||
param = getGlTexFilter(filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, param);
|
||||
}
|
||||
|
||||
void Texture2D::SetMag(TextureFilter filter)
|
||||
{
|
||||
GLint param = 0;
|
||||
param = getGlTexFilter(filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, param);
|
||||
}
|
||||
|
||||
GLint GetGlWrap(TextureWrap wrap)
|
||||
{
|
||||
GLint param = 0;
|
||||
|
||||
if (wrap == TextureWrap::Repeat)
|
||||
param = GL_REPEAT;
|
||||
else if (wrap == TextureWrap::MirroredRepeat)
|
||||
param = GL_MIRRORED_REPEAT;
|
||||
else if (wrap == TextureWrap::ClampToEdge)
|
||||
param = GL_CLAMP_TO_EDGE;
|
||||
else if (wrap == TextureWrap::ClampToBorder)
|
||||
param = GL_CLAMP_TO_BORDER;
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
GLint GetGlTexFilter(TextureFilter filter)
|
||||
{
|
||||
GLint param = 0;
|
||||
|
||||
if (filter == TextureFilter::Linear)
|
||||
param = GL_LINEAR;
|
||||
else if (filter == TextureFilter::Nearest)
|
||||
param = GL_NEAREST;
|
||||
else if (filter == TextureFilter::LinearMipmapLinear)
|
||||
param = GL_LINEAR_MIPMAP_LINEAR;
|
||||
else if (filter == TextureFilter::LinearMipmapNearest)
|
||||
param = GL_LINEAR_MIPMAP_NEAREST;
|
||||
else if (filter == TextureFilter::NearestMipmapLinear)
|
||||
param = GL_NEAREST_MIPMAP_LINEAR;
|
||||
else if (filter == TextureFilter::NearestMipmapNearest)
|
||||
param = GL_NEAREST_MIPMAP_NEAREST;
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
uint getGLPF(PixelFormat pf)
|
||||
{
|
||||
return 0;
|
||||
//return uint32_t();
|
||||
}
|
||||
|
||||
// Kirill: Remove to render_main.cpp or something else
|
||||
uint getGLInternalPF(PixelFormat pf)
|
||||
{
|
||||
switch (pf)
|
||||
{
|
||||
case PF_UNKNOWN:
|
||||
return 0;
|
||||
|
||||
case PF_R8G8B8:
|
||||
case PF_R8G8B8F:
|
||||
return GL_RGB;
|
||||
|
||||
case PF_R8G8B8A8:
|
||||
case PF_R8G8B8A8F:
|
||||
return GL_RGBA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint getGLTypePF(PixelFormat pf)
|
||||
{
|
||||
switch (pf)
|
||||
{
|
||||
case PF_UNKNOWN:
|
||||
return 0;
|
||||
|
||||
case PF_R8G8B8:
|
||||
case PF_R8G8B8A8:
|
||||
return GL_UNSIGNED_BYTE;
|
||||
|
||||
case PF_R8G8B8F:
|
||||
case PF_R8G8B8A8F:
|
||||
return GL_FLOAT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
49
engine/render/texture2d.h
Normal file
49
engine/render/texture2d.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef TEXTURE2D_H
|
||||
#define TEXTURE2D_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "render/render_shared.h"
|
||||
|
||||
class TexturesManager;
|
||||
|
||||
class Texture2D
|
||||
{
|
||||
friend class TexturesManager;
|
||||
public:
|
||||
static Texture2D* Create();
|
||||
|
||||
public:
|
||||
Texture2D();
|
||||
~Texture2D();
|
||||
|
||||
void CreateBlackTexture(int width, int height, int channels);
|
||||
void CreateWhiteTexture(int width, int height, int channels);
|
||||
void CreateGrayTexture(int width, int height, int channels);
|
||||
void CreateTexture_Generator(int width, int height, int channels, int color);
|
||||
void CreateFromExistedData(void* data, int width, int height, int channels);
|
||||
void CreateFromFile(const char* filename);
|
||||
|
||||
void CreateRaw(void* data, int width, int height, PixelFormat pf);
|
||||
|
||||
void GenerateMipmaps();
|
||||
|
||||
void Bind();
|
||||
|
||||
void SetWrapS(TextureWrap wrap);
|
||||
void SetWrapT(TextureWrap wrap);
|
||||
void SetMin(TextureFilter filter);
|
||||
void SetMag(TextureFilter filter);
|
||||
|
||||
uint GetHandle() { return m_handle; }
|
||||
|
||||
private:
|
||||
std::string m_textureFileName;
|
||||
PixelFormat m_pf;
|
||||
int m_width;
|
||||
int m_height;
|
||||
int m_channels;
|
||||
uint m_handle;
|
||||
};
|
||||
|
||||
#endif // !TEXTURE2D_H
|
||||
192
engine/render/texturesmanager.cpp
Normal file
192
engine/render/texturesmanager.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
#include "utils/logger.h"
|
||||
#include "filesystem/filemanager.h"
|
||||
#include "render/texture2d.h"
|
||||
#include "render/texturesmanager.h"
|
||||
#include "render/gl_shared.h"
|
||||
|
||||
// STB Image loading code
|
||||
void Texture2D::CreateFromFile(const char* filename)
|
||||
{
|
||||
/*
|
||||
int width, height, channels;
|
||||
m_textureFileName = filename;
|
||||
|
||||
File* file = g_fileManager->OpenFile(filename, FileAccess::Read);
|
||||
|
||||
file->seek(SeekDir::End, 0);
|
||||
size_t imageSize = file->tell();
|
||||
file->seek(SeekDir::Begin, 0);
|
||||
|
||||
uint8_t* fileData = (uint8_t*)malloc(imageSize);
|
||||
file->read(fileData, imageSize);
|
||||
|
||||
g_fileManager->CloseFile(file);
|
||||
|
||||
uint8_t* imageData = stbi_load_from_memory(fileData, int(imageSize), &width, &height, &channels, 0);
|
||||
|
||||
if (imageData == NULL) {
|
||||
free(fileData);
|
||||
Msg("Texture loading error: %s (%s)", filename, stbi_failure_reason());
|
||||
assert(imageData);
|
||||
}
|
||||
|
||||
CreateFromExistedData(imageData, width, height, channels);
|
||||
m_textureFileName = filename;
|
||||
|
||||
free(fileData);
|
||||
|
||||
stbi_image_free(imageData);
|
||||
*/
|
||||
}
|
||||
|
||||
static const char* g_texFileExtensions[] = { ".png", ".jpeg", ".jpg", ".tga", ".bmp" };
|
||||
const int kTexFileExtensionsSize = sizeof(g_texFileExtensions) / sizeof(g_texFileExtensions[0]);
|
||||
|
||||
TexturesManager* g_texturesManager = NULL;
|
||||
|
||||
TexturesManager::TexturesManager()
|
||||
{
|
||||
m_notex = NULL;
|
||||
}
|
||||
|
||||
TexturesManager::~TexturesManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TexturesManager::Init()
|
||||
{
|
||||
//stbi_set_flip_vertically_on_load(true);
|
||||
|
||||
m_notex = LoadTexture2D("content/textures/system/notex.png", true);
|
||||
if (!m_notex) {
|
||||
Logger::Error("TexturesManager::Init: Failed to initialize system texture! 'system/notex.png' is not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
void TexturesManager::Shutdown()
|
||||
{
|
||||
if (!m_textures.empty()) {
|
||||
Msg("--- unfreed textures ---");
|
||||
|
||||
for (std::vector<Texture2D*>::iterator it = m_textures.begin(); it != m_textures.end(); ++it) {
|
||||
Msg("%s", (*it)->m_textureFileName.c_str());
|
||||
delete* it;
|
||||
*it = NULL;
|
||||
}
|
||||
|
||||
m_textures.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void TexturesManager::SetTexture(int slot, Texture2D* texture)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, texture ? texture->GetHandle() : 0);
|
||||
}
|
||||
|
||||
Texture2D* TexturesManager::CreateManual2D(const char* name, int width, int height, PixelFormat format, bool useAsRenderTarget)
|
||||
{
|
||||
for (std::vector<Texture2D*>::iterator it = m_textures.begin(); it != m_textures.end(); ++it) {
|
||||
if ((*it)->m_textureFileName == name) {
|
||||
Logger::Error("TexturesManager::CreateManual2D: texture %s is already created!", name);
|
||||
}
|
||||
}
|
||||
|
||||
// allocate
|
||||
Texture2D* texture = Texture2D::Create();
|
||||
texture->CreateRaw(nullptr, width, height, format);
|
||||
texture->m_textureFileName = name;
|
||||
|
||||
if (useAsRenderTarget)
|
||||
Msg("Created rt texture [%s]", name);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
bool IsSupportedExtension(const char* filename)
|
||||
{
|
||||
std::string ext = fs::getFileExtension(filename);
|
||||
|
||||
for (int i = 0; i < kTexFileExtensionsSize; i++) {
|
||||
if (ext == g_texFileExtensions[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Texture2D* TexturesManager::LoadTexture2D(const char* texturename, bool useMipmaps /*= false*/)
|
||||
{
|
||||
int texturesNbr = m_textures.size();
|
||||
for (int i = 0; i < texturesNbr; i++) {
|
||||
if (m_textures[i]->m_textureFileName == texturename)
|
||||
return m_textures[i];
|
||||
}
|
||||
|
||||
if (strcmp(texturename, "$white$") == 0) {
|
||||
Texture2D* tex = Texture2D::Create();
|
||||
tex->m_textureFileName = "$white$";
|
||||
tex->CreateWhiteTexture(16, 16, 3);
|
||||
m_textures.push_back(tex);
|
||||
return tex;
|
||||
}
|
||||
if (strcmp(texturename, "$black$") == 0) {
|
||||
Texture2D* tex = Texture2D::Create();
|
||||
tex->m_textureFileName = "$black$";
|
||||
tex->CreateBlackTexture(16, 16, 3);
|
||||
m_textures.push_back(tex);
|
||||
return tex;
|
||||
}
|
||||
if (strcmp(texturename, "$gray$") == 0) {
|
||||
Texture2D* tex = Texture2D::Create();
|
||||
tex->m_textureFileName = "$gray$";
|
||||
tex->CreateGrayTexture(16, 16, 3);
|
||||
m_textures.push_back(tex);
|
||||
return tex;
|
||||
}
|
||||
if (strcmp(texturename, "$gray_console$") == 0) {
|
||||
Texture2D* tex = Texture2D::Create();
|
||||
tex->CreateTexture_Generator(16, 16, 3, 32);
|
||||
m_textures.push_back(tex);
|
||||
return tex;
|
||||
}
|
||||
|
||||
if (strlen(texturename) <= 0) {
|
||||
return m_notex;
|
||||
}
|
||||
|
||||
std::string texnamebuf;
|
||||
|
||||
// find texture from disk
|
||||
for (int i = 0; i < kTexFileExtensionsSize; i++)
|
||||
{
|
||||
std::string textureFilename = fs::getFileNameWithoutExtension(texturename);
|
||||
textureFilename += g_texFileExtensions[i];
|
||||
|
||||
if (g_fileManager->FileExist(textureFilename.c_str()))
|
||||
{
|
||||
texnamebuf = textureFilename;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!texnamebuf.empty()) {
|
||||
Texture2D* texture = Texture2D::Create();
|
||||
texture->CreateFromFile(texnamebuf.c_str());
|
||||
|
||||
if (useMipmaps)
|
||||
texture->GenerateMipmaps();
|
||||
|
||||
Msg("loaded %s", fs::getFilenameWithoutPathAndExtension(texturename).c_str());
|
||||
m_textures.push_back(texture);
|
||||
return texture;
|
||||
}
|
||||
else if (texnamebuf.empty() && m_notex) {
|
||||
Msg("not found %s", fs::getFilenameWithoutPathAndExtension(texturename).c_str());
|
||||
return m_notex;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
38
engine/render/texturesmanager.h
Normal file
38
engine/render/texturesmanager.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef TEXTURESMANAGER_H
|
||||
#define TEXTURESMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "render/render_shared.h"
|
||||
|
||||
class Texture2D;
|
||||
|
||||
class TexturesManager
|
||||
{
|
||||
public:
|
||||
TexturesManager();
|
||||
~TexturesManager();
|
||||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
|
||||
void SetTexture(int slot, Texture2D* texture);
|
||||
|
||||
Texture2D* CreateManual2D(
|
||||
const char* name,
|
||||
int width,
|
||||
int height,
|
||||
PixelFormat format,
|
||||
bool useAsRenderTarget = false);
|
||||
|
||||
Texture2D* LoadTexture2D(const char* texturename, bool useMipmaps = false);
|
||||
|
||||
private:
|
||||
std::vector<Texture2D*> m_textures;
|
||||
|
||||
Texture2D* m_notex;
|
||||
};
|
||||
|
||||
extern TexturesManager* g_texturesManager;
|
||||
|
||||
#endif // !TEXTURESMANAGER_H
|
||||
141
engine/utils/rtti.h
Normal file
141
engine/utils/rtti.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
|
||||
The other day we tracked a bad bug where a base class was been cast to
|
||||
the wrong thing.
|
||||
The reason why it happed was because we didn't have any RTTI (Run Time
|
||||
Type Information) in place.
|
||||
We also didn't want to use the one that it comes with the compiler for
|
||||
fear that it will add "evil" code.
|
||||
So after hitting that bug I decided to do my on RTTI. I wanted to be
|
||||
simple and very fast.
|
||||
This is what we use now. It looks kind of neat so I thought to share it.
|
||||
Enjoy.
|
||||
|
||||
Tomas
|
||||
tarce@zen-x.net
|
||||
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
//==============================================================================
|
||||
// RTTI
|
||||
//==============================================================================
|
||||
// Using the RTTI
|
||||
//------------------------------------------------------------------------------
|
||||
// struct base
|
||||
// {
|
||||
// CREATE_RTTI_BASE( base );
|
||||
// };
|
||||
//
|
||||
// struct pepe : public base
|
||||
// {
|
||||
// CREATE_RTTI( pepe, base, base )
|
||||
// void Normal( void ){}
|
||||
// };
|
||||
//
|
||||
// struct super_pepe : public pepe
|
||||
// {
|
||||
// CREATE_RTTI( super_pepe, pepe, base )
|
||||
// void Super( void ){}
|
||||
// };
|
||||
//
|
||||
// void main( void )
|
||||
// {
|
||||
// super_pepe SP; // The original class
|
||||
// base& B = SP; // Some generic base reference
|
||||
//
|
||||
// // We want to safely convert to pepe
|
||||
// pepe& P = pepe::GetSaveType( B );
|
||||
//
|
||||
// // cast the base class right
|
||||
// if( B.IsKindOf( super_pepe::GetRTTI() ) )
|
||||
// {
|
||||
// super_pepe& SP = super_pepe::GetSaveType( B );
|
||||
// SP.Super();
|
||||
// }
|
||||
// else if( B.IsKindOf( pepe::GetRTTI() ) )
|
||||
// {
|
||||
// pepe& P = pepe::GetSaveType( B );
|
||||
// P.Normal();
|
||||
// }
|
||||
// }
|
||||
//==============================================================================
|
||||
#define CREATE_RTTI( TYPE, BASE_CLASS )
|
||||
#define CREATE_RTTI_BASE( TYPE )
|
||||
|
||||
struct RTTI
|
||||
{
|
||||
bool IsKindOf( const RTTI& RTTI ) const;
|
||||
RTTI ( const char* pTypeName );
|
||||
RTTI ( const char* pTypeName, const RTTI& RTTI );
|
||||
|
||||
const char* pType; // This is not really need it, just useful in debugger.
|
||||
const RTTI& Next;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// IMPLEMENTATION
|
||||
//==============================================================================
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4355 ) // warning 'this' used in base member initializer list
|
||||
#undef CREATE_RTTI
|
||||
#undef CREATE_RTTI_BASE
|
||||
|
||||
inline RTTI::RTTI( const char* pTypeName ) :
|
||||
pType(pTypeName), Next( *this ){}
|
||||
|
||||
inline RTTI::RTTI( const char* pTypeName, const RTTI& RTTI ) :
|
||||
pType(pTypeName), Next( RTTI ){}
|
||||
|
||||
inline bool RTTI::IsKindOf( const RTTI& RTTI ) const
|
||||
{
|
||||
const RTTI* p = this;
|
||||
do
|
||||
{
|
||||
if( p == &RTTI ) return true;
|
||||
if( p == &p->Next ) break;
|
||||
p = &p->Next;
|
||||
|
||||
} while(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
#define PRIVATE_RTTI_FUNCTION_SET( TYPE, BASE_CLASS ) \
|
||||
virtual inline const RTTI& GetObjectRTTI( void ) const \
|
||||
{ \
|
||||
return TYPE::GetRTTI(); \
|
||||
} \
|
||||
inline const bool IsKindOf( const RTTI& RTTI ) const \
|
||||
{ \
|
||||
return GetObjectRTTI().IsKindOf( RTTI ); \
|
||||
} \
|
||||
static inline TYPE& GetSaveType( BASE_CLASS& Object ) \
|
||||
{ \
|
||||
assert( Object.IsKindOf(TYPE::GetRTTI()) ); \
|
||||
return *((TYPE*)&Object); \
|
||||
} \
|
||||
static inline const TYPE& GetSaveType( const BASE_CLASS& Object ) \
|
||||
{ \
|
||||
assert( Object.IsKindOf(TYPE::GetRTTI()) ); \
|
||||
return *((const TYPE*)&Object); \
|
||||
}
|
||||
|
||||
#define CREATE_RTTI( TYPE, TYPE_PARENT, BASE_CLASS ) \
|
||||
static inline const RTTI& GetRTTI( void ) \
|
||||
{ \
|
||||
static RTTI s_RTTI( #TYPE, TYPE_PARENT::GetRTTI() ); \
|
||||
return s_RTTI; \
|
||||
} \
|
||||
PRIVATE_RTTI_FUNCTION_SET(TYPE,BASE_CLASS)
|
||||
|
||||
#define CREATE_RTTI_BASE( TYPE ) \
|
||||
static inline const RTTI& GetRTTI( void ) \
|
||||
{ \
|
||||
static RTTI s_RTTI( #TYPE ); \
|
||||
return s_RTTI; \
|
||||
} \
|
||||
PRIVATE_RTTI_FUNCTION_SET(TYPE,TYPE)
|
||||
|
||||
#pragma warning( pop )
|
||||
Reference in New Issue
Block a user