Add renderer stuff
This commit is contained in:
@@ -137,10 +137,22 @@ SOURCE=.\render\renderdevice.cpp
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\render\rendertarget.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\filesystem\stream.cpp
|
SOURCE=.\filesystem\stream.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin 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
|
SOURCE=.\render\vertexbuffer.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
@@ -193,10 +205,22 @@ SOURCE=.\render\renderdevice.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\render\rendertarget.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\filesystem\stream.h
|
SOURCE=.\filesystem\stream.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin 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
|
SOURCE=.\render\vertexbuffer.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# 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));
|
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)
|
uint GetGLBlendFactor(BlendFactor factor)
|
||||||
{
|
{
|
||||||
switch (factor)
|
switch (factor)
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ void GL_CheckError();
|
|||||||
void GL_CheckErrorEx(const char* filename, int line);
|
void GL_CheckErrorEx(const char* filename, int line);
|
||||||
void GL_CheckErrorFunction(const char* expression, 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() \
|
#define GL_CHECK_ERROR() \
|
||||||
GL_CheckErrorEx(__FILE__, __LINE__)
|
GL_CheckErrorEx(__FILE__, __LINE__)
|
||||||
|
|
||||||
@@ -20,6 +22,9 @@ void GL_CheckErrorFunction(const char* expression, const char* filename, int lin
|
|||||||
expr; \
|
expr; \
|
||||||
GL_CheckErrorFunction(#expr, __FILE__, __LINE__)
|
GL_CheckErrorFunction(#expr, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
// OpenGL 1.3 Functional
|
||||||
|
|
||||||
|
|
||||||
// OpenGL 1.5 Functional
|
// OpenGL 1.5 Functional
|
||||||
extern PFNGLGENQUERIESPROC glGenQueries;
|
extern PFNGLGENQUERIESPROC glGenQueries;
|
||||||
extern PFNGLDELETEQUERIESPROC glDeleteQueries;
|
extern PFNGLDELETEQUERIESPROC glDeleteQueries;
|
||||||
|
|||||||
@@ -57,6 +57,24 @@ enum PrimitiveType
|
|||||||
PT_TRIANGLES
|
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)
|
// Base structure for render view (view and projection matrices, viewport settings)
|
||||||
struct View
|
struct View
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,11 +136,11 @@ void RenderDevice::SetReadRenderTarget(RenderTarget* renderTarget)
|
|||||||
if (renderTarget) {
|
if (renderTarget) {
|
||||||
if (m_activeReadRT != renderTarget) {
|
if (m_activeReadRT != renderTarget) {
|
||||||
m_activeReadRT = renderTarget;
|
m_activeReadRT = renderTarget;
|
||||||
//glBindFramebuffer(GL_READ_FRAMEBUFFER, renderTarget->m_framebuffer);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, renderTarget->m_framebuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // set default rt
|
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 (renderTarget) {
|
||||||
if (m_activeWriteRT != renderTarget) {
|
if (m_activeWriteRT != renderTarget) {
|
||||||
m_activeWriteRT = renderTarget;
|
m_activeWriteRT = renderTarget;
|
||||||
//glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderTarget->m_framebuffer);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderTarget->m_framebuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // set default rt
|
else { // set default rt
|
||||||
//glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
#include "render/texturesmanager.h"
|
#include "render/texturesmanager.h"
|
||||||
#include "render/texture2d.h"
|
#include "render/texture2d.h"
|
||||||
|
|
||||||
#include "glad/glad.h"
|
|
||||||
|
|
||||||
void RenderTarget::setDefaultFramebuffer()
|
void RenderTarget::setDefaultFramebuffer()
|
||||||
{
|
{
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
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