mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-13 03:32:28 +00:00
chore: initial commit
This commit is contained in:
commit
70b00c5c38
965 changed files with 264882 additions and 0 deletions
1312
src/gx/gll/CGxDeviceGLL.cpp
Normal file
1312
src/gx/gll/CGxDeviceGLL.cpp
Normal file
File diff suppressed because it is too large
Load diff
80
src/gx/gll/CGxDeviceGLL.hpp
Normal file
80
src/gx/gll/CGxDeviceGLL.hpp
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#ifndef GX_GLL_C_GX_DEVICE_GLL_HPP
|
||||
#define GX_GLL_C_GX_DEVICE_GLL_HPP
|
||||
|
||||
#include "gx/CGxDevice.hpp"
|
||||
#include "gx/gll/GLDevice.h"
|
||||
#include "gx/gll/GLWindow.h"
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
class CGxBatch;
|
||||
class CGxShader;
|
||||
|
||||
class CGxDeviceGLL : public CGxDevice {
|
||||
public:
|
||||
// Static variables
|
||||
static GLEnum s_glCubeMapFaces[];
|
||||
static GLEnum s_glDstBlend[];
|
||||
static GLEnum s_glSrcBlend[];
|
||||
static GLTextureFormat s_gxTexFmtToGLLFmt[];
|
||||
static GLEnum s_poolTarget2BufferFormat[];
|
||||
static GLEnum s_poolTarget2BufferType[];
|
||||
static GLEnum s_poolUsage2BufferUsage[];
|
||||
static GLEnum s_primitiveConversion[];
|
||||
|
||||
// Member variables
|
||||
GLDevice m_glDevice;
|
||||
GLWindow m_glWindow;
|
||||
GLVertexFormat m_glFormats[GxVertexBufferFormats_Last] = {};
|
||||
|
||||
// Virtual member functions
|
||||
virtual void ITexMarkAsUpdated(CGxTex*);
|
||||
virtual void IRsSendToHw(EGxRenderState);
|
||||
virtual int32_t DeviceCreate(long (*)(void*, uint32_t, uint32_t, long), const CGxFormat&);
|
||||
virtual int32_t DeviceSetFormat(const CGxFormat&);
|
||||
virtual void CapsWindowSize(CRect&);
|
||||
virtual void CapsWindowSizeInScreenCoords(CRect& dst);
|
||||
virtual void ScenePresent(void);
|
||||
virtual void SceneClear(uint32_t, CImVector);
|
||||
virtual void XformSetProjection(const C44Matrix&);
|
||||
virtual void XformSetView(const C44Matrix&);
|
||||
virtual void Draw(CGxBatch*, int32_t);
|
||||
virtual void PoolSizeSet(CGxPool*, uint32_t);
|
||||
virtual char* BufLock(CGxBuf*);
|
||||
virtual int32_t BufUnlock(CGxBuf*, uint32_t);
|
||||
virtual void TexDestroy(CGxTex* texId);
|
||||
virtual void IShaderCreate(CGxShader*);
|
||||
virtual void ShaderCreate(CGxShader*[], EGxShTarget, const char*, const char*, int32_t);
|
||||
virtual int32_t StereoEnabled(void);
|
||||
|
||||
// Member functions
|
||||
CGxDeviceGLL();
|
||||
char* IBufLock(CGxBuf*);
|
||||
int32_t IBufUnlock(CGxBuf*);
|
||||
void ISceneBegin();
|
||||
void ISetCaps(void);
|
||||
void IShaderBindPixel(CGxShader*);
|
||||
void IShaderBindVertex(CGxShader*);
|
||||
void IShaderConstantsFlush(void);
|
||||
void IShaderCreatePixel(CGxShader*);
|
||||
void IShaderCreateVertex(CGxShader*);
|
||||
void IStateSetGLLDefaults();
|
||||
void IStateSync(void);
|
||||
void IStateSyncEnables(void);
|
||||
void IStateSyncIndexPtr(void);
|
||||
void IStateSyncLights(void);
|
||||
void IStateSyncMaterial(void);
|
||||
void IStateSyncScissorRect(void);
|
||||
void IStateSyncVertexPtrs(void);
|
||||
void IStateSyncXforms(void);
|
||||
void ITexCreate(CGxTex*);
|
||||
void ITexSetFlags(CGxTex*);
|
||||
void ITexUpload(CGxTex*);
|
||||
void IXformSetProjection(const C44Matrix&);
|
||||
void IXformSetView(const C44Matrix&);
|
||||
void IXformSetViewport(void);
|
||||
void PatchPixelShader(CGxShader*);
|
||||
void PatchVertexShader(CGxShader*);
|
||||
void Resize(uint32_t width, uint32_t height);
|
||||
};
|
||||
|
||||
#endif
|
||||
50
src/gx/gll/GL.cpp
Normal file
50
src/gx/gll/GL.cpp
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#include "gx/gll/GL.h"
|
||||
|
||||
TextureFormatInfo k_TextureFormatInfo[GLTF_NUM_TEXTURE_FORMATS] = {
|
||||
{ 0, 0, 0, 0, 0, "GLTF INVALID!!" },
|
||||
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 4, "ARGB8888" },
|
||||
{ GL_RGB8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 4, "XRGB8888" },
|
||||
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 0, 4, "RGBA8888" },
|
||||
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 4, "ABGR8888" },
|
||||
{ GL_RGB8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0, 4, "ARGB0888" },
|
||||
{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, 0, 3, "RGB888" },
|
||||
{ GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE, 0, 3, "BGR888" },
|
||||
{ GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, 0, 16, "RGBA32F" },
|
||||
{ GL_RGBA16F_ARB, GL_RGBA, GL_HALF_FLOAT, 0, 8, "RGBA16F" },
|
||||
{ GL_RGB16F_ARB, GL_RGB, GL_HALF_FLOAT, 0, 6, "RG16F" },
|
||||
{ GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 4, "D32" },
|
||||
{ GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 4, "D24" },
|
||||
{ GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0, 2, "D16" },
|
||||
{ GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_HALF_FLOAT, 0, 4, "DF" },
|
||||
{ GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0, 4, "D24S8" },
|
||||
{ GL_ALPHA8, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, 0, 1, "S8" },
|
||||
{ GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 0, 2, "ARGB4444" },
|
||||
{ GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0, 2, "ARGB1555" },
|
||||
{ GL_RGB5, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0, 2, "ARGB0555" },
|
||||
{ GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0, 2, "RGB565" },
|
||||
{ GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 0, 4, "A2RGB10" },
|
||||
{ GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT, 0, 6, "RGB16" },
|
||||
{ GL_LUMINANCE8, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, 1, "L8" },
|
||||
{ GL_ALPHA8, GL_ALPHA, GL_UNSIGNED_BYTE, 0, 1, "A8" },
|
||||
{ GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0, 2, "A8L8" },
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, 1, 8, "DXT1" },
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, 1, 16, "DXT3" },
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, 1, 16, "DXT5" }
|
||||
};
|
||||
|
||||
VertexTypeInfo k_VertexTypeInfo[GLVT_NUM_VERTEX_TYPES] = {
|
||||
{ 0, 0, 0, 0, "INVALID" },
|
||||
{ GL_FLOAT, 1, 0, 4, "FLOAT1" },
|
||||
{ GL_FLOAT, 2, 0, 8, "FLOAT2" },
|
||||
{ GL_FLOAT, 3, 0, 12, "FLOAT3" },
|
||||
{ GL_FLOAT, 4, 0, 16, "FLOAT4" },
|
||||
{ GL_UNSIGNED_BYTE, 4, 0, 4, "UBYTE4" },
|
||||
{ GL_UNSIGNED_BYTE, 4, 1, 4, "UBYTE4N" },
|
||||
{ GL_SHORT, 1, 0, 2, "SHORT" },
|
||||
{ GL_SHORT, 2, 0, 4, "SHORT2" },
|
||||
{ GL_SHORT, 4, 0, 8, "SHORT4" },
|
||||
{ GL_SHORT, 2, 1, 4, "SHORT2N" },
|
||||
{ GL_SHORT, 4, 1, 8, "SHORT4N" },
|
||||
{ GL_UNSIGNED_SHORT, 2, 1, 4, "USHORT2N" },
|
||||
{ GL_UNSIGNED_SHORT, 4, 1, 8, "USHORT4N" }
|
||||
};
|
||||
31
src/gx/gll/GL.h
Normal file
31
src/gx/gll/GL.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef GX_GLL_GL_H
|
||||
#define GX_GLL_GL_H
|
||||
|
||||
#include "gx/gll/GLTypes.h"
|
||||
#include <OpenGL/gl.h>
|
||||
|
||||
typedef GLenum GLEnum;
|
||||
|
||||
#define kMAX_VERTEX_ATTRIBS 16
|
||||
|
||||
struct TextureFormatInfo {
|
||||
GLenum m_InternalFormat;
|
||||
GLenum m_DataFormat;
|
||||
GLenum m_DataType;
|
||||
int32_t m_IsCompressed;
|
||||
int32_t m_BytePerPixel;
|
||||
char m_Name[16];
|
||||
};
|
||||
|
||||
struct VertexTypeInfo {
|
||||
GLenum m_Type;
|
||||
GLint m_Size;
|
||||
GLboolean m_Normalized;
|
||||
GLint m_ByteSize;
|
||||
const char* m_Name;
|
||||
};
|
||||
|
||||
extern TextureFormatInfo k_TextureFormatInfo[GLTF_NUM_TEXTURE_FORMATS];
|
||||
extern VertexTypeInfo k_VertexTypeInfo[GLVT_NUM_VERTEX_TYPES];
|
||||
|
||||
#endif
|
||||
19
src/gx/gll/GLAbstractWindow.cpp
Normal file
19
src/gx/gll/GLAbstractWindow.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "gx/gll/GLAbstractWindow.h"
|
||||
#include <cmath>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
int32_t GLAbstractWindow::GetBackingWidth() {
|
||||
return static_cast<int32_t>(std::floor(this->GetBackingRect().size.width));
|
||||
}
|
||||
|
||||
int32_t GLAbstractWindow::GetBackingHeight() {
|
||||
return static_cast<int32_t>(std::floor(this->GetBackingRect().size.height));
|
||||
}
|
||||
|
||||
int32_t GLAbstractWindow::GetWidth() {
|
||||
return static_cast<int32_t>(std::floor(this->GetRect().size.width));
|
||||
}
|
||||
|
||||
int32_t GLAbstractWindow::GetHeight() {
|
||||
return static_cast<int32_t>(std::floor(this->GetRect().size.height));
|
||||
}
|
||||
36
src/gx/gll/GLAbstractWindow.h
Normal file
36
src/gx/gll/GLAbstractWindow.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef GX_GLL_GL_ABSTRACT_WINDOW_H
|
||||
#define GX_GLL_GL_ABSTRACT_WINDOW_H
|
||||
|
||||
#ifdef __OBJC__
|
||||
#include <AppKit/AppKit.h>
|
||||
#else
|
||||
#include <objc/runtime.h>
|
||||
typedef struct objc_object NSWindow;
|
||||
typedef struct objc_object NSView;
|
||||
#endif
|
||||
|
||||
struct CGRect;
|
||||
class GLContext;
|
||||
|
||||
class GLAbstractWindow {
|
||||
public:
|
||||
// Virtual member functions
|
||||
virtual int32_t GetWidth(void);
|
||||
virtual int32_t GetHeight(void);
|
||||
virtual CGRect GetRect(void) = 0;
|
||||
virtual void Show(void) = 0;
|
||||
virtual void Resize(uint32_t, uint32_t) = 0;
|
||||
virtual void SetTitle(const char*) = 0;
|
||||
virtual void CreateView(void) = 0;
|
||||
virtual void SetOpenGLContext(GLContext*) = 0;
|
||||
// virtual NSWindow* GetNSWindow(void) = 0;
|
||||
virtual NSView* GetNSView(void) = 0;
|
||||
virtual bool CanEnterFullscreenMode(void) = 0;
|
||||
// virtual void EnterFullscreenMode(uint32_t, bool) = 0;
|
||||
virtual void ExitFullscreenMode(void) = 0;
|
||||
virtual CGRect GetBackingRect() = 0;
|
||||
virtual int32_t GetBackingWidth();
|
||||
virtual int32_t GetBackingHeight();
|
||||
};
|
||||
|
||||
#endif
|
||||
45
src/gx/gll/GLBatch.h
Normal file
45
src/gx/gll/GLBatch.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef GX_GLL_GL_BATCH_H
|
||||
#define GX_GLL_GL_BATCH_H
|
||||
|
||||
#include "gx/gll/GLBuffer.h"
|
||||
#include "gx/gll/GLShader.h"
|
||||
#include "gx/gll/GLTexture.h"
|
||||
#include "gx/gll/GLTypes.h"
|
||||
#include "gx/gll/GLVertexFormat.h"
|
||||
#include <cstdint>
|
||||
|
||||
class GLBatch {
|
||||
public:
|
||||
GLShader* var0;
|
||||
GLShader* var1;
|
||||
GLTexture* textures[16];
|
||||
GLBuffer* var3;
|
||||
GLBuffer* var4[4];
|
||||
uint32_t var5[4];
|
||||
uint32_t var6[4];
|
||||
GLVertexFormat* var7;
|
||||
uint32_t var8;
|
||||
uint32_t var9;
|
||||
uint32_t var10;
|
||||
uint32_t var11;
|
||||
uint32_t var12;
|
||||
uint32_t var13;
|
||||
uint32_t var14;
|
||||
int32_t var15;
|
||||
bool var16;
|
||||
bool var17;
|
||||
GLStates var18;
|
||||
GLTexture2D* colorBuffer[4];
|
||||
GLTexture2D* var20;
|
||||
uint32_t var21[128];
|
||||
char var22[64];
|
||||
char var23[1024];
|
||||
uint32_t var24;
|
||||
bool var25;
|
||||
int64_t var26;
|
||||
int64_t var27;
|
||||
float var28[4096];
|
||||
float var29[1024];
|
||||
};
|
||||
|
||||
#endif
|
||||
128
src/gx/gll/GLBuffer.cpp
Normal file
128
src/gx/gll/GLBuffer.cpp
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#include "gx/gll/GLBuffer.h"
|
||||
#include "gx/gll/GLDevice.h"
|
||||
#include "gx/gll/GLPool.h"
|
||||
#include "util/BlizzardCore.hpp"
|
||||
|
||||
bool GLBuffer::m_UsingVBO = 1;
|
||||
|
||||
GLEnum GLBuffer::s_FlagToAccess[] = {
|
||||
GL_READ_WRITE, // GLMap_None
|
||||
GL_WRITE_ONLY, // GLMap_Unk1
|
||||
GL_WRITE_ONLY, // GLMap_Unk2
|
||||
GL_READ_ONLY // GLMap_Unk3
|
||||
};
|
||||
|
||||
GLBuffer* GLBuffer::Create(GLEnum type, uint32_t size, const void* a3, GLEnum usage, GLEnum format) {
|
||||
GLBuffer* buffer = GLPool<GLBuffer>::Get()->GetNextObject();
|
||||
|
||||
buffer->m_Type = type;
|
||||
buffer->m_Size = size;
|
||||
buffer->m_Usage = usage;
|
||||
buffer->m_IndexFormat = format;
|
||||
|
||||
GLDevice* device = GLDevice::Get();
|
||||
device->BindBuffer(buffer, GL_ZERO);
|
||||
|
||||
if (GLBuffer::m_UsingVBO) {
|
||||
glBufferData(buffer->m_Type, buffer->m_Size, a3, buffer->m_Usage);
|
||||
glBufferParameteriAPPLE(buffer->m_Type, GL_BUFFER_SERIALIZED_MODIFY_APPLE, buffer->m_Usage - GL_DYNAMIC_DRAW > 1);
|
||||
glBufferParameteriAPPLE(buffer->m_Type, GL_BUFFER_FLUSHING_UNMAP_APPLE, 0);
|
||||
} else {
|
||||
Blizzard::Memory::Free(buffer->m_Data);
|
||||
|
||||
void* data = Blizzard::Memory::Allocate(size);
|
||||
if (a3) {
|
||||
memcpy(data, a3, size);
|
||||
}
|
||||
|
||||
buffer->m_Data = reinterpret_cast<char*>(data);
|
||||
}
|
||||
|
||||
// TODO
|
||||
// buffer->m_TimeStamp = Blizzard::Time::GetTimestamp();
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
GLBuffer::GLBuffer() : GLObject() {
|
||||
if (GLBuffer::m_UsingVBO) {
|
||||
this->m_BufferID = GLPool<GLBuffer>::Get()->GetNextName();
|
||||
}
|
||||
}
|
||||
|
||||
char* GLBuffer::Map(uint32_t offset, uint32_t size, eMapFlag flag) {
|
||||
BLIZZARD_ASSERT((offset + size) <= this->m_Size);
|
||||
BLIZZARD_ASSERT(this->m_Usage == GL_STATIC_DRAW || flag != GLMap_None);
|
||||
BLIZZARD_ASSERT(this->m_MapFlag == GLMap_NotMapped);
|
||||
BLIZZARD_ASSERT(flag >= GLMap_None && flag < GLMap_Count);
|
||||
|
||||
this->m_MapOffset = offset;
|
||||
this->m_MapSize = offset + size == 0 ? this->m_Size : size;
|
||||
this->m_MapFlag = flag;
|
||||
|
||||
if (GLBuffer::m_UsingVBO) {
|
||||
GLDevice* device = GLDevice::Get();
|
||||
device->BindBuffer(this, GL_ZERO);
|
||||
|
||||
if (flag == GLMap_Unk2) {
|
||||
if (this->m_Usage - GL_DYNAMIC_DRAW <= 1) {
|
||||
BLIZZARD_ASSERT(offset == 0);
|
||||
}
|
||||
|
||||
glBufferData(this->m_Type, this->m_Size, nullptr, this->m_Usage);
|
||||
}
|
||||
|
||||
void* data = glMapBuffer(this->m_Type, GLBuffer::s_FlagToAccess[flag]);
|
||||
this->m_Data = reinterpret_cast<char*>(data);
|
||||
|
||||
BLIZZARD_ASSERT(this->m_Data != nullptr);
|
||||
}
|
||||
|
||||
return this->m_Data + offset;
|
||||
}
|
||||
|
||||
void GLBuffer::ReleaseObject() {
|
||||
if (GLBuffer::m_UsingVBO) {
|
||||
if (this->m_Type) {
|
||||
GLDevice* device = GLDevice::Get();
|
||||
device->BindBuffer(this, GL_ZERO);
|
||||
|
||||
glBufferData(this->m_Type, 1, nullptr, this->m_Usage);
|
||||
|
||||
// TODO GLPool<GLBuffer>::GLObjectPool::Push((GLPool<GLBuffer>::m_pool + 32776), this);
|
||||
} else {
|
||||
// TODO GLPool<GLBuffer>::GLObjectPool::Push((GLPool<GLBuffer>::m_pool + 32776), this);
|
||||
}
|
||||
} else {
|
||||
Blizzard::Memory::Free(this->m_Data);
|
||||
this->m_Data = nullptr;
|
||||
|
||||
// TODO GLPool<GLBuffer>::GLObjectPool::Push((GLPool<GLBuffer>::m_pool + 32776), this);
|
||||
}
|
||||
}
|
||||
|
||||
void GLBuffer::Unmap(uint32_t size) {
|
||||
BLIZZARD_ASSERT((this->m_MapOffset + size) <= m_Size);
|
||||
|
||||
GLDevice* device = GLDevice::Get();
|
||||
device->BindBuffer(this, GL_ZERO);
|
||||
|
||||
if (this->m_MapFlag != 3) {
|
||||
if (GLBuffer::m_UsingVBO) {
|
||||
glFlushMappedBufferRangeAPPLE(this->m_Type, this->m_MapOffset, size ? size : this->m_MapSize);
|
||||
}
|
||||
|
||||
// TODO
|
||||
// this->m_TimeStamp = Blizzard::Time::GetTimestamp();
|
||||
}
|
||||
|
||||
if (!GLBuffer::m_UsingVBO) {
|
||||
this->m_MapFlag = GLMap_NotMapped;
|
||||
return;
|
||||
}
|
||||
|
||||
GLboolean result = glUnmapBuffer(this->m_Type);
|
||||
BLIZZARD_ASSERT(result);
|
||||
|
||||
this->m_MapFlag = GLMap_NotMapped;
|
||||
}
|
||||
47
src/gx/gll/GLBuffer.h
Normal file
47
src/gx/gll/GLBuffer.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef GX_GLL_GL_BUFFER_H
|
||||
#define GX_GLL_GL_BUFFER_H
|
||||
|
||||
#include "gx/gll/GL.h"
|
||||
#include "gx/gll/GLObject.h"
|
||||
#include "gx/gll/GLTypes.h"
|
||||
|
||||
class GLBuffer : public GLObject {
|
||||
public:
|
||||
// Types
|
||||
enum eMapFlag {
|
||||
GLMap_NotMapped = -1,
|
||||
GLMap_None = 0,
|
||||
GLMap_Unk1 = 1,
|
||||
GLMap_Unk2 = 2,
|
||||
GLMap_Unk3 = 3,
|
||||
GLMap_Count = 4
|
||||
};
|
||||
|
||||
// Static variables
|
||||
static bool m_UsingVBO;
|
||||
static GLEnum s_FlagToAccess[];
|
||||
|
||||
// Static functions
|
||||
static GLBuffer* Create(GLEnum, uint32_t, const void*, GLEnum, GLEnum);
|
||||
|
||||
// Member variables
|
||||
uint32_t m_Size = 0;
|
||||
GLEnum m_Type = 0;
|
||||
GLEnum m_Usage = 0;
|
||||
uint32_t m_BufferID = 0;
|
||||
GLEnum m_IndexFormat = 0;
|
||||
char* m_Data = nullptr;
|
||||
uint32_t m_MapOffset = 0;
|
||||
uint32_t m_MapSize = 0;
|
||||
uint32_t m_MapFlag = GLMap_NotMapped;
|
||||
|
||||
// Virtual member functions
|
||||
virtual void ReleaseObject();
|
||||
|
||||
// Member functions
|
||||
GLBuffer();
|
||||
char* Map(uint32_t, uint32_t, eMapFlag);
|
||||
void Unmap(uint32_t);
|
||||
};
|
||||
|
||||
#endif
|
||||
8
src/gx/gll/GLBufferPool.h
Normal file
8
src/gx/gll/GLBufferPool.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef GX_GLL_GL_BUFFER_POOL_H
|
||||
#define GX_GLL_GL_BUFFER_POOL_H
|
||||
|
||||
class GLBufferPool {
|
||||
public:
|
||||
};
|
||||
|
||||
#endif
|
||||
24
src/gx/gll/GLCommand.cpp
Normal file
24
src/gx/gll/GLCommand.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include "gx/gll/GLCommand.h"
|
||||
#include "gx/gll/GLTexture.h"
|
||||
|
||||
void GLFlush::Execute(GLDevice* device) {
|
||||
glFlush();
|
||||
}
|
||||
|
||||
GLTexUnmap::GLTexUnmap(GLTexture* texture, GLMipmap* mipmap, GLMipmap::MapParams* mapParams) {
|
||||
this->m_Texture = texture;
|
||||
this->m_Mipmap = mipmap;
|
||||
this->m_MapParams = mapParams;
|
||||
}
|
||||
|
||||
void GLTexUnmap::Execute(GLDevice* device) {
|
||||
this->m_Mipmap->Unmap(this->m_MapParams);
|
||||
}
|
||||
|
||||
GLTexDestroy::GLTexDestroy(GLTexture* texture) {
|
||||
this->m_Texture = texture;
|
||||
}
|
||||
|
||||
void GLTexDestroy::Execute(GLDevice* device) {
|
||||
this->m_Texture->FreeTexture();
|
||||
}
|
||||
46
src/gx/gll/GLCommand.h
Normal file
46
src/gx/gll/GLCommand.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef GX_GLL_GL_COMMAND_H
|
||||
#define GX_GLL_GL_COMMAND_H
|
||||
|
||||
#include "gx/gll/GLMipmap.h"
|
||||
|
||||
class GLDevice;
|
||||
|
||||
class GLCommand {
|
||||
public:
|
||||
// Virtual member functions
|
||||
virtual void Execute(GLDevice*) = 0;
|
||||
};
|
||||
|
||||
class GLFlush : public GLCommand {
|
||||
public:
|
||||
// Virtual member functions
|
||||
virtual void Execute(GLDevice* device);
|
||||
};
|
||||
|
||||
class GLTexUnmap : public GLCommand {
|
||||
public:
|
||||
// Member variables
|
||||
GLTexture* m_Texture;
|
||||
GLMipmap* m_Mipmap;
|
||||
GLMipmap::MapParams* m_MapParams;
|
||||
|
||||
// Virtual member functions
|
||||
virtual void Execute(GLDevice*);
|
||||
|
||||
// Member functions
|
||||
GLTexUnmap(GLTexture*, GLMipmap*, GLMipmap::MapParams*);
|
||||
};
|
||||
|
||||
class GLTexDestroy : public GLCommand {
|
||||
public:
|
||||
// Member variables
|
||||
GLTexture* m_Texture;
|
||||
|
||||
// Virtual member functions
|
||||
virtual void Execute(GLDevice* device);
|
||||
|
||||
// Member functions
|
||||
GLTexDestroy(GLTexture* texture);
|
||||
};
|
||||
|
||||
#endif
|
||||
96
src/gx/gll/GLContext.h
Normal file
96
src/gx/gll/GLContext.h
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
#ifndef GX_GLL_GL_CONTEXT_H
|
||||
#define GX_GLL_GL_CONTEXT_H
|
||||
|
||||
#include "gx/gll/GLAbstractWindow.h"
|
||||
#include "gx/gll/GLTypes.h"
|
||||
#include "util/BlizzardCore.hpp"
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#ifdef __OBJC__
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#else
|
||||
typedef struct objc_object NSOpenGLContext;
|
||||
typedef struct objc_object NSOpenGLPixelFormat;
|
||||
#endif
|
||||
|
||||
class GLDevice;
|
||||
|
||||
class GLContext {
|
||||
public:
|
||||
// Types
|
||||
struct Context {
|
||||
NSOpenGLContext* context;
|
||||
NSOpenGLPixelFormat* pixelFormat;
|
||||
int32_t sampleCount;
|
||||
|
||||
~Context();
|
||||
};
|
||||
|
||||
struct GammaFormula {
|
||||
float m_RedMin;
|
||||
float m_RedMax;
|
||||
float m_RedGamma;
|
||||
float m_GreenMin;
|
||||
float m_GreenMax;
|
||||
float m_GreenGamma;
|
||||
float m_BlueMin;
|
||||
float m_BlueMax;
|
||||
float m_BlueGamma;
|
||||
};
|
||||
|
||||
// Static variables
|
||||
static NSOpenGLContext* s_MainContext;
|
||||
static Blizzard::Thread::TLSSlot s_CurrentContext;
|
||||
static Blizzard::Thread::TLSSlot s_CurrentGLContext;
|
||||
static CFDictionaryRef s_DesktopMode;
|
||||
|
||||
// Static functions
|
||||
static NSOpenGLContext* GetNSOpenGLCurrentContext(void);
|
||||
static NSOpenGLContext* GetCurrentContext(void);
|
||||
static void SetCurrentContext(NSOpenGLContext*);
|
||||
static GLContext* GetCurrentGLContext(void);
|
||||
static void SetCurrentGLContext(GLContext*);
|
||||
|
||||
// Member variables
|
||||
std::basic_string<char, std::char_traits<char>, std::allocator<char>> m_DebugName;
|
||||
std::map<uint32_t, GLContext::Context, std::less<uint32_t>, std::allocator<std::pair<const uint32_t, GLContext::Context>>> m_Contexts;
|
||||
Context* m_Context;
|
||||
GLDevice* m_Device;
|
||||
GLAbstractWindow* m_Window;
|
||||
bool m_Windowed;
|
||||
bool m_MTGLEnabled;
|
||||
bool m_VSyncEnabled;
|
||||
bool m_CaptureDisplay;
|
||||
uint32_t m_Width;
|
||||
uint32_t m_Height;
|
||||
uint32_t m_RefreshRate;
|
||||
GammaFormula m_GammaFormula;
|
||||
bool m_GammaTablesSet;
|
||||
std::vector<uint16_t, std::allocator<uint16_t>> m_GammaTableR;
|
||||
std::vector<uint16_t, std::allocator<uint16_t>> m_GammaTableG;
|
||||
std::vector<uint16_t, std::allocator<uint16_t>> m_GammaTableB;
|
||||
std::vector<uint16_t, std::allocator<uint16_t>> m_OsGammaTableR;
|
||||
std::vector<uint16_t, std::allocator<uint16_t>> m_OsGammaTableG;
|
||||
std::vector<uint16_t, std::allocator<uint16_t>> m_OsGammaTableB;
|
||||
|
||||
// Member functions
|
||||
GLContext(GLDevice*, const char*);
|
||||
int32_t GetBackingWidth();
|
||||
int32_t GetBackingHeight();
|
||||
int32_t GetWidth(void);
|
||||
int32_t GetHeight(void);
|
||||
bool IsCurrentContext(void);
|
||||
void MakeCurrent(bool);
|
||||
void SetContextFormat(GLTextureFormat, uint32_t);
|
||||
void SetFullscreenMode(uint32_t, uint32_t, uint32_t, bool);
|
||||
void SetWindow(GLAbstractWindow*, bool);
|
||||
void Swap(void);
|
||||
void Update(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
389
src/gx/gll/GLContext.mm
Normal file
389
src/gx/gll/GLContext.mm
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
#include "gx/gll/GLContext.h"
|
||||
#include "gx/gll/GLDevice.h"
|
||||
#include "util/Autorelease.hpp"
|
||||
|
||||
NSOpenGLContext* GLContext::s_MainContext;
|
||||
Blizzard::Thread::TLSSlot GLContext::s_CurrentContext;
|
||||
Blizzard::Thread::TLSSlot GLContext::s_CurrentGLContext;
|
||||
CFDictionaryRef GLContext::s_DesktopMode;
|
||||
|
||||
void* Sub2A1E0(void* ptr) {
|
||||
NSOpenGLContext** ptrptr = new NSOpenGLContext*;
|
||||
*ptrptr = nullptr;
|
||||
return ptrptr;
|
||||
}
|
||||
|
||||
void Sub2A200(void* ptr) {
|
||||
delete static_cast<NSOpenGLContext**>(ptr);
|
||||
}
|
||||
|
||||
void* Sub720A0(void* ptr) {
|
||||
GLContext** ptrptr = new GLContext*;
|
||||
*ptrptr = nullptr;
|
||||
return ptrptr;
|
||||
}
|
||||
|
||||
void Sub720C0(void* ptr) {
|
||||
delete static_cast<GLContext**>(ptr);
|
||||
}
|
||||
|
||||
GLContext::Context::~Context() {
|
||||
if (this->context) {
|
||||
glFlush();
|
||||
|
||||
[this->context clearDrawable];
|
||||
|
||||
if (GLContext::GetCurrentContext() == context) {
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
GLContext::SetCurrentContext(nullptr);
|
||||
}
|
||||
|
||||
[this->context release];
|
||||
}
|
||||
|
||||
[this->pixelFormat release];
|
||||
}
|
||||
|
||||
NSOpenGLContext* GLContext::GetNSOpenGLCurrentContext() {
|
||||
return [NSOpenGLContext currentContext];
|
||||
}
|
||||
|
||||
NSOpenGLContext* GLContext::GetCurrentContext() {
|
||||
return *static_cast<NSOpenGLContext**>(
|
||||
Blizzard::Thread::RegisterLocalStorage(&GLContext::s_CurrentContext, Sub2A1E0, 0, Sub2A200)
|
||||
);
|
||||
}
|
||||
|
||||
void GLContext::SetCurrentContext(NSOpenGLContext* context) {
|
||||
*static_cast<NSOpenGLContext**>(
|
||||
Blizzard::Thread::RegisterLocalStorage(&GLContext::s_CurrentContext, Sub2A1E0, 0, Sub2A200)
|
||||
) = context;
|
||||
}
|
||||
|
||||
GLContext* GLContext::GetCurrentGLContext() {
|
||||
return *static_cast<GLContext**>(
|
||||
Blizzard::Thread::RegisterLocalStorage(&GLContext::s_CurrentGLContext, Sub720A0, 0, Sub720C0)
|
||||
);
|
||||
}
|
||||
|
||||
void GLContext::SetCurrentGLContext(GLContext* context) {
|
||||
*static_cast<GLContext**>(
|
||||
Blizzard::Thread::RegisterLocalStorage(&GLContext::s_CurrentGLContext, Sub720A0, 0, Sub720C0)
|
||||
) = context;
|
||||
}
|
||||
|
||||
GLContext::GLContext(GLDevice* a2, const char* a3) {
|
||||
this->m_Context = nullptr;
|
||||
this->m_Window = nullptr;
|
||||
this->m_Windowed = false;
|
||||
this->m_MTGLEnabled = false;
|
||||
this->m_Device = a2;
|
||||
this->m_Width = 0;
|
||||
this->m_Height = 0;
|
||||
this->m_RefreshRate = 0;
|
||||
}
|
||||
|
||||
int32_t GLContext::GetBackingWidth() {
|
||||
if (this->m_Windowed) {
|
||||
return this->m_Window->GetBackingWidth();
|
||||
} else {
|
||||
return this->m_Width;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t GLContext::GetBackingHeight() {
|
||||
if (this->m_Windowed) {
|
||||
return this->m_Window->GetBackingHeight();
|
||||
} else {
|
||||
return this->m_Height;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t GLContext::GetWidth() {
|
||||
if (this->m_Windowed) {
|
||||
return this->m_Window->GetWidth();
|
||||
} else {
|
||||
return this->m_Width;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t GLContext::GetHeight() {
|
||||
if (this->m_Windowed) {
|
||||
return this->m_Window->GetHeight();
|
||||
} else {
|
||||
return this->m_Height;
|
||||
}
|
||||
}
|
||||
|
||||
bool GLContext::IsCurrentContext() {
|
||||
return GLContext::GetCurrentGLContext() == this;
|
||||
}
|
||||
|
||||
void GLContext::MakeCurrent(bool a2) {
|
||||
BLIZZARD_ASSERT(this->m_Context->context != nullptr);
|
||||
|
||||
if (a2) {
|
||||
NSOpenGLContext* v6 = GLContext::GetNSOpenGLCurrentContext();
|
||||
GLContext::SetCurrentContext(v6);
|
||||
}
|
||||
|
||||
if (this->m_Context->context != GLContext::GetCurrentContext()) {
|
||||
int32_t mtglEnabled = 0;
|
||||
|
||||
if (GLContext::GetCurrentContext()) {
|
||||
mtglEnabled = this->m_MTGLEnabled;
|
||||
|
||||
// TODO
|
||||
// this->ToggleMTGL(0);
|
||||
// GLOcclusionQuery::DeleteAllQueries();
|
||||
// GLFence::DeleteAllFences();
|
||||
|
||||
glFlush();
|
||||
}
|
||||
|
||||
[this->m_Context->context makeCurrentContext];
|
||||
|
||||
GLContext::SetCurrentContext(this->m_Context->context);
|
||||
GLContext::SetCurrentGLContext(this);
|
||||
|
||||
// TODO
|
||||
// GLOcclusionQuery::RecreateAllQueries();
|
||||
// GLFence::RecreateAllFences();
|
||||
// this->ToggleMTGL(mtglEnabled);
|
||||
|
||||
GLDevice* device = GLDevice::Get();
|
||||
|
||||
if (device && this->m_Contexts.size() > 1) {
|
||||
device->ApplyGLStates(device->m_States, 1);
|
||||
device->ApplyGLBindings(device->m_States, 1);
|
||||
device->m_DefaultVertexArrayObject.ApplyGLStates(device->m_DefaultVertexArrayObject.m_GLStates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLContext::SetContextFormat(GLTextureFormat a2, uint32_t sampleCount) {
|
||||
System_Autorelease::ScopedPool autorelease;
|
||||
|
||||
uint32_t v61 = sampleCount | (a2 << 8);
|
||||
|
||||
if (this->m_Contexts.find(v61) != this->m_Contexts.end()) {
|
||||
this->m_Context = &this->m_Contexts[v61];
|
||||
|
||||
if (this->m_Window) {
|
||||
this->m_Window->SetOpenGLContext(this);
|
||||
}
|
||||
} else {
|
||||
auto& context = this->m_Contexts[v61];
|
||||
|
||||
CGDirectDisplayID v6 = CGMainDisplayID();
|
||||
|
||||
NSOpenGLPixelFormatAttribute formatAttributes[] = {
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFANoRecovery,
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFADepthSize, 0,
|
||||
NSOpenGLPFAStencilSize, 0,
|
||||
NSOpenGLPFAColorSize, 32,
|
||||
NSOpenGLPFAWindow,
|
||||
NSOpenGLPFAFullScreen,
|
||||
NSOpenGLPFAScreenMask, CGDisplayIDToOpenGLDisplayMask(v6),
|
||||
0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
switch (a2) {
|
||||
case GLTF_INVALID:
|
||||
break;
|
||||
|
||||
case GLTF_D32:
|
||||
formatAttributes[4] = 32;
|
||||
break;
|
||||
|
||||
case GLTF_D24:
|
||||
formatAttributes[4] = 24;
|
||||
break;
|
||||
|
||||
case GLTF_D16:
|
||||
formatAttributes[4] = 16;
|
||||
break;
|
||||
|
||||
case GLTF_D24S8:
|
||||
formatAttributes[4] = 24;
|
||||
formatAttributes[6] = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
BLIZZARD_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (sampleCount > 1) {
|
||||
BLIZZARD_ASSERT(sampleCount % 2 == 0);
|
||||
BLIZZARD_ASSERT(formatAttributes[13] == 0);
|
||||
BLIZZARD_ASSERT(formatAttributes[14] == 0);
|
||||
BLIZZARD_ASSERT(formatAttributes[15] == 0);
|
||||
BLIZZARD_ASSERT(formatAttributes[16] == 0);
|
||||
BLIZZARD_ASSERT(formatAttributes[17] == 0);
|
||||
|
||||
formatAttributes[13] = NSOpenGLPFASampleBuffers;
|
||||
formatAttributes[14] = 1;
|
||||
formatAttributes[15] = NSOpenGLPFASamples;
|
||||
formatAttributes[16] = sampleCount;
|
||||
}
|
||||
|
||||
context.sampleCount = sampleCount;
|
||||
|
||||
context.pixelFormat = [[NSOpenGLPixelFormat alloc]
|
||||
initWithAttributes: formatAttributes
|
||||
];
|
||||
|
||||
BLIZZARD_ASSERT(context.pixelFormat != nullptr);
|
||||
|
||||
context.context = [[NSOpenGLContext alloc]
|
||||
initWithFormat: context.pixelFormat
|
||||
shareContext: GLContext::s_MainContext
|
||||
];
|
||||
|
||||
BLIZZARD_ASSERT(context.context != nullptr);
|
||||
|
||||
this->m_Context = &context;
|
||||
|
||||
auto contextObj = [context.context CGLContextObj];
|
||||
|
||||
int32_t vsyncEnabled = this->m_VSyncEnabled;
|
||||
CGLSetParameter(contextObj, kCGLCPSwapInterval, &vsyncEnabled);
|
||||
|
||||
auto result = this->m_MTGLEnabled
|
||||
? CGLEnable(contextObj, kCGLCEMPEngine)
|
||||
: CGLDisable(contextObj, kCGLCEMPEngine);
|
||||
BLIZZARD_ASSERT(result == kCGLNoError);
|
||||
|
||||
if (this->m_Window) {
|
||||
this->m_Window->SetOpenGLContext(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->m_Context->context != GLContext::GetCurrentContext()) {
|
||||
this->MakeCurrent(0);
|
||||
}
|
||||
}
|
||||
|
||||
void GLContext::SetFullscreenMode(uint32_t, uint32_t, uint32_t, bool) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void GLContext::SetWindow(GLAbstractWindow* a2, bool a3) {
|
||||
if (!a2) {
|
||||
if (this->m_Window) {
|
||||
this->m_Window->SetOpenGLContext(nullptr);
|
||||
}
|
||||
|
||||
this->m_Window = nullptr;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_Windowed && a2 == this->m_Window) {
|
||||
if (a3) {
|
||||
a2->Show();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NSView* v5;
|
||||
|
||||
if (this->m_Window) {
|
||||
v5 = this->m_Window->GetNSView();
|
||||
|
||||
if (v5 && this->m_Windowed && a2 != this->m_Window) {
|
||||
this->m_Window = a2;
|
||||
this->m_Window->SetOpenGLContext(this);
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
v5 = nullptr;
|
||||
}
|
||||
|
||||
this->m_Window = a2;
|
||||
|
||||
if (!a2->GetNSView()) {
|
||||
this->m_Window->CreateView();
|
||||
}
|
||||
|
||||
float v15;
|
||||
bool v16 = false;
|
||||
CGDisplayFadeReservationToken v17 = 0;
|
||||
|
||||
if (v5 && GLDevice::GetRendererInfo().unk100 > 2639 && this->m_Window->CanEnterFullscreenMode()) {
|
||||
if (!this->m_Windowed) {
|
||||
if (!GLContext::s_DesktopMode) {
|
||||
// TODO
|
||||
// Blizzard::Debug::Assert(
|
||||
// "s_DesktopMode",
|
||||
// "/Users/Shared/BuildServer/wow2.old/work/WoW-code/branches/wow-patch-3_3_5-BNet/WoW/Source/Mac/../../../"
|
||||
// "Engine/Source/Gx/CGxDeviceGLL/GLLayer/GLContext.cpp",
|
||||
// 215
|
||||
// );
|
||||
}
|
||||
|
||||
v15 = 1.25;
|
||||
v16 = false;
|
||||
CGDisplayFadeReservationToken v8 = 0;
|
||||
|
||||
CGError v7 = CGAcquireDisplayFadeReservation(2.25, &v17);
|
||||
|
||||
if (!v7) {
|
||||
v8 = v17;
|
||||
}
|
||||
|
||||
v17 = v8;
|
||||
|
||||
if (v8) {
|
||||
v16 = CGDisplayFade(v8, 0.25, 0, 1.0, 0, 0, 0, 1) == kCGErrorSuccess;
|
||||
}
|
||||
|
||||
CGDirectDisplayID v10 = CGMainDisplayID();
|
||||
CGDisplaySwitchToMode(v10, GLContext::s_DesktopMode);
|
||||
|
||||
this->m_Window->ExitFullscreenMode();
|
||||
|
||||
// TODO
|
||||
// SetSystemUIMode(0, 0);
|
||||
}
|
||||
|
||||
CGReleaseAllDisplays();
|
||||
}
|
||||
|
||||
if (a3) {
|
||||
this->m_Window->Show();
|
||||
}
|
||||
|
||||
this->m_Windowed = 1;
|
||||
CGDisplayRestoreColorSyncSettings();
|
||||
|
||||
if (v17) {
|
||||
if (v16) {
|
||||
float v6 = v15;
|
||||
|
||||
if (v15 > 1.0) {
|
||||
usleep(1000);
|
||||
v6 = v15 - 1.0;
|
||||
}
|
||||
|
||||
CGDisplayFade(v17, v6, 1.0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
CGReleaseDisplayFadeReservation(v17);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void GLContext::Swap() {
|
||||
[this->m_Context->context flushBuffer];
|
||||
}
|
||||
|
||||
void GLContext::Update() {
|
||||
[this->m_Context->context update];
|
||||
}
|
||||
8
src/gx/gll/GLDebugMipmap2D.h
Normal file
8
src/gx/gll/GLDebugMipmap2D.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef GX_GLL_GL_DEBUG_MIPMAP_2D_H
|
||||
#define GX_GLL_GL_DEBUG_MIPMAP_2D_H
|
||||
|
||||
class GLDebugMipmap2D {
|
||||
public:
|
||||
};
|
||||
|
||||
#endif
|
||||
2612
src/gx/gll/GLDevice.cpp
Normal file
2612
src/gx/gll/GLDevice.cpp
Normal file
File diff suppressed because it is too large
Load diff
191
src/gx/gll/GLDevice.h
Normal file
191
src/gx/gll/GLDevice.h
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
#ifndef GX_GLL_GL_DEVICE_H
|
||||
#define GX_GLL_GL_DEVICE_H
|
||||
|
||||
#include "gx/gll/GL.h"
|
||||
#include "gx/gll/GLAbstractWindow.h"
|
||||
#include "gx/gll/GLBatch.h"
|
||||
#include "gx/gll/GLBufferPool.h"
|
||||
#include "gx/gll/GLContext.h"
|
||||
#include "gx/gll/GLDebugMipmap2D.h"
|
||||
#include "gx/gll/GLFramebuffer.h"
|
||||
#include "gx/gll/GLGLSLProgram.h"
|
||||
#include "gx/gll/GLMipmap.h"
|
||||
#include "gx/gll/GLShader.h"
|
||||
#include "gx/gll/GLTexture.h"
|
||||
#include "gx/gll/GLTypes.h"
|
||||
#include "gx/gll/GLVertexArray.h"
|
||||
#include "gx/gll/GLWorker.h"
|
||||
#include "util/BlizzardCore.hpp"
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class GLDevice {
|
||||
public:
|
||||
// Types
|
||||
enum GLDeviceOption {
|
||||
eUseMTGL = 0,
|
||||
eUseVertexArray = 1,
|
||||
eUseGLSL = 2,
|
||||
eCheckGLStates = 3,
|
||||
eFlushBeforeDraw = 4,
|
||||
eDeviceOption5 = 5,
|
||||
eUseHybridShader = 6,
|
||||
eDeviceOption7 = 7,
|
||||
eDeviceOption8 = 8,
|
||||
eShaderConstantBindings = 9
|
||||
};
|
||||
|
||||
struct RendererInfo {
|
||||
uint8_t init = 0;
|
||||
uint32_t vendor_id;
|
||||
uint32_t renderer_id;
|
||||
uint32_t max_color_attachments;
|
||||
uint32_t unk36; // max clip planes
|
||||
uint32_t unk100;
|
||||
};
|
||||
|
||||
// Static variables
|
||||
static Blizzard::Thread::TLSSlot m_CurrentDevice;
|
||||
static std::vector<GLDevice *, std::allocator<GLDevice*>> m_Devices;
|
||||
static bool m_ExtARBShadow;
|
||||
static bool m_ExtColorMaskIndexed;
|
||||
static RendererInfo m_RendererInfo;
|
||||
static bool m_ShaderConstantBindings;
|
||||
static int32_t m_StaticResourcesRefCount;
|
||||
static bool m_UseHybridShader;
|
||||
static GLBuffer* m_BlitQuadVBO;
|
||||
static GLShader* m_DeviceShaders[];
|
||||
static GLTexture* m_DeviceTextures[];
|
||||
static GLVertexFormat m_NormalBlitVF;
|
||||
static GLVertexFormat m_InvertedBlitVF;
|
||||
static GLFramebuffer* m_F8330C;
|
||||
|
||||
// Static functions
|
||||
static GLDevice* Get(void);
|
||||
static void Set(GLDevice*);
|
||||
static void InitPools(void);
|
||||
static RendererInfo GetRendererInfo(void);
|
||||
static void InitRendererInfo(void);
|
||||
static void SetOption(GLDeviceOption, bool);
|
||||
static void StaticInit(void);
|
||||
|
||||
// Member variables
|
||||
std::basic_string<char, std::char_traits<char>, std::allocator<char>> m_DebugName;
|
||||
GLStates m_States;
|
||||
GLTexture* m_Textures[16] = {};
|
||||
GLShader* m_PixelShader = nullptr;
|
||||
GLShader* m_VertexShader = nullptr;
|
||||
GLGLSLProgram* m_GLSLProgram = nullptr;
|
||||
GLVertexArray* m_VertexArrayObject = &m_DefaultVertexArrayObject;
|
||||
GLFramebuffer* m_SystemTarget = nullptr;
|
||||
GLFramebuffer* m_FBOTarget = nullptr;
|
||||
GLFramebuffer* m_CurrentTarget = nullptr;
|
||||
GLMipmap* m_CurrentTargetColor[4] = {};
|
||||
GLMipmap* m_CurrentTargetDepth = nullptr;
|
||||
GLMipmap* m_CurrentTargetStencil = nullptr;
|
||||
GLMipmap* m_CurrentDepthBuffer = nullptr;
|
||||
GLTexture2D* m_BackBufferColor = nullptr;
|
||||
GLTexture2D* m_BackBufferDepth = nullptr;
|
||||
GLTexture2D* m_BackBufferStencil = nullptr;
|
||||
GLContext m_Context;
|
||||
GLBufferPool* m_PBOPool = nullptr;
|
||||
GLWorker* m_TexWorker = nullptr;
|
||||
GLTexture* m_BoundTextures[4][16] = {};
|
||||
GLVertexArray m_DefaultVertexArrayObject;
|
||||
GLDirtyRange m_DirtyVertexShaderConsts;
|
||||
GLDirtyRange m_DirtyPixelShaderConsts;
|
||||
float m_ConstantDepthBias = 0.0f;
|
||||
float m_SlopeScaledDepthBias = 0.0f;
|
||||
bool m_Init = 0;
|
||||
uint32_t m_DrawCount = 0;
|
||||
uint32_t m_ID = -1;
|
||||
std::list<GLTexture*, std::allocator<GLTexture*>> m_TextureList;
|
||||
std::list<GLTexture*>::iterator m_OldestActiveTexture;
|
||||
uint32_t m_TextureTotalSize = 0;
|
||||
uint32_t m_FrameNumber = 1;
|
||||
std::list<GLDebugMipmap2D*, std::allocator<GLDebugMipmap2D*>> m_DebugMipmaps;
|
||||
bool m_BatchViewerEnabled = 0;
|
||||
bool m_UseWindowSystemBuffer = 0;
|
||||
bool m_FlippedSystemBuffer = 0;
|
||||
bool m_ShaderCompiler = 0;
|
||||
bool m_WorkerDevice;
|
||||
GLStates m_DefaultStates;
|
||||
std::vector<GLBatch, std::allocator<GLBatch>>* m_FrameBatches;
|
||||
bool m_CaptureOnlyOneFrame = 0;
|
||||
bool m_StopCapturingBatches = 0;
|
||||
bool m_CaptureBatches = 0;
|
||||
int32_t m_IndentLevel = 0;
|
||||
GLAbstractWindow* m_FirstCapturedWindow = nullptr;
|
||||
|
||||
// Member functions
|
||||
GLDevice();
|
||||
void ApplyGLBindings(const GLStates&, bool);
|
||||
void ApplyGLStates(const GLStates&, bool);
|
||||
void ApplyShaderConstants(void);
|
||||
void ApplyTransforms(void);
|
||||
void BindBuffer(GLBuffer*, GLEnum);
|
||||
void BindFramebuffer(GLFramebuffer*);
|
||||
void BindGLSLProgram(GLGLSLProgram*);
|
||||
void BindShader(GLShader*);
|
||||
void BindTexture(GLEnum, GLTexture*);
|
||||
void BindVertexArray(GLVertexArray*);
|
||||
void BlitFramebuffer(GLMipmap*, const GLRect*, GLMipmap*, const GLRect*, GLEnum, GLEnum);
|
||||
void CheckDepthTarget(void);
|
||||
void Clear(uint32_t, const GLColor4f&, double, int32_t);
|
||||
void CopyTex(uint32_t, uint32_t, GLMipmap*, const GLRect*);
|
||||
GLBuffer* CreateBuffer(GLEnum, uint32_t, const void*, GLEnum, GLEnum);
|
||||
GLShader* CreateShader(GLShader::ShaderType, const void*, int32_t, const char*);
|
||||
GLTexture* CreateTexture2D(uint32_t, uint32_t, uint32_t, GLTextureFormat, uint32_t);
|
||||
GLTexture* CreateTextureCubeMap(uint32_t, uint32_t, GLTextureFormat, uint32_t);
|
||||
void Draw(GLEnum, uint32_t, uint32_t);
|
||||
void DrawIndexed(GLEnum, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
void DrawRect(void);
|
||||
GLFramebuffer* GetCurrentTarget(void); // invented name
|
||||
uint32_t GetID(void);
|
||||
GLShader* GetShader(GLShader::ShaderType);
|
||||
const GLStates::VertexArrayObject& GetVertexArrayStates();
|
||||
void GLLDraw(GLEnum, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
void Init(GLAbstractWindow*, const char*, uint32_t, GLTextureFormat);
|
||||
void LoadDefaultStates(void);
|
||||
void ResetBackbuffer(uint32_t width, uint32_t height, GLTextureFormat colorFormat, GLTextureFormat depthFormat, uint32_t sampleCount);
|
||||
void Resize(uint32_t width, uint32_t height);
|
||||
void RestoreTextures(void);
|
||||
void SetActiveTexture(uint32_t);
|
||||
void SetAlphaBlend(GLEnum, GLEnum, GLEnum);
|
||||
void SetAlphaBlendEnable(bool);
|
||||
void SetAlphaTest(GLEnum, float);
|
||||
void SetAlphaTestEnable(bool);
|
||||
void SetClearColor(const GLColor4f&);
|
||||
void SetClearDepth(double);
|
||||
void SetClearStencil(int32_t);
|
||||
void SetColorWriteMask(bool red, bool green, bool blue, bool alpha, uint32_t index);
|
||||
void SetCullMode(GLEnum);
|
||||
void SetDepthBias(float constantBias, float slopeScaledBias);
|
||||
void SetDepthTestEnable(bool);
|
||||
void SetDepthTestFunc(GLEnum);
|
||||
void SetDepthWriteMask(bool);
|
||||
void SetDisplay(uint32_t, uint32_t, GLTextureFormat, GLTextureFormat, uint32_t, bool, bool, uint32_t);
|
||||
void SetFogColor(float r, float g, float b, float a);
|
||||
void SetFogEnable(bool enable);
|
||||
void SetFogParam(GLEnum param, float value);
|
||||
void SetIndexBuffer(GLBuffer*);
|
||||
void SetLightingEnable(bool enable);
|
||||
void SetScissor(bool, const GLRect&);
|
||||
void SetShader(GLShader::ShaderType, GLShader*);
|
||||
void SetShaderConstants(GLShader::ShaderType, uint32_t, const float*, uint32_t);
|
||||
void SetShaderConstantsInternal(GLShader::ShaderType, uint32_t, const float*, uint32_t);
|
||||
void SetTexture(uint32_t, GLTexture*);
|
||||
void SetTransform(GLEnum, const float*);
|
||||
void SetUnpackClientStorage(bool);
|
||||
void SetVertexBuffer(uint32_t, GLBuffer*, uint32_t, uint32_t);
|
||||
void SetVertexFormat(GLVertexFormat*);
|
||||
void SetViewport(const GLRect&, double, double);
|
||||
void Sub34BB0(GLEnum a2, GLMipmap* a3, uint32_t index);
|
||||
void Sub38460(bool);
|
||||
void Swap(void);
|
||||
void UpdateFFPTexturing(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
149
src/gx/gll/GLFramebuffer.cpp
Normal file
149
src/gx/gll/GLFramebuffer.cpp
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
#include "gx/gll/GLFramebuffer.h"
|
||||
#include "gx/gll/GLDevice.h"
|
||||
#include "gx/gll/GLMipmap.h"
|
||||
#include "gx/gll/GLPool.h"
|
||||
#include "gx/gll/GLTypes.h"
|
||||
|
||||
GLFramebuffer* GLFramebuffer::Create(bool a1) {
|
||||
GLFramebuffer* framebuffer = new GLFramebuffer(a1);
|
||||
|
||||
if (!a1) {
|
||||
// TODO
|
||||
// BLIZZARD_ASSERT(framebuffer->m_FramebufferID >= PoolStats<GLFramebuffer>::NAME_POOL_FIRST_NAME);
|
||||
}
|
||||
|
||||
BLIZZARD_ASSERT(framebuffer->m_NumAttach == 0);
|
||||
|
||||
framebuffer->m_Width = 0;
|
||||
framebuffer->m_Height = 0;
|
||||
framebuffer->m_Device = GLDevice::Get();
|
||||
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
GLFramebuffer::GLFramebuffer(bool a1) : GLObject() {
|
||||
if (!a1) {
|
||||
this->m_FramebufferID = GLPool<GLFramebuffer>::Get()->GetNextName();
|
||||
}
|
||||
}
|
||||
|
||||
void GLFramebuffer::Attach(GLMipmap* image, GLenum a3, int32_t a4) {
|
||||
BLIZZARD_ASSERT(this->m_Device == GLDevice::Get());
|
||||
|
||||
if (!image) {
|
||||
this->Detach(a3);
|
||||
return;
|
||||
}
|
||||
|
||||
if (a3 == GL_DEPTH_STENCIL) {
|
||||
BLIZZARD_ASSERT(image->GetFormat() == GLTF_D24S8);
|
||||
|
||||
this->Attach(image, GL_DEPTH_ATTACHMENT, 0);
|
||||
this->Attach(image, GL_STENCIL_ATTACHMENT, 0);
|
||||
|
||||
(*image->m_AttachPoints)[this->m_FramebufferID].point = GL_DEPTH_STENCIL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t index;
|
||||
|
||||
if (a3 == GL_DEPTH_ATTACHMENT) {
|
||||
index = 4;
|
||||
} else if (a3 == GL_STENCIL_ATTACHMENT) {
|
||||
index = 5;
|
||||
} else {
|
||||
index = a3 - GL_COLOR_ATTACHMENT0;
|
||||
}
|
||||
|
||||
BLIZZARD_ASSERT(index < MAX_ATTACHMENT);
|
||||
|
||||
GLMipmap* oldImage = this->m_Attachments[index];
|
||||
|
||||
if (image != oldImage) {
|
||||
if (oldImage) {
|
||||
oldImage->Detach(this, a3, true);
|
||||
} else {
|
||||
++this->m_NumAttach;
|
||||
}
|
||||
|
||||
this->m_Attachments[index] = image;
|
||||
|
||||
this->m_Width = image->m_Width;
|
||||
this->m_Height = image->m_Height;
|
||||
|
||||
image->Attach(this, a3, a4);
|
||||
this->m_Device->Sub38460(0);
|
||||
}
|
||||
|
||||
BLIZZARD_ASSERT((*image->m_AttachPoints)[m_FramebufferID].framebuffer == this);
|
||||
}
|
||||
|
||||
void GLFramebuffer::Detach(GLenum a2) {
|
||||
int32_t v2 = a2;
|
||||
int32_t index;
|
||||
|
||||
if (a2 == GL_DEPTH_STENCIL) {
|
||||
index = 5;
|
||||
v2 = GL_STENCIL_ATTACHMENT;
|
||||
this->Detach(GL_DEPTH_ATTACHMENT);
|
||||
} else if (a2 == GL_DEPTH_ATTACHMENT) {
|
||||
index = 4;
|
||||
} else if (a2 == GL_STENCIL_ATTACHMENT) {
|
||||
index = 5;
|
||||
} else {
|
||||
index = a2 - GL_COLOR_ATTACHMENT0;
|
||||
}
|
||||
|
||||
BLIZZARD_ASSERT(index < MAX_ATTACHMENT);
|
||||
|
||||
GLMipmap* oldImage = this->m_Attachments[index];
|
||||
|
||||
if (oldImage) {
|
||||
oldImage->Detach(this, v2, 0);
|
||||
|
||||
--this->m_NumAttach;
|
||||
|
||||
this->m_Attachments[index] = 0;
|
||||
|
||||
if (this->m_Device == GLDevice::Get()) {
|
||||
this->m_Device->Sub38460(0);
|
||||
}
|
||||
|
||||
if (this->m_NumAttach == 0) {
|
||||
this->m_Width = 0;
|
||||
this->m_Height = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLMipmap* GLFramebuffer::GetAttachment(GLEnum a2) {
|
||||
int32_t index;
|
||||
|
||||
if (a2 == GL_DEPTH_ATTACHMENT) {
|
||||
index = 4;
|
||||
} else if (a2 == GL_STENCIL_ATTACHMENT) {
|
||||
index = 5;
|
||||
} else {
|
||||
index = a2 - GL_COLOR_ATTACHMENT0;
|
||||
}
|
||||
|
||||
BLIZZARD_ASSERT(index < MAX_ATTACHMENT);
|
||||
|
||||
return this->m_Attachments[index];
|
||||
}
|
||||
|
||||
int32_t GLFramebuffer::GetSampleCount() {
|
||||
return this->m_FramebufferID
|
||||
? 1
|
||||
: this->m_Device->m_Context.m_Context->sampleCount;
|
||||
}
|
||||
|
||||
bool GLFramebuffer::IsValid() {
|
||||
auto status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
|
||||
return status == GL_FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
|
||||
void GLFramebuffer::ReleaseObject() {
|
||||
// TODO
|
||||
}
|
||||
38
src/gx/gll/GLFramebuffer.h
Normal file
38
src/gx/gll/GLFramebuffer.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef GX_GLL_GL_FRAMEBUFFER_H
|
||||
#define GX_GLL_GL_FRAMEBUFFER_H
|
||||
|
||||
#include "gx/gll/GL.h"
|
||||
#include "gx/gll/GLObject.h"
|
||||
#include <cstdint>
|
||||
|
||||
#define MAX_ATTACHMENT 6
|
||||
|
||||
class GLDevice;
|
||||
class GLMipmap;
|
||||
|
||||
class GLFramebuffer : public GLObject {
|
||||
public:
|
||||
// Static functions
|
||||
static GLFramebuffer* Create(bool);
|
||||
|
||||
// Member variables
|
||||
int32_t m_Width = 0;
|
||||
int32_t m_Height = 0;
|
||||
uint32_t m_FramebufferID = 0;
|
||||
GLDevice* m_Device;
|
||||
GLMipmap* m_Attachments[6] = {};
|
||||
uint32_t m_NumAttach = 0;
|
||||
|
||||
// Virtual member functions
|
||||
virtual void ReleaseObject();
|
||||
|
||||
// Member functions
|
||||
GLFramebuffer(bool);
|
||||
void Attach(GLMipmap*, GLenum, int32_t);
|
||||
void Detach(GLenum);
|
||||
GLMipmap* GetAttachment(GLEnum);
|
||||
int32_t GetSampleCount(void);
|
||||
bool IsValid();
|
||||
};
|
||||
|
||||
#endif
|
||||
7
src/gx/gll/GLGLSLProgram.cpp
Normal file
7
src/gx/gll/GLGLSLProgram.cpp
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include "gx/gll/GLGLSLProgram.h"
|
||||
#include "gx/gll/GLShader.h"
|
||||
|
||||
GLGLSLProgram* GLGLSLProgram::Find(GLShader* a1, GLShader* a2) {
|
||||
// TODO
|
||||
return nullptr;
|
||||
}
|
||||
14
src/gx/gll/GLGLSLProgram.h
Normal file
14
src/gx/gll/GLGLSLProgram.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef GX_GLL_GL_GLSL_PROGRAM_H
|
||||
#define GX_GLL_GL_GLSL_PROGRAM_H
|
||||
|
||||
#include "gx/gll/GLObject.h"
|
||||
|
||||
class GLShader;
|
||||
|
||||
class GLGLSLProgram : public GLObject {
|
||||
public:
|
||||
// Static functions
|
||||
static GLGLSLProgram* Find(GLShader*, GLShader*);
|
||||
};
|
||||
|
||||
#endif
|
||||
39
src/gx/gll/GLLayerView.h
Normal file
39
src/gx/gll/GLLayerView.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef GX_GLL_GL_LAYER_VIEW_H
|
||||
#define GX_GLL_GL_LAYER_VIEW_H
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
class GLWindow;
|
||||
|
||||
@interface GLLayerView : NSView <NSWindowDelegate>
|
||||
|
||||
@property CGDirectDisplayID m_display;
|
||||
@property GLWindow* m_GLWindow;
|
||||
@property (retain) NSOpenGLContext* m_savedContext;
|
||||
@property (retain) NSCursor* m_cursor;
|
||||
|
||||
- (BOOL)acceptsFirstResponder;
|
||||
- (void)drawRect:(NSRect)dirtyRect;
|
||||
- (id)initWithFrame:(NSRect)frame glWindow:(GLWindow*)window;
|
||||
- (void)keyDown:(NSEvent*)event;
|
||||
- (void)keyUp:(NSEvent*)event;
|
||||
- (void)mouseDown:(NSEvent*)event;
|
||||
- (void)mouseDragged:(NSEvent*)event;
|
||||
- (void)mouseMoved:(NSEvent*)event;
|
||||
- (void)mouseUp:(NSEvent*)event;
|
||||
- (void)otherMouseDown:(NSEvent*)event;
|
||||
- (void)otherMouseDragged:(NSEvent*)event;
|
||||
- (void)otherMouseUp:(NSEvent*)event;
|
||||
- (void)rightMouseDown:(NSEvent*)event;
|
||||
- (void)rightMouseDragged:(NSEvent*)event;
|
||||
- (void)rightMouseUp:(NSEvent*)event;
|
||||
- (void)scrollWheel:(NSEvent*)event;
|
||||
- (void)viewDidChangeBackingProperties;
|
||||
- (void)viewDidEndLiveResize;
|
||||
- (void)update;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
179
src/gx/gll/GLLayerView.mm
Normal file
179
src/gx/gll/GLLayerView.mm
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
#include "gx/gll/GLLayerView.h"
|
||||
#include "gx/gll/GLContext.h"
|
||||
#include "gx/gll/GLDevice.h"
|
||||
#include "gx/gll/GLWindow.h"
|
||||
#include <cmath>
|
||||
|
||||
@implementation GLLayerView
|
||||
|
||||
- (BOOL)acceptsFirstResponder {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (GLWindowCallbacks*)callbacks {
|
||||
if (self.m_GLWindow) {
|
||||
return self.m_GLWindow->m_ActiveCallbacks;
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect {
|
||||
GLContext* context = self.m_GLWindow->m_Context;
|
||||
|
||||
if (context && context->m_Device) {
|
||||
context->m_Device->DrawRect();
|
||||
}
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame glWindow:(GLWindow*)window {
|
||||
self = [super initWithFrame:frame];
|
||||
[self setWantsBestResolutionOpenGLSurface:YES];
|
||||
|
||||
if (self) {
|
||||
[self setGLWindow:window];
|
||||
}
|
||||
|
||||
CGSetLocalEventsSuppressionInterval(0.0);
|
||||
|
||||
self.m_display = [self findMyDisplay];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setGLWindow:(GLWindow*)window {
|
||||
self.m_GLWindow = window;
|
||||
}
|
||||
|
||||
- (CGDirectDisplayID)findMyDisplay {
|
||||
NSRect frame = self.frame;
|
||||
|
||||
uint32_t displayCount;
|
||||
CGDirectDisplayID displays[1];
|
||||
|
||||
CGGetDisplaysWithPoint(frame.origin, 1, displays, &displayCount);
|
||||
|
||||
if (displayCount) {
|
||||
return displays[0];
|
||||
} else {
|
||||
return CGMainDisplayID();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent*)event {
|
||||
[self callbacks]->OnKeyDown(event);
|
||||
}
|
||||
|
||||
- (void)keyUp:(NSEvent*)event {
|
||||
[self callbacks]->OnKeyUp(event);
|
||||
}
|
||||
|
||||
- (void)mouseDown:(NSEvent*)event {
|
||||
NSPoint location = event.locationInWindow;
|
||||
NSRect frame = self.frame;
|
||||
|
||||
float x = location.x;
|
||||
float y = frame.size.height - location.y;
|
||||
|
||||
NSInteger buttonNumber = event.buttonNumber;
|
||||
|
||||
[self callbacks]->OnMouseDown(
|
||||
buttonNumber,
|
||||
static_cast<int32_t>(floor(x)),
|
||||
static_cast<int32_t>(floor(y))
|
||||
);
|
||||
}
|
||||
|
||||
- (void)mouseDragged:(NSEvent*)event {
|
||||
[self mouseMoved:event];
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(NSEvent*)event {
|
||||
float v20 = 0.0;
|
||||
float v21 = 0.0;
|
||||
|
||||
// TODO
|
||||
// - logic to handle fullscreen mouse movement
|
||||
|
||||
NSPoint location = event.locationInWindow;
|
||||
NSRect frame = self.frame;
|
||||
|
||||
float x = location.x + v21;
|
||||
float y = (frame.size.height - location.y) + v20;
|
||||
|
||||
[self callbacks]->OnMouseMoved(
|
||||
static_cast<int32_t>(floor(x)),
|
||||
static_cast<int32_t>(floor(y))
|
||||
);
|
||||
}
|
||||
|
||||
- (void)mouseUp:(NSEvent*)event {
|
||||
NSPoint location = event.locationInWindow;
|
||||
NSRect frame = self.frame;
|
||||
|
||||
float x = location.x;
|
||||
float y = frame.size.height - location.y;
|
||||
|
||||
NSInteger buttonNumber = event.buttonNumber;
|
||||
|
||||
[self callbacks]->OnMouseUp(
|
||||
buttonNumber,
|
||||
static_cast<int32_t>(floor(x)),
|
||||
static_cast<int32_t>(floor(y))
|
||||
);
|
||||
}
|
||||
|
||||
- (void)otherMouseDown:(NSEvent*)event {
|
||||
[self mouseDown:event];
|
||||
}
|
||||
|
||||
- (void)otherMouseDragged:(NSEvent*)event {
|
||||
[self mouseMoved:event];
|
||||
}
|
||||
|
||||
- (void)otherMouseUp:(NSEvent*)event {
|
||||
[self mouseUp:event];
|
||||
}
|
||||
|
||||
- (void)rightMouseDown:(NSEvent*)event {
|
||||
[self mouseDown:event];
|
||||
}
|
||||
|
||||
- (void)rightMouseDragged:(NSEvent*)event {
|
||||
[self mouseMoved:event];
|
||||
}
|
||||
|
||||
- (void)rightMouseUp:(NSEvent*)event {
|
||||
[self mouseUp:event];
|
||||
}
|
||||
|
||||
- (void)scrollWheel:(NSEvent*)event {
|
||||
// TODO
|
||||
}
|
||||
|
||||
- (void)viewDidChangeBackingProperties {
|
||||
[self update];
|
||||
}
|
||||
|
||||
- (void)viewDidEndLiveResize {
|
||||
int32_t width = std::floor(self.frame.size.width);
|
||||
int32_t height = std::floor(self.frame.size.height);
|
||||
|
||||
[self update];
|
||||
|
||||
[self callbacks]->OnResized(
|
||||
width,
|
||||
height,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
- (void)update {
|
||||
self.m_display = [self findMyDisplay];
|
||||
|
||||
if (self.m_GLWindow->m_Context) {
|
||||
self.m_GLWindow->m_Context->Update();
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
492
src/gx/gll/GLMipmap.cpp
Normal file
492
src/gx/gll/GLMipmap.cpp
Normal file
|
|
@ -0,0 +1,492 @@
|
|||
#include "gx/gll/GLMipmap.h"
|
||||
#include "gx/gll/GLCommand.h"
|
||||
#include "gx/gll/GLDevice.h"
|
||||
#include "gx/gll/GLFramebuffer.h"
|
||||
|
||||
int32_t GLMipmap::GetDepthBits() {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GLMipmap::Attach(GLFramebuffer* framebuffer, GLenum attachPoint, int32_t a4) {
|
||||
if (!this->m_AttachPoints) {
|
||||
this->m_AttachPoints = new std::vector<GLAttachPoint>();
|
||||
}
|
||||
|
||||
auto& attachPoints = *this->m_AttachPoints;
|
||||
auto framebufferID = framebuffer->m_FramebufferID;
|
||||
|
||||
if (framebufferID >= attachPoints.size()) {
|
||||
attachPoints.resize(framebufferID + 1);
|
||||
} else {
|
||||
BLIZZARD_ASSERT(attachPoints[framebufferID].framebuffer != framebuffer || attachPoints[framebufferID].point != attachPoint);
|
||||
|
||||
auto& attach = attachPoints[framebufferID];
|
||||
|
||||
if (
|
||||
attach.point
|
||||
&& (attach.point != GL_DEPTH_ATTACHMENT || attachPoint != GL_STENCIL_ATTACHMENT)
|
||||
&& (attach.point != GL_STENCIL_ATTACHMENT || attachPoint != GL_DEPTH_ATTACHMENT)
|
||||
) {
|
||||
framebuffer->Detach(attach.point);
|
||||
}
|
||||
}
|
||||
|
||||
GLDevice* device = GLDevice::Get();
|
||||
|
||||
auto currentTarget = device->GetCurrentTarget();
|
||||
device->BindFramebuffer(framebuffer);
|
||||
|
||||
if (framebufferID) {
|
||||
if (this->m_Target == GL_TEXTURE_3D) {
|
||||
glFramebufferTexture3DEXT(
|
||||
GL_FRAMEBUFFER,
|
||||
attachPoint,
|
||||
GL_TEXTURE_3D,
|
||||
this->m_Texture->m_TextureID,
|
||||
this->m_Level,
|
||||
a4
|
||||
);
|
||||
} else {
|
||||
glFramebufferTexture2DEXT(
|
||||
GL_FRAMEBUFFER,
|
||||
attachPoint,
|
||||
this->m_Target,
|
||||
this->m_Texture->m_TextureID,
|
||||
this->m_Level
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (attachPoint == GL_DEPTH_ATTACHMENT && !this->m_DepthBits) {
|
||||
GLint depthBits = 0;
|
||||
glGetIntegerv(GL_DEPTH_BITS, &depthBits);
|
||||
this->m_DepthBits = depthBits;
|
||||
}
|
||||
|
||||
device->BindFramebuffer(currentTarget);
|
||||
|
||||
auto& attach = attachPoints[framebufferID];
|
||||
attach.framebuffer = framebuffer;
|
||||
attach.zOffset = a4;
|
||||
|
||||
if (
|
||||
(attach.point != GL_DEPTH_ATTACHMENT || attachPoint != GL_STENCIL_ATTACHMENT)
|
||||
&& (attach.point != GL_STENCIL_ATTACHMENT || attachPoint != GL_DEPTH_ATTACHMENT)
|
||||
) {
|
||||
attach.point = attachPoint;
|
||||
} else {
|
||||
attach.point = GL_DEPTH_STENCIL;
|
||||
}
|
||||
}
|
||||
|
||||
void GLMipmap::Detach(GLFramebuffer* framebuffer, GLenum attachPoint, bool a4) {
|
||||
GLuint framebufferID = framebuffer->m_FramebufferID;
|
||||
|
||||
auto& attachPoints = *this->m_AttachPoints;
|
||||
|
||||
BLIZZARD_ASSERT(attachPoints.size() >= framebufferID);
|
||||
BLIZZARD_ASSERT(attachPoints[framebufferID].framebuffer == framebuffer);
|
||||
|
||||
if (!a4 && framebufferID) {
|
||||
GLDevice* v12 = GLDevice::Get();
|
||||
GLFramebuffer* v14 = v12->GetCurrentTarget();
|
||||
v12->BindFramebuffer(framebuffer);
|
||||
|
||||
if (this->m_Target == GL_TEXTURE_3D) {
|
||||
glFramebufferTexture3DEXT(GL_FRAMEBUFFER, attachPoint, GL_TEXTURE_3D, 0, 0, 0);
|
||||
} else {
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER, attachPoint, this->m_Target, 0, 0);
|
||||
}
|
||||
|
||||
v12->BindFramebuffer(v14);
|
||||
}
|
||||
|
||||
GLAttachPoint* v9 = &attachPoints[framebufferID];
|
||||
|
||||
if (v9->point == GL_DEPTH_STENCIL) {
|
||||
BLIZZARD_ASSERT(this->GetFormat() == GLTF_D24S8);
|
||||
|
||||
if (attachPoint == GL_DEPTH_ATTACHMENT) {
|
||||
v9->point = GL_STENCIL_ATTACHMENT;
|
||||
} else if (attachPoint == GL_STENCIL_ATTACHMENT) {
|
||||
v9->point = GL_DEPTH_ATTACHMENT;
|
||||
} else {
|
||||
BLIZZARD_ASSERT(false);
|
||||
}
|
||||
} else {
|
||||
BLIZZARD_ASSERT(attachPoints[framebufferID].point == attachPoint);
|
||||
|
||||
v9->framebuffer = 0;
|
||||
v9->point = 0;
|
||||
v9->zOffset = 0;
|
||||
|
||||
// TODO
|
||||
// this->m_Texture->m_TimeStamp = Blizzard::Time::GetTimestamp();
|
||||
}
|
||||
}
|
||||
|
||||
void GLMipmap::DetachAll() {
|
||||
if (!this->m_AttachPoints) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& attachPoints = *this->m_AttachPoints;
|
||||
for (int32_t i = 0; i < attachPoints.size(); i++) {
|
||||
BLIZZARD_ASSERT(attachPoints[i].point != GL_ZERO);
|
||||
BLIZZARD_ASSERT(attachPoints[i].framebuffer->m_FramebufferID == i);
|
||||
|
||||
attachPoints[i].framebuffer->Detach(attachPoints[i].point);
|
||||
}
|
||||
}
|
||||
|
||||
GLTextureFormat GLMipmap::GetFormat() {
|
||||
return this->m_Texture->GetFormat();
|
||||
}
|
||||
|
||||
TextureFormatInfo& GLMipmap::GetFormatInfo() {
|
||||
return this->m_Texture->GetFormatInfo();
|
||||
};
|
||||
|
||||
uint16_t GLMipmap::GetHeight() {
|
||||
return this->m_Height;
|
||||
}
|
||||
|
||||
int32_t GLMipmap::GetPitch() {
|
||||
int32_t bpp = this->GetFormatInfo().m_BytePerPixel;
|
||||
int32_t v4 = this->m_Texture->var12 >> this->m_Level;
|
||||
return v4 >= bpp ? v4 : bpp;
|
||||
}
|
||||
|
||||
GLTexture* GLMipmap::GetTexture() {
|
||||
return this->m_Texture;
|
||||
}
|
||||
|
||||
uint32_t GLMipmap::GetTextureID() {
|
||||
return this->m_Texture->m_TextureID;
|
||||
}
|
||||
|
||||
uint16_t GLMipmap::GetWidth() {
|
||||
return this->m_Width;
|
||||
}
|
||||
|
||||
void* GLMipmap::Map(GLEnum mode, const GLBox* area) {
|
||||
BLIZZARD_ASSERT(!this->m_Texture->IsSystemBuffer());
|
||||
BLIZZARD_ASSERT(this->m_Data != nullptr);
|
||||
BLIZZARD_ASSERT(!this->m_Texture->IsRenderTarget());
|
||||
BLIZZARD_ASSERT(mode != GL_ZERO);
|
||||
BLIZZARD_ASSERT(this->m_MapParams == nullptr);
|
||||
|
||||
if (mode != GL_READ_ONLY) {
|
||||
this->m_Texture->m_MappedMipmaps++;
|
||||
}
|
||||
|
||||
MapParams* mapParams = new MapParams();
|
||||
this->m_MapParams = mapParams;
|
||||
|
||||
if (area) {
|
||||
BLIZZARD_ASSERT(area->width > 0);
|
||||
BLIZZARD_ASSERT(area->height > 0);
|
||||
BLIZZARD_ASSERT(area->depth > 0);
|
||||
BLIZZARD_ASSERT(!this->GetFormatInfo().m_IsCompressed || ((area->top & 0x3) == 0 && (area->left & 0x3) == 0 && (area->width & 0x3) == 0 && (area->height & 0x3) == 0));
|
||||
BLIZZARD_ASSERT((area->height + area->top) <= this->m_Height);
|
||||
BLIZZARD_ASSERT((area->depth + area->front) <= this->m_Depth);
|
||||
BLIZZARD_ASSERT((area->width + area->left) <= this->m_Width);
|
||||
|
||||
mapParams->m_MapArea = {
|
||||
area->left,
|
||||
area->top,
|
||||
area->front,
|
||||
area->width,
|
||||
area->height,
|
||||
area->depth
|
||||
};
|
||||
|
||||
int32_t size = this->GetFormatInfo().m_BytePerPixel
|
||||
* this->m_Width
|
||||
* mapParams->m_MapArea.depth
|
||||
* mapParams->m_MapArea.height;
|
||||
|
||||
mapParams->m_Size = this->GetFormatInfo().m_IsCompressed
|
||||
? size >> 4
|
||||
: size;
|
||||
|
||||
mapParams->m_Unk7 = (this->GetFormatInfo().m_BytePerPixel * mapParams->m_MapArea.left)
|
||||
>> this->GetFormatInfo().m_IsCompressed ? 2 : 0;
|
||||
} else {
|
||||
mapParams->m_MapArea = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
this->m_Width,
|
||||
this->m_Height,
|
||||
this->m_Depth
|
||||
};
|
||||
|
||||
mapParams->m_Size = this->m_Size;
|
||||
|
||||
mapParams->m_Unk7 = 0;
|
||||
}
|
||||
|
||||
mapParams->m_MapMode = mode;
|
||||
|
||||
int32_t rowPitch = this->GetPitch();
|
||||
|
||||
BLIZZARD_ASSERT(((mapParams->m_MapArea.top * rowPitch) + mapParams->m_MapArea.left * this->GetFormatInfo().m_BytePerPixel) < (this->GetFormatInfo().m_IsCompressed ? this->m_Size << 4 : this->m_Size));
|
||||
|
||||
int32_t v22 = rowPitch * this->m_Height;
|
||||
if (this->GetFormatInfo().m_IsCompressed) {
|
||||
v22 >>= 2;
|
||||
}
|
||||
|
||||
unsigned char* v24 = this->m_Data
|
||||
+ ((mapParams->m_MapArea.top * rowPitch) >> (this->GetFormatInfo().m_IsCompressed ? 2 : 0))
|
||||
+ (mapParams->m_MapArea.front * v22);
|
||||
|
||||
mapParams->m_Unk8 = v24;
|
||||
|
||||
return v24 + mapParams->m_Unk7;
|
||||
}
|
||||
|
||||
void* GLMipmap::Map(GLEnum mode, const GLRect* rect) {
|
||||
if (rect) {
|
||||
GLBox area = {
|
||||
rect->left,
|
||||
rect->top,
|
||||
0,
|
||||
rect->width,
|
||||
rect->height,
|
||||
1
|
||||
};
|
||||
|
||||
return this->Map(mode, &area);
|
||||
} else {
|
||||
return this->Map(mode, static_cast<GLBox*>(nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
void GLMipmap::ReleaseObject() {
|
||||
BLIZZARD_ASSERT(this->m_MapParams == nullptr);
|
||||
|
||||
this->RemoveDebugMipmap();
|
||||
this->DetachAll();
|
||||
|
||||
if (this->m_AttachPoints) {
|
||||
delete this->m_AttachPoints;
|
||||
}
|
||||
|
||||
this->m_AttachPoints = nullptr;
|
||||
this->m_Unk24 = 0;
|
||||
}
|
||||
|
||||
void GLMipmap::RemoveDebugMipmap() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void GLMipmap::ResetData(GLEnum target, int32_t level, unsigned char* data) {
|
||||
BLIZZARD_ASSERT(this->m_Target != GL_TEXTURE_3D || !this->GetFormatInfo().m_IsCompressed);
|
||||
|
||||
this->m_Target = target;
|
||||
this->m_Level = level;
|
||||
this->m_Data = data;
|
||||
|
||||
BLIZZARD_ASSERT(this->GetFormat() != GLTF_INVALID);
|
||||
BLIZZARD_ASSERT(this->GetFormat() < GLTF_NUM_TEXTURE_FORMATS);
|
||||
|
||||
if (!this->m_Texture->IsSystemBuffer() && this->m_Texture->IsRenderTarget()) {
|
||||
BLIZZARD_ASSERT(!this->GetFormatInfo().m_IsCompressed);
|
||||
|
||||
this->TexImage(nullptr);
|
||||
this->m_Unk24 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void GLMipmap::ResetSize(uint32_t width, uint32_t height, uint32_t depth) {
|
||||
this->m_Width = width ? width : 1;
|
||||
this->m_Height = height ? height : 1;
|
||||
this->m_Depth = depth ? depth : 1;
|
||||
|
||||
if (this->GetFormatInfo().m_IsCompressed) {
|
||||
BLIZZARD_ASSERT(this->m_Depth == 1);
|
||||
|
||||
this->m_Width = (this->m_Width + 3) & 0xFFFC;
|
||||
this->m_Height = (this->m_Height + 3) & 0xFFFC;
|
||||
}
|
||||
|
||||
uint32_t v11 = this->GetFormatInfo().m_BytePerPixel;
|
||||
uint32_t v20 = this->m_Texture->var12 >> this->m_Level;
|
||||
|
||||
if (v20 >= v11) {
|
||||
v11 = v20;
|
||||
}
|
||||
|
||||
uint32_t v15 = v11 * this->m_Height;
|
||||
uint32_t v12;
|
||||
|
||||
if (this->GetFormatInfo().m_IsCompressed) {
|
||||
v12 = v15 >> 2;
|
||||
} else {
|
||||
v12 = v15;
|
||||
}
|
||||
|
||||
this->m_Size = this->m_Depth * v12;
|
||||
}
|
||||
|
||||
void GLMipmap::TexImage(const void* pixels) {
|
||||
BLIZZARD_ASSERT((this->m_Texture->IsRenderTarget() || pixels != nullptr) && GLDevice::Get()->GetVertexArrayStates().buffers[eGLBT_PIXEL_UNPACK] == 0);
|
||||
|
||||
if (this->m_Target == GL_TEXTURE_3D) {
|
||||
glTexImage3D(
|
||||
GL_TEXTURE_3D,
|
||||
this->m_Level,
|
||||
this->GetFormatInfo().m_InternalFormat,
|
||||
this->m_Width,
|
||||
this->m_Height,
|
||||
this->m_Depth,
|
||||
0,
|
||||
this->GetFormatInfo().m_DataFormat,
|
||||
this->GetFormatInfo().m_DataType,
|
||||
pixels
|
||||
);
|
||||
} else if (this->GetFormatInfo().m_IsCompressed) {
|
||||
glCompressedTexImage2D(
|
||||
this->m_Target,
|
||||
this->m_Level,
|
||||
this->GetFormatInfo().m_InternalFormat,
|
||||
this->m_Width,
|
||||
this->m_Height,
|
||||
0,
|
||||
this->m_Size,
|
||||
pixels
|
||||
);
|
||||
} else {
|
||||
glTexImage2D(
|
||||
this->m_Target,
|
||||
this->m_Level,
|
||||
this->GetFormatInfo().m_InternalFormat,
|
||||
this->m_Width,
|
||||
this->m_Height,
|
||||
0,
|
||||
this->GetFormatInfo().m_DataFormat,
|
||||
this->GetFormatInfo().m_DataType,
|
||||
pixels
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void GLMipmap::TexSubImage(const GLBox& a2, int32_t size, const void* pixels) {
|
||||
// TODO
|
||||
// BLIZZARD_ASSERT(!this->m_Texture->IsRenderTarget() && pixels != 0 && GLDevice::Get()->GetVertexArrayStates().buffers[eGLBT_PIXEL_UNPACK] == 0);
|
||||
|
||||
if (this->m_Target == GL_TEXTURE_3D) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, this->m_Width);
|
||||
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, this->m_Height);
|
||||
|
||||
glTexSubImage3D(
|
||||
this->m_Target,
|
||||
this->m_Level,
|
||||
a2.left,
|
||||
a2.top,
|
||||
a2.front,
|
||||
a2.width,
|
||||
a2.height,
|
||||
a2.depth,
|
||||
this->GetFormatInfo().m_DataFormat,
|
||||
this->GetFormatInfo().m_DataType,
|
||||
pixels
|
||||
);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
|
||||
} else if (this->GetFormatInfo().m_IsCompressed) {
|
||||
glCompressedTexSubImage2D(
|
||||
this->m_Target,
|
||||
this->m_Level,
|
||||
0,
|
||||
a2.top,
|
||||
this->m_Width,
|
||||
a2.height,
|
||||
this->GetFormatInfo().m_InternalFormat,
|
||||
size,
|
||||
pixels
|
||||
);
|
||||
} else {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, this->m_Width);
|
||||
|
||||
glTexSubImage2D(
|
||||
this->m_Target,
|
||||
this->m_Level,
|
||||
a2.left,
|
||||
a2.top,
|
||||
a2.width,
|
||||
a2.height,
|
||||
this->GetFormatInfo().m_DataFormat,
|
||||
this->GetFormatInfo().m_DataType,
|
||||
pixels
|
||||
);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void GLMipmap::Unmap() {
|
||||
BLIZZARD_ASSERT(!this->m_Texture->IsRenderTarget());
|
||||
BLIZZARD_ASSERT(!this->m_Texture->IsSystemBuffer());
|
||||
BLIZZARD_ASSERT(this->m_MapParams != nullptr);
|
||||
|
||||
if (this->m_MapParams->m_MapMode == GL_READ_ONLY) {
|
||||
delete this->m_MapParams;
|
||||
this->m_MapParams = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
GLDevice* device = GLDevice::Get();
|
||||
|
||||
BLIZZARD_ASSERT(this->m_Texture->m_MappedMipmaps > 0);
|
||||
|
||||
if (device->m_TexWorker) {
|
||||
device->m_TexWorker->Lock();
|
||||
|
||||
GLTexUnmap* command = new GLTexUnmap(this->m_Texture, this, this->m_MapParams);
|
||||
device->m_TexWorker->Send(command);
|
||||
device->m_TexWorker->Signal();
|
||||
|
||||
device->m_TexWorker->Unlock();
|
||||
} else {
|
||||
this->Unmap(this->m_MapParams);
|
||||
}
|
||||
|
||||
this->m_MapParams = nullptr;
|
||||
}
|
||||
|
||||
void GLMipmap::Unmap(MapParams* mapParams) {
|
||||
BLIZZARD_ASSERT(mapParams != nullptr);
|
||||
|
||||
this->m_Texture->Bind(nullptr, 0);
|
||||
|
||||
if (this->m_Unk24) {
|
||||
if (this->GetFormatInfo().m_IsCompressed) {
|
||||
GLBox area = {
|
||||
0,
|
||||
mapParams->m_MapArea.top,
|
||||
mapParams->m_MapArea.front,
|
||||
this->m_Width,
|
||||
mapParams->m_MapArea.height,
|
||||
mapParams->m_MapArea.depth
|
||||
};
|
||||
|
||||
this->TexSubImage(area, mapParams->m_Size, mapParams->m_Unk8);
|
||||
} else {
|
||||
this->TexSubImage(mapParams->m_MapArea, mapParams->m_Size, mapParams->m_Unk8 + mapParams->m_Unk7);
|
||||
}
|
||||
} else {
|
||||
this->TexImage(this->m_Data);
|
||||
this->m_Unk24 = 1;
|
||||
}
|
||||
|
||||
delete mapParams;
|
||||
|
||||
// TODO
|
||||
|
||||
this->m_Texture->m_MappedMipmaps--;
|
||||
}
|
||||
62
src/gx/gll/GLMipmap.h
Normal file
62
src/gx/gll/GLMipmap.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#ifndef GX_GLL_GL_MIPMAP_H
|
||||
#define GX_GLL_GL_MIPMAP_H
|
||||
|
||||
#include "gx/gll/GL.h"
|
||||
#include "gx/gll/GLTypes.h"
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
class GLFramebuffer;
|
||||
class GLTexture;
|
||||
|
||||
class GLMipmap {
|
||||
public:
|
||||
// Types
|
||||
struct MapParams {
|
||||
GLBox m_MapArea;
|
||||
int32_t m_MapMode = 0;
|
||||
int32_t m_Unk7 = 0;
|
||||
unsigned char* m_Unk8 = nullptr;
|
||||
int32_t m_Size = 0;
|
||||
};
|
||||
|
||||
// Member variables
|
||||
GLTexture* m_Texture = nullptr;
|
||||
uint16_t m_Width = 0;
|
||||
uint16_t m_Height = 0;
|
||||
uint16_t m_Depth = 0;
|
||||
uint8_t m_Level = 0;
|
||||
uint8_t m_DepthBits = 0;
|
||||
uint32_t m_Size = 0;
|
||||
int32_t m_Target = 0;
|
||||
unsigned char* m_Data = nullptr; // TODO proper type
|
||||
MapParams* m_MapParams = nullptr;
|
||||
std::vector<GLAttachPoint>* m_AttachPoints = nullptr;
|
||||
uint32_t m_Unk20 = 0;
|
||||
uint32_t m_Unk24 = 0;
|
||||
|
||||
// Member functions
|
||||
void Attach(GLFramebuffer*, GLenum, int32_t);
|
||||
void Detach(GLFramebuffer*, GLenum, bool);
|
||||
void DetachAll();
|
||||
int32_t GetDepthBits(void);
|
||||
GLTextureFormat GetFormat(void);
|
||||
TextureFormatInfo& GetFormatInfo(void);
|
||||
uint16_t GetHeight(void);
|
||||
int32_t GetPitch(void);
|
||||
GLTexture* GetTexture();
|
||||
uint32_t GetTextureID(void);
|
||||
uint16_t GetWidth(void);
|
||||
void* Map(GLEnum, const GLBox*);
|
||||
void* Map(GLEnum, const GLRect*);
|
||||
void ReleaseObject();
|
||||
void RemoveDebugMipmap();
|
||||
void ResetData(GLEnum, int32_t, unsigned char*);
|
||||
void ResetSize(uint32_t, uint32_t, uint32_t);
|
||||
void TexImage(const void*);
|
||||
void TexSubImage(const GLBox&, int32_t, const void*);
|
||||
void Unmap(void);
|
||||
void Unmap(MapParams*);
|
||||
};
|
||||
|
||||
#endif
|
||||
22
src/gx/gll/GLObject.cpp
Normal file
22
src/gx/gll/GLObject.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include "gx/gll/GLObject.h"
|
||||
#include "util/BlizzardCore.hpp"
|
||||
|
||||
void GLObject::AddRefTwin() {
|
||||
}
|
||||
|
||||
uint32_t GLObject::Release() {
|
||||
BLIZZARD_ASSERT(this->m_RefCount > 0);
|
||||
|
||||
this->m_RefCount--;
|
||||
|
||||
if (this->m_RefCount == 0) {
|
||||
this->ReleaseObject();
|
||||
}
|
||||
|
||||
this->ReleaseTwin();
|
||||
|
||||
return this->m_RefCount;
|
||||
}
|
||||
|
||||
void GLObject::ReleaseTwin() {
|
||||
}
|
||||
22
src/gx/gll/GLObject.h
Normal file
22
src/gx/gll/GLObject.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef GX_GLL_GL_OBJECT_H
|
||||
#define GX_GLL_GL_OBJECT_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class GLObject {
|
||||
public:
|
||||
// Member variables
|
||||
GLObject* m_Next;
|
||||
uint32_t m_RefCount;
|
||||
int64_t m_TimeStamp;
|
||||
|
||||
// Virtual member functions
|
||||
virtual void ReleaseObject() = 0;
|
||||
virtual void AddRefTwin();
|
||||
virtual void ReleaseTwin();
|
||||
|
||||
// Member functions
|
||||
uint32_t Release();
|
||||
};
|
||||
|
||||
#endif
|
||||
17
src/gx/gll/GLPixelShader.cpp
Normal file
17
src/gx/gll/GLPixelShader.cpp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#include "gx/gll/GLPixelShader.h"
|
||||
#include "gx/gll/GL.h"
|
||||
|
||||
GLPixelShader* GLPixelShader::Create() {
|
||||
// TODO
|
||||
// GLPool stuff
|
||||
|
||||
GLPixelShader* shader = new GLPixelShader();
|
||||
|
||||
shader->m_ShaderID = 0;
|
||||
shader->m_RefCount = 1;
|
||||
shader->m_ShaderType = ePixelShader;
|
||||
shader->m_UsingGLSL = 0;
|
||||
shader->var5 = GL_FRAGMENT_PROGRAM_ARB;
|
||||
|
||||
return shader;
|
||||
}
|
||||
12
src/gx/gll/GLPixelShader.h
Normal file
12
src/gx/gll/GLPixelShader.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef GX_GLL_GL_PIXEL_SHADER_H
|
||||
#define GX_GLL_GL_PIXEL_SHADER_H
|
||||
|
||||
#include "gx/gll/GLShader.h"
|
||||
|
||||
class GLPixelShader : public GLShader {
|
||||
public:
|
||||
// Static functions
|
||||
static GLPixelShader* Create(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
57
src/gx/gll/GLPool.h
Normal file
57
src/gx/gll/GLPool.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef GX_GLL_GL_POOL_H
|
||||
#define GX_GLL_GL_POOL_H
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
template<class T>
|
||||
class GLPool {
|
||||
public:
|
||||
// Static variables
|
||||
static GLPool<T>* m_pool;
|
||||
|
||||
// Static functions
|
||||
static GLPool<T>* Get(void);
|
||||
static void Init(void);
|
||||
|
||||
// Member variables
|
||||
std::atomic<uint32_t> m_NextName;
|
||||
|
||||
// Member functions
|
||||
uint32_t GetNextName(void);
|
||||
T* GetNextObject(void);
|
||||
void SetNextName(uint32_t);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
GLPool<T>* GLPool<T>::m_pool;
|
||||
|
||||
template<class T>
|
||||
GLPool<T>* GLPool<T>::Get() {
|
||||
return GLPool<T>::m_pool;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void GLPool<T>::Init() {
|
||||
GLPool<T>::m_pool = new GLPool<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
uint32_t GLPool<T>::GetNextName() {
|
||||
return this->m_NextName++;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T* GLPool<T>::GetNextObject() {
|
||||
// TODO
|
||||
// - pop off of GLObjectPool
|
||||
|
||||
return new T();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void GLPool<T>::SetNextName(uint32_t name) {
|
||||
this->m_NextName = name;
|
||||
}
|
||||
|
||||
#endif
|
||||
133
src/gx/gll/GLShader.cpp
Normal file
133
src/gx/gll/GLShader.cpp
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
#include "gx/gll/GLShader.h"
|
||||
#include "gx/gll/GLDevice.h"
|
||||
#include "gx/gll/GLPixelShader.h"
|
||||
#include "gx/gll/GLPool.h"
|
||||
#include "gx/gll/GLVertexShader.h"
|
||||
|
||||
// TODO
|
||||
// - threaded compiler support
|
||||
// - glsl support
|
||||
// - hybrid support
|
||||
GLShader* GLShader::Create(ShaderType shaderType, bool hybrid, bool usingCG, const char* a4, const void* buf, int32_t codeLen, const char* a7, const char* name, GLShaderLogInfo* logInfo) {
|
||||
const char* shaderCode = reinterpret_cast<const char*>(buf);
|
||||
|
||||
if (*reinterpret_cast<const int32_t*>(buf) == 'GSL1') {
|
||||
BLIZZARD_ASSERT(!usingCG);
|
||||
|
||||
const ShaderDataHeader header = *reinterpret_cast<const ShaderDataHeader*>(buf);
|
||||
|
||||
BLIZZARD_ASSERT(header.shaderType == shaderType);
|
||||
BLIZZARD_ASSERT(header.size == codeLen);
|
||||
BLIZZARD_ASSERT(header.codePos >= sizeof(ShaderDataHeader));
|
||||
BLIZZARD_ASSERT(header.codeSize > 0);
|
||||
|
||||
shaderCode = &reinterpret_cast<const char*>(buf)[header.codePos];
|
||||
}
|
||||
|
||||
GLShader* shader = nullptr;
|
||||
|
||||
if (shaderType == ePixelShader) {
|
||||
shader = GLPixelShader::Create();
|
||||
} else if (shaderType == eVertexShader) {
|
||||
shader = GLVertexShader::Create();
|
||||
} else {
|
||||
// TODO
|
||||
// sub_1C5E0(&v38, "Unknown shader type %d!", shaderType);
|
||||
}
|
||||
|
||||
shader->m_UsingCG = usingCG;
|
||||
|
||||
if (usingCG) {
|
||||
shader->CompileCG(a4, shaderCode, codeLen, a7, logInfo);
|
||||
} else {
|
||||
shader->m_Code.assign(shaderCode, codeLen);
|
||||
|
||||
// TODO
|
||||
// sub_5CD10(shader);
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
bool GLShader::CheckErrorsARB(GLShaderLogInfo* logInfo) {
|
||||
GLint errorPos;
|
||||
|
||||
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
|
||||
const GLubyte* errorStr = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
|
||||
|
||||
// TODO
|
||||
// Blizzard::Debug::VAssert(logInfo != 0 || errorPos == -1, errorStr);
|
||||
|
||||
return errorPos == -1;
|
||||
}
|
||||
|
||||
void GLShader::Compile(GLShaderLogInfo* logInfo) {
|
||||
this->ImmediateCompile(logInfo);
|
||||
}
|
||||
|
||||
void GLShader::CompileCG(const char* a2, const void* shaderCode, int32_t codeLen, const char* a5, GLShaderLogInfo* logInfo) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void GLShader::FlushUniforms(GLGLSLProgram* program) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
std::string& GLShader::GetCode() {
|
||||
return this->m_Code;
|
||||
}
|
||||
|
||||
int32_t GLShader::GetShaderType() {
|
||||
return this->m_ShaderType;
|
||||
}
|
||||
|
||||
void GLShader::ImmediateCompile(GLShaderLogInfo* logInfo) {
|
||||
BLIZZARD_ASSERT(!this->GetCode().empty());
|
||||
|
||||
this->m_Device = GLDevice::Get();
|
||||
|
||||
if (!this->m_UsingGLSL) {
|
||||
if (!this->m_ShaderID) {
|
||||
if (this->m_ShaderType == eVertexShader) {
|
||||
this->m_ShaderID = GLPool<GLVertexShader>::Get()->GetNextName();
|
||||
} else {
|
||||
this->m_ShaderID = GLPool<GLPixelShader>::Get()->GetNextName();
|
||||
}
|
||||
}
|
||||
|
||||
this->m_Device->BindShader(this);
|
||||
|
||||
const char* arbCode = this->GetCode().c_str();
|
||||
size_t arbLen = strlen(arbCode);
|
||||
|
||||
glProgramStringARB(this->var5, GL_PROGRAM_FORMAT_ASCII_ARB, arbLen, arbCode);
|
||||
|
||||
BLIZZARD_ASSERT(this->CheckErrorsARB(logInfo));
|
||||
} else {
|
||||
// TODO
|
||||
// - handle GLSL shaders
|
||||
// - handle hybrid shaders
|
||||
}
|
||||
|
||||
if (logInfo) {
|
||||
// TODO
|
||||
// this->var20 = logInfo[0];
|
||||
} else {
|
||||
this->var20 = 1;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// this->m_TimeStamp = Blizzard::Time::GetTimestamp();
|
||||
}
|
||||
|
||||
bool GLShader::IsEnabled() {
|
||||
return this->m_Enabled;
|
||||
}
|
||||
|
||||
void GLShader::ReleaseObject() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void GLShader::SetShaderConstants(ShaderType shaderType, uint32_t index, const float* constants, uint32_t count) {
|
||||
// TODO
|
||||
}
|
||||
75
src/gx/gll/GLShader.h
Normal file
75
src/gx/gll/GLShader.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#ifndef GX_GLL_GL_SHADER_H
|
||||
#define GX_GLL_GL_SHADER_H
|
||||
|
||||
#include "gx/gll/GLObject.h"
|
||||
#include "gx/gll/GLShaderInput.h"
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class GLDevice;
|
||||
class GLGLSLProgram;
|
||||
class GLShaderLogInfo;
|
||||
|
||||
class GLShader : public GLObject {
|
||||
public:
|
||||
// Types
|
||||
enum ShaderType {
|
||||
eVertexShader = 1,
|
||||
ePixelShader = 2,
|
||||
eShaderTypeCount = 3
|
||||
};
|
||||
|
||||
struct ShaderDataHeader {
|
||||
uint32_t signature;
|
||||
uint32_t size;
|
||||
ShaderType shaderType;
|
||||
uint32_t codePos;
|
||||
uint32_t codeSize;
|
||||
uint32_t unk1;
|
||||
uint32_t unk2;
|
||||
uint32_t unk3;
|
||||
};
|
||||
|
||||
// Static functions
|
||||
static GLShader* Create(ShaderType, bool, bool, const char*, const void*, int32_t, const char*, const char*, GLShaderLogInfo*);
|
||||
|
||||
// Member variables
|
||||
int32_t m_ShaderType = 0;
|
||||
int32_t var5 = 0;
|
||||
uint32_t m_ShaderID = 0;
|
||||
bool m_UsingCG = false;
|
||||
bool m_UsingGLSL = false;
|
||||
uint32_t m_UniformRegisterCount = 0;
|
||||
GLShaderInput** var10 = nullptr;
|
||||
float* var11 = nullptr;
|
||||
bool var12 = false;
|
||||
uint32_t var13 = 0;
|
||||
uint32_t var14 = 0;
|
||||
std::vector<GLShaderInput*, std::allocator<GLShaderInput*>> var15;
|
||||
std::vector<GLShaderInput*, std::allocator<GLShaderInput*>> var16;
|
||||
std::vector<GLShaderInput*, std::allocator<GLShaderInput*>> var17;
|
||||
GLShader* var18 = nullptr;
|
||||
GLDevice* m_Device = nullptr;
|
||||
bool var20 = 0;
|
||||
bool m_Enabled = true;
|
||||
std::basic_string<char, std::char_traits<char>, std::allocator<char>> m_Code;
|
||||
std::basic_string<char, std::char_traits<char>, std::allocator<char>> var23;
|
||||
|
||||
// Virtual member functions
|
||||
virtual void ReleaseObject();
|
||||
|
||||
// Member functions
|
||||
bool CheckErrorsARB(GLShaderLogInfo*);
|
||||
bool CheckErrorsGLSL(GLShaderLogInfo*);
|
||||
void Compile(GLShaderLogInfo*);
|
||||
void CompileCG(const char*, const void*, int32_t, const char*, GLShaderLogInfo*);
|
||||
void FlushUniforms(GLGLSLProgram*);
|
||||
std::string& GetCode(void);
|
||||
int32_t GetShaderType(void);
|
||||
void ImmediateCompile(GLShaderLogInfo*);
|
||||
bool IsEnabled(void);
|
||||
void SetShaderConstants(ShaderType, uint32_t, const float*, uint32_t);
|
||||
};
|
||||
|
||||
#endif
|
||||
33
src/gx/gll/GLShaderInput.h
Normal file
33
src/gx/gll/GLShaderInput.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef GX_GLL_GL_SHADER_INPUT_H
|
||||
#define GX_GLL_GL_SHADER_INPUT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class GLShader;
|
||||
|
||||
class GLShaderInput {
|
||||
public:
|
||||
// Member variables
|
||||
GLShader *m_Shader;
|
||||
std::basic_string<char, std::char_traits<char>, std::allocator<char>> m_Name;
|
||||
std::basic_string<char, std::char_traits<char>, std::allocator<char>> var2;
|
||||
int16_t m_MapIndex;
|
||||
int16_t var4;
|
||||
int16_t var5;
|
||||
int16_t m_UsedSize;
|
||||
int16_t var7;
|
||||
int16_t var8;
|
||||
GLShaderInput *m_Parent;
|
||||
int32_t var10;
|
||||
int32_t var11;
|
||||
int32_t var12;
|
||||
int8_t m_ChildrenCount;
|
||||
int8_t var14;
|
||||
uint16_t var15;
|
||||
int8_t var16;
|
||||
int8_t m_Variability;
|
||||
int8_t var18;
|
||||
int8_t var19;
|
||||
};
|
||||
|
||||
#endif
|
||||
659
src/gx/gll/GLTexture.cpp
Normal file
659
src/gx/gll/GLTexture.cpp
Normal file
|
|
@ -0,0 +1,659 @@
|
|||
#include "gx/gll/GLTexture.h"
|
||||
#include "gx/gll/GLCommand.h"
|
||||
#include "gx/gll/GLDevice.h"
|
||||
#include "gx/gll/GLPool.h"
|
||||
#include "gx/gll/GLUtil.h"
|
||||
#include "gx/texture/CGxTex.hpp"
|
||||
#include <deque>
|
||||
|
||||
Blizzard::Thread::TLSSlot GLTexture::m_Bindings[4];
|
||||
|
||||
void* GLTexture::CreateBindings(void* ptr) {
|
||||
return new std::deque<std::vector<Binding>>;
|
||||
}
|
||||
|
||||
void GLTexture::DestroyBindings(void* ptr) {
|
||||
delete static_cast<std::deque<std::vector<Binding>>*>(ptr);
|
||||
}
|
||||
|
||||
void GLTexture::Bind(GLDevice* device, bool force) {
|
||||
BLIZZARD_ASSERT(!this->IsSystemBuffer());
|
||||
BLIZZARD_ASSERT(this->m_Depth != 0);
|
||||
|
||||
if (!device) {
|
||||
device = GLDevice::Get();
|
||||
}
|
||||
|
||||
BLIZZARD_ASSERT(device != nullptr);
|
||||
|
||||
auto& bindings = this->GetBindings();
|
||||
uint32_t deviceID = device->GetID();
|
||||
|
||||
if (deviceID >= bindings.size()) {
|
||||
bindings.resize(deviceID + 1);
|
||||
}
|
||||
|
||||
bindings[deviceID].device = device;
|
||||
|
||||
uint32_t currentActiveTexture = device->m_States.binding.currentActiveTexture;
|
||||
|
||||
if (bindings[deviceID].boundStages[currentActiveTexture]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (force) {
|
||||
bindings[deviceID].boundStages[currentActiveTexture] = 1;
|
||||
device->BindTexture(this->m_TextureType, this);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < 16; i++) {
|
||||
if (bindings[deviceID].boundStages[i]) {
|
||||
device->SetActiveTexture(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bindings[deviceID].boundStages[currentActiveTexture] = 1;
|
||||
device->BindTexture(this->m_TextureType, this);
|
||||
}
|
||||
|
||||
void GLTexture::FreeTexture() {
|
||||
auto device = GLDevice::Get();
|
||||
|
||||
if (device->m_TexWorker) {
|
||||
// TODO
|
||||
|
||||
this->m_LastFrameUsed = 0;
|
||||
|
||||
int32_t numFace = this->m_TextureType == GL_TEXTURE_CUBE_MAP ? 6 : 1;
|
||||
for (int32_t face = 0; face < numFace; face++) {
|
||||
for (int32_t level = 0; level < this->m_NumMipmap; level++) {
|
||||
this->m_Mipmaps[face][level].ReleaseObject();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO this->Sub690D0();
|
||||
// TODO device->m_TexWorker->Sub72340(this);
|
||||
|
||||
device->m_TexWorker->Lock();
|
||||
|
||||
auto command = new GLTexDestroy(this);
|
||||
device->m_TexWorker->Send(command);
|
||||
device->m_TexWorker->Signal();
|
||||
|
||||
device->m_TexWorker->Unlock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t numFace = this->m_TextureType == GL_TEXTURE_CUBE_MAP ? 6 : 1;
|
||||
for (int32_t face = 0; face < numFace; face++) {
|
||||
if (this->m_Mipmaps[face]) {
|
||||
delete[] this->m_Mipmaps[face];
|
||||
}
|
||||
}
|
||||
|
||||
if (this->m_Mipmaps) {
|
||||
delete[] this->m_Mipmaps;
|
||||
}
|
||||
|
||||
this->m_Mipmaps = nullptr;
|
||||
this->m_Depth = 0;
|
||||
|
||||
// TODO this->Sub690D0();
|
||||
|
||||
glDeleteTextures(1, &this->m_TextureID);
|
||||
|
||||
this->m_GenerateMipmaps = 0;
|
||||
this->m_MaxMipmapLevel = 1000;
|
||||
this->m_BaseMipmapLevel = 0;
|
||||
this->m_CompareMode = 0;
|
||||
|
||||
this->m_Sampler.mipmapBias = 0.0f;
|
||||
this->m_Sampler.borderColor = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
this->m_Sampler.addressModeS = GL_REPEAT;
|
||||
this->m_Sampler.addressModeT = GL_REPEAT;
|
||||
this->m_Sampler.addressModeR = GL_REPEAT;
|
||||
this->m_Sampler.magFilterMode = GL_LINEAR;
|
||||
this->m_Sampler.minFilterMode = GL_NEAREST_MIPMAP_LINEAR;
|
||||
this->m_Sampler.maxAnisotropy = 1.0f;
|
||||
|
||||
Blizzard::Memory::Free(this->m_Data);
|
||||
this->m_Data = nullptr;
|
||||
|
||||
switch (this->m_TextureType) {
|
||||
case GL_TEXTURE_3D:
|
||||
// TODO GLPool<GLTexture3D>::GLObjectPool::Push(GLPool<GLTexture3D>::m_pool + 264, this);
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
// TODO GLPool<GLTextureCubeMap>::GLObjectPool::Push(GLPool<GLTextureCubeMap>::m_pool + 520, this);
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_2D:
|
||||
// TODO GLPool<GLTexture2D>::GLObjectPool::Push(GLPool<GLTexture2D>::m_pool + 131080, this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<GLTexture::Binding>& GLTexture::GetBindings() {
|
||||
uint32_t index = GLLTextureTypeToIndex(this->m_TextureType);
|
||||
|
||||
uint32_t id;
|
||||
|
||||
if (index == 0) {
|
||||
id = this->m_TextureID - 33;
|
||||
} else if (index == 1) {
|
||||
id = this->m_TextureID - 32801;
|
||||
} else if (index == 2) {
|
||||
id = this->m_TextureID - 32865;
|
||||
} else if (index == 3) {
|
||||
id = this->m_TextureID - 1;
|
||||
}
|
||||
|
||||
auto target = static_cast<std::deque<std::vector<Binding>>*>(
|
||||
Blizzard::Thread::RegisterLocalStorage(
|
||||
&GLTexture::m_Bindings[index],
|
||||
GLTexture::CreateBindings,
|
||||
nullptr,
|
||||
GLTexture::DestroyBindings
|
||||
)
|
||||
);
|
||||
|
||||
if (id >= target->size()) {
|
||||
target->resize(id + 1);
|
||||
}
|
||||
|
||||
return (*target)[id];
|
||||
}
|
||||
|
||||
GLTextureFormat GLTexture::GetFormat() {
|
||||
return this->m_Format;
|
||||
}
|
||||
|
||||
TextureFormatInfo& GLTexture::GetFormatInfo() {
|
||||
return k_TextureFormatInfo[this->m_Format];
|
||||
}
|
||||
|
||||
GLMipmap* GLTexture::GetMipmap(uint32_t level, GLEnum face) {
|
||||
BLIZZARD_ASSERT(face >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
|
||||
BLIZZARD_ASSERT(level < this->m_NumMipmap);
|
||||
BLIZZARD_ASSERT(this->m_Mipmaps != nullptr);
|
||||
BLIZZARD_ASSERT(this->m_Mipmaps[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X] != nullptr);
|
||||
|
||||
return &this->m_Mipmaps[face - GL_TEXTURE_CUBE_MAP_POSITIVE_X][level];
|
||||
}
|
||||
|
||||
bool GLTexture::IsRenderTarget() {
|
||||
return this->m_Flags & GLTFLAG_RENDERTARGET;
|
||||
}
|
||||
|
||||
bool GLTexture::IsSystemBuffer() {
|
||||
return this->m_Flags & GLTFLAG_SYSTEM_BUFFER;
|
||||
}
|
||||
|
||||
bool GLTexture::IsValid() {
|
||||
return this->m_Depth;
|
||||
}
|
||||
|
||||
void* GLTexture::Map(uint32_t level, const GLRect* a3, uint32_t& a4, GLEnum a5) {
|
||||
BLIZZARD_ASSERT(this->m_TextureType != GL_TEXTURE_3D);
|
||||
|
||||
auto mipmap = this->GetMipmap(level, GL_TEXTURE_CUBE_MAP_POSITIVE_X);
|
||||
a4 = mipmap->GetPitch();
|
||||
return mipmap->Map(a5, a3);
|
||||
}
|
||||
|
||||
void GLTexture::RecreateGLTexture() {
|
||||
BLIZZARD_ASSERT(GLDevice::Get()->m_TexWorker != nullptr);
|
||||
|
||||
if (this->m_TextureType == GL_TEXTURE_RECTANGLE_EXT) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isCubeMap = this->m_TextureType == GL_TEXTURE_CUBE_MAP;
|
||||
int32_t numFace = isCubeMap ? 6 : 1;
|
||||
|
||||
for (int32_t face = 0; face < numFace; face++) {
|
||||
for (int32_t level = 0; level < this->m_NumMipmap; level++) {
|
||||
this->m_Mipmaps[face][level].Map(GL_WRITE_ONLY, static_cast<GLBox*>(nullptr));
|
||||
this->m_Mipmaps[face][level].Unmap();
|
||||
}
|
||||
}
|
||||
|
||||
glTexParameterf(this->m_TextureType, GL_TEXTURE_LOD_BIAS, this->m_Sampler.mipmapBias);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_WRAP_S, this->m_Sampler.addressModeS);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_WRAP_T, this->m_Sampler.addressModeT);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_WRAP_R, this->m_Sampler.addressModeR);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_MIN_FILTER, this->m_Sampler.minFilterMode);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_MAG_FILTER, this->m_Sampler.magFilterMode);
|
||||
glTexParameterf(this->m_TextureType, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->m_Sampler.maxAnisotropy);
|
||||
glTexParameterfv(this->m_TextureType, GL_TEXTURE_BORDER_COLOR, reinterpret_cast<GLfloat*>(&this->m_Sampler.borderColor));
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_MAX_LEVEL, this->m_MaxMipmapLevel);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_BASE_LEVEL, this->m_BaseMipmapLevel);
|
||||
glTexParameteri(this->m_TextureType, GL_GENERATE_MIPMAP, this->m_GenerateMipmaps);
|
||||
}
|
||||
|
||||
void GLTexture::ResizeMipmaps() {
|
||||
BLIZZARD_ASSERT(this->m_Mipmaps == nullptr);
|
||||
|
||||
int32_t numFace = this->m_TextureType == GL_TEXTURE_CUBE_MAP ? 6 : 1;
|
||||
|
||||
this->m_Mipmaps = new GLMipmap*[numFace];
|
||||
|
||||
for (int32_t face = 0; face < numFace; face++) {
|
||||
this->m_Mipmaps[face] = new GLMipmap[this->m_NumMipmap];
|
||||
}
|
||||
}
|
||||
|
||||
void GLTexture::SetAddressModeR(GLEnum mode) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void GLTexture::SetAddressModeS(GLEnum mode) {
|
||||
if (this->m_Sampler.addressModeS == mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == GL_CLAMP_TO_EDGE) {
|
||||
this->Bind(nullptr, 0);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_WRAP_S, mode);
|
||||
this->m_Sampler.addressModeS = mode;
|
||||
} else {
|
||||
// Workaround for buggy GPU (possibly ATI Radeon X1900)
|
||||
if (GLDevice::GetRendererInfo().renderer_id == 0x21900) {
|
||||
if (this->m_Width & (this->m_Width - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_Height & (this->m_Height - 1)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->Bind(nullptr, 0);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_WRAP_S, mode);
|
||||
this->m_Sampler.addressModeS = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void GLTexture::SetAddressModeT(GLEnum mode) {
|
||||
if (this->m_Sampler.addressModeT == mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == GL_CLAMP_TO_EDGE) {
|
||||
this->Bind(nullptr, 0);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_WRAP_T, mode);
|
||||
this->m_Sampler.addressModeT = mode;
|
||||
} else {
|
||||
// Workaround for buggy GPU (possibly ATI Radeon X1900)
|
||||
if (GLDevice::GetRendererInfo().renderer_id == 0x21900) {
|
||||
if (this->m_Width & (this->m_Width - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_Height & (this->m_Height - 1)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->Bind(nullptr, 0);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_WRAP_T, mode);
|
||||
this->m_Sampler.addressModeT = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void GLTexture::SetBorderColor(const GLColor4f& color) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void GLTexture::SetCompareMode(GLEnum compareMode) {
|
||||
BLIZZARD_ASSERT(
|
||||
this->GetFormatInfo().m_DataFormat == GL_DEPTH_COMPONENT
|
||||
|| this->GetFormatInfo().m_DataFormat == GL_DEPTH_STENCIL_EXT
|
||||
|| compareMode == GL_NONE
|
||||
);
|
||||
|
||||
if (this->m_CompareMode != compareMode) {
|
||||
this->Bind(nullptr, 0);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_COMPARE_MODE, compareMode);
|
||||
this->m_CompareMode = compareMode;
|
||||
}
|
||||
}
|
||||
|
||||
void GLTexture::SetMagFilterMode(GLEnum mode) {
|
||||
if (this->m_Sampler.magFilterMode == mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GLDevice::GetRendererInfo().vendor_id == 2 && this->IsRenderTarget() && mode != GL_LINEAR) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->Bind(nullptr, 0);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_MAG_FILTER, mode);
|
||||
this->m_Sampler.magFilterMode = mode;
|
||||
}
|
||||
|
||||
void GLTexture::SetMaxAnisotropy(int32_t maxAnisotropy) {
|
||||
if (this->m_Sampler.maxAnisotropy == maxAnisotropy) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->Bind(nullptr, 0);
|
||||
glTexParameterf(this->m_TextureType, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy);
|
||||
this->m_Sampler.maxAnisotropy = maxAnisotropy;
|
||||
}
|
||||
|
||||
void GLTexture::SetMinFilterMode(GLEnum mode) {
|
||||
if (this->m_Sampler.minFilterMode == mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GLDevice::GetRendererInfo().vendor_id == 2 && this->IsRenderTarget() && mode != GL_LINEAR) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->Bind(nullptr, 0);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_MIN_FILTER, mode);
|
||||
this->m_Sampler.minFilterMode = mode;
|
||||
}
|
||||
|
||||
void GLTexture::SetupTexture() {
|
||||
BLIZZARD_ASSERT(this->m_NumMipmap == 1 || (this->m_Flags & GLTFLAG_AUTOGEN_MIPMAP) == 0);
|
||||
BLIZZARD_ASSERT(!this->IsRenderTarget() || this->m_NumMipmap == 1);
|
||||
BLIZZARD_ASSERT(!this->IsRenderTarget() || (this->m_Flags & GLTFLAG_READ_ACCESS) == 0);
|
||||
|
||||
GLDevice* device = GLDevice::Get();
|
||||
|
||||
if (this->GetFormatInfo().m_IsCompressed) {
|
||||
int32_t smallestDim = std::min(this->m_Width, this->m_Height);
|
||||
|
||||
BLIZZARD_ASSERT(smallestDim >= 4);
|
||||
|
||||
if (smallestDim == 4) {
|
||||
this->m_NumMipmap = 1;
|
||||
} else if (smallestDim == 8) {
|
||||
this->m_NumMipmap = 2;
|
||||
} else if (smallestDim == 16) {
|
||||
this->m_NumMipmap = 3;
|
||||
} else if (smallestDim == 32) {
|
||||
this->m_NumMipmap = 4;
|
||||
} else if (smallestDim == 64) {
|
||||
this->m_NumMipmap = 5;
|
||||
} else if (smallestDim == 128) {
|
||||
this->m_NumMipmap = 6;
|
||||
} else if (smallestDim == 256) {
|
||||
this->m_NumMipmap = 7;
|
||||
} else if (smallestDim == 512) {
|
||||
this->m_NumMipmap = 8;
|
||||
} else if (smallestDim == 1024) {
|
||||
this->m_NumMipmap = 9;
|
||||
} else if (smallestDim == 2048) {
|
||||
this->m_NumMipmap = 10;
|
||||
} else if (smallestDim == 4096) {
|
||||
this->m_NumMipmap = 11;
|
||||
} else {
|
||||
int32_t i = smallestDim >> 1;
|
||||
int32_t n = 0;
|
||||
|
||||
while (i) {
|
||||
i >>= 1;
|
||||
n++;
|
||||
}
|
||||
|
||||
this->m_NumMipmap = n - 1;
|
||||
}
|
||||
} else {
|
||||
int32_t largestDim = std::max(this->m_Width, this->m_Height);
|
||||
|
||||
if (largestDim == 1) {
|
||||
this->m_NumMipmap = 1;
|
||||
} else if (largestDim == 2) {
|
||||
this->m_NumMipmap = 2;
|
||||
} else if (largestDim == 4) {
|
||||
this->m_NumMipmap = 3;
|
||||
} else if (largestDim == 8) {
|
||||
this->m_NumMipmap = 4;
|
||||
} else if (largestDim == 16) {
|
||||
this->m_NumMipmap = 5;
|
||||
} else if (largestDim == 32) {
|
||||
this->m_NumMipmap = 6;
|
||||
} else if (largestDim == 64) {
|
||||
this->m_NumMipmap = 7;
|
||||
} else if (largestDim == 128) {
|
||||
this->m_NumMipmap = 8;
|
||||
} else if (largestDim == 256) {
|
||||
this->m_NumMipmap = 9;
|
||||
} else if (largestDim == 512) {
|
||||
this->m_NumMipmap = 10;
|
||||
} else if (largestDim == 1024) {
|
||||
this->m_NumMipmap = 11;
|
||||
} else if (largestDim == 2048) {
|
||||
this->m_NumMipmap = 12;
|
||||
} else if (largestDim == 4096) {
|
||||
this->m_NumMipmap = 13;
|
||||
} else {
|
||||
int32_t i = largestDim >> 1;
|
||||
int32_t n = 0;
|
||||
|
||||
while (i) {
|
||||
i >>= 1;
|
||||
n++;
|
||||
}
|
||||
|
||||
this->m_NumMipmap = n + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(this->m_Flags & GLTFLAG_SYSTEM_BUFFER)) {
|
||||
BLIZZARD_ASSERT(this->m_RequestedNumMipmaps != 0);
|
||||
|
||||
this->m_NumMipmap = std::min(this->m_NumMipmap, this->m_RequestedNumMipmaps);
|
||||
}
|
||||
|
||||
this->var12 = this->GetFormatInfo().m_BytePerPixel * this->m_Width;
|
||||
if (this->GetFormatInfo().m_IsCompressed) {
|
||||
this->var12 >>= 2;
|
||||
}
|
||||
|
||||
this->ResizeMipmaps();
|
||||
|
||||
bool isCubeMap = this->m_TextureType == GL_TEXTURE_CUBE_MAP;
|
||||
|
||||
this->m_Size = 0;
|
||||
|
||||
int32_t numFace = isCubeMap ? 6 : 1;
|
||||
|
||||
for (int32_t face = 0; face < numFace; face++) {
|
||||
for (int32_t level = 0; level < this->m_NumMipmap; level++) {
|
||||
GLMipmap* mip = this->GetMipmap(level, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face);
|
||||
|
||||
mip->m_Level = level;
|
||||
mip->m_Texture = this;
|
||||
mip->ResetSize(this->m_Width >> level, this->m_Height >> level, this->m_Depth >> level);
|
||||
|
||||
this->m_Size += mip->m_Size;
|
||||
}
|
||||
}
|
||||
|
||||
this->var7 = GLDevice::m_Devices[0]->m_TextureList.begin();
|
||||
|
||||
if (this->m_Flags & GLTFLAG_SYSTEM_BUFFER) {
|
||||
return;
|
||||
}
|
||||
|
||||
BLIZZARD_ASSERT(this->m_Data == nullptr);
|
||||
|
||||
if (!this->IsRenderTarget()) {
|
||||
this->m_Data = static_cast<char*>(Blizzard::Memory::Allocate(this->m_Size));
|
||||
}
|
||||
|
||||
this->Bind(nullptr, 0);
|
||||
|
||||
if (this->IsRenderTarget()) {
|
||||
this->SetAddressModeR(GL_CLAMP_TO_EDGE);
|
||||
this->SetAddressModeS(GL_CLAMP_TO_EDGE);
|
||||
this->SetAddressModeT(GL_CLAMP_TO_EDGE);
|
||||
this->SetMinFilterMode(GL_LINEAR);
|
||||
this->SetMagFilterMode(GL_LINEAR);
|
||||
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE);
|
||||
} else {
|
||||
this->SetAddressModeR(GL_REPEAT);
|
||||
this->SetAddressModeS(GL_REPEAT);
|
||||
this->SetAddressModeT(GL_REPEAT);
|
||||
this->SetMinFilterMode(GL_NEAREST_MIPMAP_NEAREST);
|
||||
this->SetMagFilterMode(GL_NEAREST);
|
||||
}
|
||||
|
||||
if (this->GetFormatInfo().m_DataFormat == GL_DEPTH_COMPONENT || this->GetFormatInfo().m_DataFormat == GL_DEPTH_STENCIL) {
|
||||
this->SetCompareMode(GLDevice::m_ExtARBShadow >= 1 ? GL_COMPARE_R_TO_TEXTURE : 0);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
||||
glTexParameteri(this->m_TextureType, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
|
||||
} else {
|
||||
this->SetCompareMode(0);
|
||||
}
|
||||
|
||||
this->SetMaxAnisotropy(1);
|
||||
|
||||
this->SetBorderColor(GLColor4f::ZERO);
|
||||
|
||||
int32_t autogenMipmap = this->m_Flags & GLTFLAG_AUTOGEN_MIPMAP;
|
||||
if (autogenMipmap != this->m_GenerateMipmaps) {
|
||||
this->Bind(nullptr, 0);
|
||||
glTexParameteri(this->m_TextureType, GL_GENERATE_MIPMAP, autogenMipmap);
|
||||
this->m_GenerateMipmaps = autogenMipmap;
|
||||
}
|
||||
|
||||
int32_t maxMipmapLevel = this->m_NumMipmap - 1;
|
||||
if (maxMipmapLevel != this->m_MaxMipmapLevel) {
|
||||
this->Bind(nullptr, 0);
|
||||
glTexParameteri(this->m_TextureType, GL_TEXTURE_MAX_LEVEL, maxMipmapLevel);
|
||||
this->m_MaxMipmapLevel = maxMipmapLevel;
|
||||
}
|
||||
|
||||
if (this->m_TextureType == GL_TEXTURE_RECTANGLE_EXT) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->IsRenderTarget()) {
|
||||
device->SetUnpackClientStorage(0);
|
||||
}
|
||||
|
||||
unsigned char* data = reinterpret_cast<unsigned char*>(this->m_Data);
|
||||
|
||||
for (int32_t face = 0; face < numFace; face++) {
|
||||
for (int32_t level = 0; level < this->m_NumMipmap; level++) {
|
||||
GLMipmap* mip = this->GetMipmap(level, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face);
|
||||
|
||||
if (this->m_TextureType == GL_TEXTURE_CUBE_MAP) {
|
||||
mip->ResetData(face, level, data);
|
||||
} else {
|
||||
mip->ResetData(this->m_TextureType, level, data);
|
||||
}
|
||||
|
||||
if (data) {
|
||||
data += mip->m_Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// this->m_TimeStamp = Blizzard::Time::GetTimestamp();
|
||||
|
||||
if (this->IsRenderTarget()) {
|
||||
device->SetUnpackClientStorage(1);
|
||||
}
|
||||
}
|
||||
|
||||
void GLTexture::Unbind(GLDevice* device, uint32_t stage) {
|
||||
auto& bindings = this->GetBindings();
|
||||
|
||||
BLIZZARD_ASSERT(device->GetID() < bindings.size());
|
||||
BLIZZARD_ASSERT(bindings[device->GetID()].device == device);
|
||||
BLIZZARD_ASSERT(bindings[device->GetID()].boundStages[stage]);
|
||||
|
||||
bindings[device->GetID()].boundStages[stage] = 0;
|
||||
}
|
||||
|
||||
void GLTexture::Unmap(uint32_t level, GLEnum face) {
|
||||
auto mipmap = this->GetMipmap(level, face);
|
||||
mipmap->Unmap();
|
||||
}
|
||||
|
||||
GLTexture2D* GLTexture2D::Create(uint32_t width, uint32_t height, uint32_t numMipMap, GLTextureFormat format, uint32_t flags) {
|
||||
GLTexture2D* tex;
|
||||
|
||||
// TODO
|
||||
// tex = GLPool<GLTexture2D>::GLObjectPool::Pop(GLPool<GLTexture2D>::m_pool + 131080);
|
||||
tex = nullptr;
|
||||
|
||||
if (!tex) {
|
||||
tex = new GLTexture2D();
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Blizzard::Debug::Assert(tex->m_refCount == 0);
|
||||
|
||||
tex->m_RefCount = 1;
|
||||
|
||||
// TODO
|
||||
// Blizzard::Debug::Assert(tex->m_TextureID >= PoolStats<GLTexture2D>::NAME_POOL_FIRST_NAME);
|
||||
|
||||
tex->m_TextureType = GL_TEXTURE_2D;
|
||||
tex->m_Width = width;
|
||||
tex->m_Depth = 1;
|
||||
tex->m_Height = height;
|
||||
tex->m_Format = format;
|
||||
tex->m_NumMipmap = numMipMap;
|
||||
tex->m_RequestedNumMipmaps = numMipMap;
|
||||
tex->m_Flags = flags;
|
||||
|
||||
tex->SetupTexture();
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
GLTexture2D::GLTexture2D() : GLTexture() {
|
||||
this->m_TextureType = GL_TEXTURE_2D;
|
||||
this->m_TextureID = GLPool<GLTexture2D>::Get()->GetNextName();
|
||||
|
||||
// TODO
|
||||
// Blizzard::Debug::Assert(this->m_TextureID >= PoolStats<GLTexture2D>::NAME_POOL_FIRST_NAME);
|
||||
}
|
||||
|
||||
void GLTexture2D::ReleaseObject() {
|
||||
BLIZZARD_ASSERT(this->m_TextureType == GL_TEXTURE_2D);
|
||||
this->FreeTexture();
|
||||
}
|
||||
|
||||
void GLLTexSetFlags(CGxTex* texId, GLTexture* a2) {
|
||||
static GLEnum convertMagFilterToOgl[] = {
|
||||
GL_NEAREST,
|
||||
GL_LINEAR,
|
||||
GL_NEAREST,
|
||||
GL_LINEAR,
|
||||
GL_LINEAR,
|
||||
GL_LINEAR
|
||||
};
|
||||
|
||||
static GLEnum convertMinFilterToOgl[] = {
|
||||
GL_NEAREST,
|
||||
GL_LINEAR,
|
||||
GL_NEAREST_MIPMAP_NEAREST,
|
||||
GL_LINEAR_MIPMAP_NEAREST,
|
||||
GL_LINEAR_MIPMAP_LINEAR,
|
||||
GL_LINEAR_MIPMAP_LINEAR
|
||||
};
|
||||
|
||||
a2->SetMagFilterMode(convertMagFilterToOgl[texId->m_flags.m_filter]);
|
||||
a2->SetMinFilterMode(convertMinFilterToOgl[texId->m_flags.m_filter]);
|
||||
|
||||
a2->SetAddressModeS(texId->m_flags.m_wrapU ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||
a2->SetAddressModeT(texId->m_flags.m_wrapV ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||
|
||||
a2->SetMaxAnisotropy(texId->m_flags.m_maxAnisotropy);
|
||||
}
|
||||
100
src/gx/gll/GLTexture.h
Normal file
100
src/gx/gll/GLTexture.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#ifndef GX_GLL_GL_TEXTURE_H
|
||||
#define GX_GLL_GL_TEXTURE_H
|
||||
|
||||
#include "gx/gll/GL.h"
|
||||
#include "gx/gll/GLObject.h"
|
||||
#include "gx/gll/GLTypes.h"
|
||||
#include "util/BlizzardCore.hpp"
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#define GLTFLAG_RENDERTARGET 0x1
|
||||
#define GLTFLAG_DEPTH 0x2
|
||||
#define GLTFLAG_STENCIL 0x4
|
||||
#define GLTFLAG_AUTOGEN_MIPMAP 0x8
|
||||
#define GLTFLAG_READ_ACCESS 0x10
|
||||
#define GLTFLAG_SYSTEM_BUFFER 0x20
|
||||
|
||||
class CGxTex;
|
||||
class GLMipmap;
|
||||
class GLDevice;
|
||||
|
||||
class GLTexture : public GLObject {
|
||||
public:
|
||||
// Types
|
||||
struct Binding {
|
||||
uint8_t boundStages[16];
|
||||
GLDevice* device;
|
||||
};
|
||||
|
||||
// Static variables
|
||||
static Blizzard::Thread::TLSSlot m_Bindings[4];
|
||||
|
||||
// Static functions
|
||||
static void* CreateBindings(void*);
|
||||
static void DestroyBindings(void*);
|
||||
|
||||
// Member variables
|
||||
uint32_t m_TextureID = 0;
|
||||
GLEnum m_TextureType = 0;
|
||||
GLMipmap** m_Mipmaps = nullptr;
|
||||
std::list<GLTexture*>::iterator var7;
|
||||
uint32_t m_LastFrameUsed;
|
||||
uint32_t m_Width = 0;
|
||||
uint32_t m_Height = 0;
|
||||
uint32_t m_Depth = 0;
|
||||
uint32_t var12 = 0;
|
||||
uint32_t m_Size = 0;
|
||||
GLTextureFormat m_Format = GLTF_INVALID;
|
||||
uint32_t m_Flags = 0;
|
||||
uint32_t m_NumMipmap = 0;
|
||||
uint32_t m_RequestedNumMipmaps;
|
||||
char* m_Data = nullptr;
|
||||
std::atomic<int32_t> m_MappedMipmaps = { 0 };
|
||||
GLStates::Sampler m_Sampler;
|
||||
bool m_GenerateMipmaps = 0;
|
||||
int32_t m_MaxMipmapLevel = 1000;
|
||||
int32_t m_BaseMipmapLevel = 0;
|
||||
int32_t m_CompareMode = 0;
|
||||
|
||||
// Member functions
|
||||
void Bind(GLDevice*, bool);
|
||||
void FreeTexture();
|
||||
std::vector<Binding>& GetBindings(void); // invented name
|
||||
GLTextureFormat GetFormat(void);
|
||||
TextureFormatInfo& GetFormatInfo(void);
|
||||
GLMipmap* GetMipmap(uint32_t, GLEnum);
|
||||
bool IsRenderTarget(void);
|
||||
bool IsSystemBuffer(void);
|
||||
bool IsValid(void);
|
||||
void* Map(uint32_t, const GLRect*, uint32_t&, GLEnum);
|
||||
void RecreateGLTexture(void);
|
||||
void ResizeMipmaps(void);
|
||||
void SetAddressModeR(GLEnum);
|
||||
void SetAddressModeS(GLEnum);
|
||||
void SetAddressModeT(GLEnum);
|
||||
void SetBorderColor(const GLColor4f&);
|
||||
void SetCompareMode(GLEnum);
|
||||
void SetMagFilterMode(GLEnum);
|
||||
void SetMaxAnisotropy(int32_t);
|
||||
void SetMinFilterMode(GLEnum);
|
||||
void SetupTexture(void);
|
||||
void Unbind(GLDevice*, uint32_t); // invented name
|
||||
void Unmap(uint32_t level, GLEnum face);
|
||||
};
|
||||
|
||||
class GLTexture2D : public GLTexture {
|
||||
public:
|
||||
// Static functions
|
||||
static GLTexture2D* Create(uint32_t, uint32_t, uint32_t, GLTextureFormat, uint32_t);
|
||||
|
||||
// Virtual member functions
|
||||
virtual void ReleaseObject();
|
||||
|
||||
// Member functions
|
||||
GLTexture2D();
|
||||
};
|
||||
|
||||
void GLLTexSetFlags(CGxTex*, GLTexture*);
|
||||
|
||||
#endif
|
||||
5
src/gx/gll/GLTypes.cpp
Normal file
5
src/gx/gll/GLTypes.cpp
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "gx/gll/GLTypes.h"
|
||||
|
||||
GLColor4f GLColor4f::ZERO = { 0.0, 0.0, 0.0, 0.0 };
|
||||
GLColor4f GLColor4f::WHITE = { 1.0, 1.0, 1.0, 1.0 };
|
||||
GLColor4f GLColor4f::BLACK = { 0.0, 0.0, 0.0, 1.0 };
|
||||
370
src/gx/gll/GLTypes.h
Normal file
370
src/gx/gll/GLTypes.h
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
#ifndef GX_GLL_GL_TYPES_H
|
||||
#define GX_GLL_GL_TYPES_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <OpenGL/gl.h>
|
||||
|
||||
class GLBuffer;
|
||||
class GLFramebuffer;
|
||||
|
||||
enum GLTextureFormat {
|
||||
GLTF_INVALID = 0,
|
||||
GLTF_ARGB8888 = 1,
|
||||
GLTF_XRGB8888 = 2,
|
||||
GLTF_RGBA8888 = 3,
|
||||
GLTF_ABGR8888 = 4,
|
||||
GLTF_ARGB0888 = 5,
|
||||
GLTF_RGB888 = 6,
|
||||
GLTF_BGR888 = 7,
|
||||
GLTF_RGBA32F = 8,
|
||||
GLTF_RGBA16F = 9,
|
||||
GLTF_RG16F = 10,
|
||||
GLTF_D32 = 11,
|
||||
GLTF_D24 = 12,
|
||||
GLTF_D16 = 13,
|
||||
GLTF_DF = 14,
|
||||
GLTF_D24S8 = 15,
|
||||
GLTF_S8 = 16,
|
||||
GLTF_ARGB4444 = 17,
|
||||
GLTF_ARGB1555 = 18,
|
||||
GLTF_ARGB0555 = 19,
|
||||
GLTF_RGB565 = 20,
|
||||
GLTF_A2RGB10 = 21,
|
||||
GLTF_RGB16 = 22,
|
||||
GLTF_L8 = 23,
|
||||
GLTF_A8 = 24,
|
||||
GLTF_A8L8 = 25,
|
||||
GLTF_DXT1 = 26,
|
||||
GLTF_DXT3 = 27,
|
||||
GLTF_DXT5 = 28,
|
||||
GLTF_NUM_TEXTURE_FORMATS = 29
|
||||
};
|
||||
|
||||
enum GLVertexType {
|
||||
GLVT_INVALID = 0,
|
||||
GLVT_FLOAT1 = 1,
|
||||
GLVT_FLOAT2 = 2,
|
||||
GLVT_FLOAT3 = 3,
|
||||
GLVT_FLOAT4 = 4,
|
||||
GLVT_UBYTE4 = 5,
|
||||
GLVT_UBYTE4N = 6,
|
||||
GLVT_SHORT = 7,
|
||||
GLVT_SHORT2 = 8,
|
||||
GLVT_SHORT4 = 9,
|
||||
GLVT_SHORT2N = 10,
|
||||
GLVT_SHORT4N = 11,
|
||||
GLVT_USHORT2N = 12,
|
||||
GLVT_USHORT4N = 13,
|
||||
GLVT_NUM_VERTEX_TYPES = 14
|
||||
};
|
||||
|
||||
enum GLBufferType {
|
||||
eGLBT_PIXEL_UNPACK = 3,
|
||||
};
|
||||
|
||||
struct GLAttachPoint {
|
||||
GLFramebuffer* framebuffer;
|
||||
int32_t point; // TODO GLenum?
|
||||
int32_t zOffset; // TODO check type
|
||||
};
|
||||
|
||||
struct GLBox {
|
||||
int32_t left;
|
||||
int32_t top;
|
||||
int32_t front;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t depth;
|
||||
};
|
||||
|
||||
struct GLColor4f {
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
|
||||
static GLColor4f ZERO;
|
||||
static GLColor4f WHITE;
|
||||
static GLColor4f BLACK;
|
||||
};
|
||||
|
||||
struct GLDirtyRange {
|
||||
uint16_t start;
|
||||
uint16_t end;
|
||||
};
|
||||
|
||||
struct GLfloat4 {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
};
|
||||
|
||||
struct GLRect {
|
||||
int32_t left;
|
||||
int32_t top;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
};
|
||||
|
||||
struct GLTransform {
|
||||
bool isDirty;
|
||||
|
||||
union {
|
||||
struct {
|
||||
float a0;
|
||||
float a1;
|
||||
float a2;
|
||||
float a3;
|
||||
float b0;
|
||||
float b1;
|
||||
float b2;
|
||||
float b3;
|
||||
float c0;
|
||||
float c1;
|
||||
float c2;
|
||||
float c3;
|
||||
float d0;
|
||||
float d1;
|
||||
float d2;
|
||||
float d3;
|
||||
};
|
||||
|
||||
struct {
|
||||
float rows[4][4];
|
||||
};
|
||||
|
||||
float m[16];
|
||||
};
|
||||
|
||||
bool isIdentity;
|
||||
};
|
||||
|
||||
struct GLStates {
|
||||
struct Depth {
|
||||
bool testEnable;
|
||||
int32_t compareFunc;
|
||||
bool writeMask;
|
||||
};
|
||||
|
||||
struct Stencil {
|
||||
struct StencilFace {
|
||||
int32_t compareFunc;
|
||||
int32_t opFail;
|
||||
int32_t opZFail;
|
||||
int32_t opZPass;
|
||||
};
|
||||
|
||||
bool testEnable;
|
||||
int32_t ref;
|
||||
uint32_t mask;
|
||||
uint32_t writeMask;
|
||||
bool useTwoSidedStencil;
|
||||
StencilFace front;
|
||||
StencilFace back;
|
||||
};
|
||||
|
||||
struct Rasterizer {
|
||||
struct ClipPlane {
|
||||
double plane[4];
|
||||
};
|
||||
|
||||
int32_t cullMode;
|
||||
int32_t cullFaceMode;
|
||||
int32_t fillMode;
|
||||
float constantDepthBias;
|
||||
float slopeScaledDepthBias;
|
||||
GLRect viewport;
|
||||
double zNear;
|
||||
double zFar;
|
||||
bool scissorEnable;
|
||||
GLRect scissor;
|
||||
uint32_t clipPlaneMask;
|
||||
ClipPlane clipPlanes[6];
|
||||
};
|
||||
|
||||
struct Blend {
|
||||
struct ColorMask {
|
||||
bool red;
|
||||
bool green;
|
||||
bool blue;
|
||||
bool alpha;
|
||||
};
|
||||
|
||||
ColorMask colorMask[4];
|
||||
bool alphaBlend;
|
||||
int32_t srcBlendFactor;
|
||||
int32_t destBlendFactor;
|
||||
int32_t blendOp;
|
||||
GLColor4f blendColor;
|
||||
};
|
||||
|
||||
struct Clear {
|
||||
GLColor4f clearColor;
|
||||
double clearDepth;
|
||||
int32_t clearStencil;
|
||||
};
|
||||
|
||||
struct FixedFunc {
|
||||
struct TexOp {
|
||||
int32_t texturing;
|
||||
GLColor4f constant;
|
||||
int32_t colorOp;
|
||||
float colorScale;
|
||||
int32_t colorArg0;
|
||||
int32_t colorArg1;
|
||||
int32_t colorArg2;
|
||||
int32_t alphaOp;
|
||||
float alphaScale;
|
||||
int32_t alphaArg0;
|
||||
int32_t alphaArg1;
|
||||
int32_t alphaArg2;
|
||||
};
|
||||
|
||||
struct Light {
|
||||
bool enable;
|
||||
GLfloat4 position;
|
||||
GLTransform view;
|
||||
float constantAttenuation;
|
||||
float linearAttenuation;
|
||||
float quadraticAttenuation;
|
||||
GLColor4f ambient;
|
||||
GLColor4f diffuse;
|
||||
GLColor4f specular;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
bool colorTracking;
|
||||
int32_t materialSource;
|
||||
GLColor4f ambient;
|
||||
GLColor4f diffuse;
|
||||
GLColor4f specular;
|
||||
float shininess;
|
||||
GLColor4f emission;
|
||||
};
|
||||
|
||||
struct Lighting {
|
||||
bool enable;
|
||||
GLColor4f sceneAmbient;
|
||||
Light lights[8];
|
||||
Material material;
|
||||
};
|
||||
|
||||
struct Transforms {
|
||||
int32_t matrixMode;
|
||||
int32_t modelviewStatus;
|
||||
GLTransform modelView;
|
||||
GLTransform world;
|
||||
GLTransform view;
|
||||
GLTransform projection;
|
||||
GLTransform texture[8];
|
||||
};
|
||||
|
||||
struct TexGen {
|
||||
int32_t S;
|
||||
int32_t T;
|
||||
int32_t R;
|
||||
int32_t Q;
|
||||
};
|
||||
|
||||
struct PointSprite {
|
||||
bool enable;
|
||||
float size;
|
||||
float attenuation[3];
|
||||
float min;
|
||||
float max;
|
||||
};
|
||||
|
||||
bool fogEnable;
|
||||
GLColor4f fogColor;
|
||||
int32_t fogMode;
|
||||
float fogStart;
|
||||
float fogEnd;
|
||||
float fogDensity;
|
||||
bool alphaTestEnable;
|
||||
int32_t alphaTestFunc;
|
||||
float alphaTestRef;
|
||||
TexOp texOp[8];
|
||||
Lighting lighting;
|
||||
Transforms transforms;
|
||||
int32_t texCoordIndex[8];
|
||||
TexGen texGen[8];
|
||||
PointSprite pointSprite;
|
||||
bool normalizeNormal;
|
||||
};
|
||||
|
||||
struct Sampler {
|
||||
float mipmapBias;
|
||||
int32_t addressModeS;
|
||||
int32_t addressModeT;
|
||||
int32_t addressModeR;
|
||||
int32_t magFilterMode;
|
||||
int32_t minFilterMode;
|
||||
float maxAnisotropy;
|
||||
GLColor4f borderColor;
|
||||
};
|
||||
|
||||
struct Shader {
|
||||
bool vertexShaderEnable;
|
||||
GLfloat4 vertexShaderConst[256];
|
||||
bool pixelShaderEnable;
|
||||
GLfloat4 pixelShaderConst[64];
|
||||
};
|
||||
|
||||
struct Binding {
|
||||
uint32_t currentActiveTexture;
|
||||
uint32_t texture[4][16];
|
||||
uint32_t framebuffer;
|
||||
uint32_t renderbuffer;
|
||||
uint32_t vertexProgram;
|
||||
uint32_t pixelProgram;
|
||||
uint32_t glslProgram;
|
||||
uint32_t vertexArrayObject;
|
||||
};
|
||||
|
||||
struct Misc {
|
||||
bool unpackClientStorage;
|
||||
int32_t drawBuffers[4];
|
||||
int32_t readBuffer;
|
||||
};
|
||||
|
||||
struct VertexArrayObject {
|
||||
struct VertexAttrib {
|
||||
bool enable = 0;
|
||||
uint32_t size = 4;
|
||||
int32_t type = GL_FLOAT;
|
||||
bool normalized = 0;
|
||||
uint32_t stride = 0;
|
||||
void* offset = nullptr;
|
||||
GLBuffer* buffer = nullptr;
|
||||
};
|
||||
|
||||
uint32_t buffers[4] = {};
|
||||
VertexAttrib vertexAttribs[16];
|
||||
VertexAttrib position;
|
||||
VertexAttrib normal;
|
||||
VertexAttrib color0;
|
||||
VertexAttrib color1;
|
||||
VertexAttrib texCoord[8];
|
||||
};
|
||||
|
||||
Depth depth;
|
||||
Stencil stencil;
|
||||
Rasterizer rasterizer;
|
||||
Blend blend;
|
||||
Clear clear;
|
||||
FixedFunc fixedFunc;
|
||||
Sampler samplers[16];
|
||||
Shader shader;
|
||||
Binding binding;
|
||||
Misc misc;
|
||||
};
|
||||
|
||||
struct GLVertexAttrib {
|
||||
uint32_t stream;
|
||||
int32_t slot;
|
||||
int32_t type;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
#endif
|
||||
22
src/gx/gll/GLUtil.cpp
Normal file
22
src/gx/gll/GLUtil.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include "gx/gll/GLUtil.h"
|
||||
#include "util/BlizzardCore.hpp"
|
||||
|
||||
uint32_t GLLTextureTypeToIndex(GLEnum textureType) {
|
||||
uint32_t index;
|
||||
|
||||
if (textureType == GL_TEXTURE_2D) {
|
||||
index = 0;
|
||||
} else if (textureType == GL_TEXTURE_3D) {
|
||||
index = 1;
|
||||
} else if (textureType == GL_TEXTURE_CUBE_MAP) {
|
||||
index = 2;
|
||||
} else if (textureType == GL_TEXTURE_RECTANGLE_EXT) {
|
||||
index = 3;
|
||||
} else {
|
||||
index = 5;
|
||||
|
||||
BLIZZARD_ASSERT(false);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
9
src/gx/gll/GLUtil.h
Normal file
9
src/gx/gll/GLUtil.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef GX_GLL_GL_UTIL_H
|
||||
#define GX_GLL_GL_UTIL_H
|
||||
|
||||
#include "gx/gll/GL.h"
|
||||
#include <cstdint>
|
||||
|
||||
uint32_t GLLTextureTypeToIndex(GLEnum textureType);
|
||||
|
||||
#endif
|
||||
189
src/gx/gll/GLVertexArray.cpp
Normal file
189
src/gx/gll/GLVertexArray.cpp
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
#include "gx/gll/GLVertexArray.h"
|
||||
#include "gx/gll/GLDevice.h"
|
||||
|
||||
bool GLVertexArray::s_VertexArrayEnable = false;
|
||||
|
||||
GLVertexArray::GLVertexArray(bool a2) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void GLVertexArray::FindVertexArray(GLDevice* a1, GLVertexArray& a2) {
|
||||
if (GLVertexArray::s_VertexArrayEnable) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
a2.ApplyVertexFormat(a1);
|
||||
}
|
||||
|
||||
void GLVertexArray::ApplyGLStates(GLStates::VertexArrayObject& vao) {
|
||||
GLDevice* device = GLDevice::Get();
|
||||
|
||||
device->BindVertexArray(this);
|
||||
|
||||
for (int32_t i = 0; i < kMAX_VERTEX_ATTRIBS; i++) {
|
||||
auto& attrib = vao.vertexAttribs[i];
|
||||
|
||||
if (attrib.enable) {
|
||||
glBindBuffer(attrib.buffer->m_Type, attrib.buffer->m_BufferID);
|
||||
|
||||
glVertexAttribPointerARB(
|
||||
i,
|
||||
attrib.size,
|
||||
attrib.type,
|
||||
attrib.normalized,
|
||||
attrib.stride,
|
||||
reinterpret_cast<void*>(attrib.offset)
|
||||
);
|
||||
|
||||
glEnableVertexAttribArrayARB(i);
|
||||
} else {
|
||||
glDisableVertexAttribArrayARB(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (vao.position.enable) {
|
||||
glBindBuffer(vao.position.buffer->m_Type, vao.position.buffer->m_BufferID);
|
||||
glVertexPointer(vao.position.size, vao.position.type, vao.position.stride, vao.position.offset);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
} else {
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
if (vao.normal.enable) {
|
||||
glBindBuffer(vao.normal.buffer->m_Type, vao.normal.buffer->m_BufferID);
|
||||
glNormalPointer(vao.normal.type, vao.normal.stride, vao.normal.offset);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
} else {
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
if (vao.color0.enable) {
|
||||
glBindBuffer(vao.color0.buffer->m_Type, vao.color0.buffer->m_BufferID);
|
||||
glColorPointer(vao.color0.size, vao.color0.type, vao.color0.stride, vao.color0.offset);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
} else {
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
if (vao.color1.enable) {
|
||||
glBindBuffer(vao.color1.buffer->m_Type, vao.color1.buffer->m_BufferID);
|
||||
glColorPointer(vao.color1.size, vao.color1.type, vao.color1.stride, vao.color1.offset);
|
||||
glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
|
||||
} else {
|
||||
glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < 8; i++) {
|
||||
glClientActiveTextureARB(GL_TEXTURE0 + i);
|
||||
|
||||
if (vao.texCoord[i].enable) {
|
||||
glBindBuffer(vao.texCoord[i].buffer->m_Type, vao.texCoord[0].buffer->m_BufferID);
|
||||
glTexCoordPointer(vao.texCoord[i].size, vao.texCoord[i].type, vao.texCoord[i].stride, vao.texCoord[i].offset);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
} else {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vao.buffers[0]);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao.buffers[1]);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, vao.buffers[2]);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, vao.buffers[3]);
|
||||
|
||||
this->m_GLStates = vao;
|
||||
}
|
||||
|
||||
void GLVertexArray::ApplyVertexFormat(GLDevice* device) {
|
||||
if (GLVertexArray::s_VertexArrayEnable) {
|
||||
device->BindVertexArray(this);
|
||||
}
|
||||
|
||||
auto indexBuffer = this->m_Properties.m_IndexBuffer;
|
||||
uint32_t indexBufferID = indexBuffer ? indexBuffer->m_BufferID : 0;
|
||||
|
||||
if (this->m_GLStates.buffers[1] != indexBufferID) {
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
|
||||
this->m_GLStates.buffers[1] = indexBufferID;
|
||||
}
|
||||
|
||||
BLIZZARD_ASSERT(this->GetProperties().m_VertexBufferFormat != nullptr);
|
||||
|
||||
auto& properties = this->GetProperties();
|
||||
bool attribEnable[16] = {};
|
||||
|
||||
bool useVertexShader = device->GetShader(GLShader::eVertexShader) != nullptr;
|
||||
|
||||
for (int32_t index = 0; index < this->GetProperties().m_VertexBufferFormat->m_Size; index++) {
|
||||
BLIZZARD_ASSERT(index < kMAX_VERTEX_ATTRIBS);
|
||||
|
||||
auto& attrib = this->GetProperties().m_VertexBufferFormat->m_Attribs[index];
|
||||
|
||||
BLIZZARD_ASSERT(attrib.type != GLVT_INVALID);
|
||||
BLIZZARD_ASSERT(attrib.type < GLVT_NUM_VERTEX_TYPES);
|
||||
|
||||
auto vertexBuffer = this->GetProperties().m_VertexBuffer[attrib.stream];
|
||||
|
||||
if (useVertexShader || attrib.slot - 1 > 1) {
|
||||
if (this->m_GLStates.buffers[0] != vertexBuffer->m_BufferID) {
|
||||
glBindBuffer(vertexBuffer->m_Type, vertexBuffer->m_BufferID);
|
||||
this->m_GLStates.buffers[0] = vertexBuffer->m_BufferID;
|
||||
}
|
||||
|
||||
attribEnable[attrib.slot] = 1;
|
||||
|
||||
int32_t stride = properties.m_VertexBufferStride[attrib.stream];
|
||||
int32_t offset = attrib.offset
|
||||
+ properties.m_VertexBufferOffset[attrib.stream]
|
||||
+ properties.m_VertexBase * stride;
|
||||
|
||||
if (useVertexShader) {
|
||||
glVertexAttribPointerARB(
|
||||
attrib.slot,
|
||||
k_VertexTypeInfo[attrib.type].m_Size,
|
||||
k_VertexTypeInfo[attrib.type].m_Type,
|
||||
k_VertexTypeInfo[attrib.type].m_Normalized,
|
||||
stride,
|
||||
reinterpret_cast<void*>(offset)
|
||||
);
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t s = 0; s < 16; s++) {
|
||||
bool* prevAttribEnable;
|
||||
|
||||
if (useVertexShader) {
|
||||
prevAttribEnable = &this->m_GLStates.vertexAttribs[s].enable;
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (*prevAttribEnable != attribEnable[s]) {
|
||||
if (attribEnable[s]) {
|
||||
if (useVertexShader) {
|
||||
glEnableVertexAttribArrayARB(s);
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
} else {
|
||||
if (useVertexShader) {
|
||||
glDisableVertexAttribArrayARB(s);
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
*prevAttribEnable = attribEnable[s];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLVertexArray::Properties& GLVertexArray::GetProperties() {
|
||||
return this->m_Properties;
|
||||
}
|
||||
|
||||
void GLVertexArray::ReleaseObject() {
|
||||
// TODO
|
||||
}
|
||||
46
src/gx/gll/GLVertexArray.h
Normal file
46
src/gx/gll/GLVertexArray.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef GX_GLL_GL_VERTEX_ARRAY_H
|
||||
#define GX_GLL_GL_VERTEX_ARRAY_H
|
||||
|
||||
#include "gx/gll/GLBuffer.h"
|
||||
#include "gx/gll/GLObject.h"
|
||||
#include "gx/gll/GLVertexFormat.h"
|
||||
#include <cstdint>
|
||||
|
||||
class GLDevice;
|
||||
|
||||
class GLVertexArray : public GLObject {
|
||||
public:
|
||||
// Types
|
||||
struct Properties {
|
||||
GLVertexFormat* m_VertexBufferFormat = nullptr;
|
||||
GLBuffer* m_IndexBuffer = nullptr;
|
||||
GLBuffer* m_PixelPackBuffer = nullptr;
|
||||
GLBuffer* m_PixelUnpackBuffer = nullptr;
|
||||
GLBuffer* m_VertexBuffer[4] = {};
|
||||
uint32_t m_VertexBase = 0;
|
||||
uint32_t m_VertexBufferOffset[4] = {};
|
||||
uint32_t m_VertexBufferStride[4] = {};
|
||||
};
|
||||
|
||||
// Static variables
|
||||
static bool s_VertexArrayEnable;
|
||||
|
||||
// Static functions
|
||||
static void FindVertexArray(GLDevice*, GLVertexArray&);
|
||||
|
||||
// Member variables
|
||||
Properties m_Properties;
|
||||
GLStates::VertexArrayObject m_GLStates;
|
||||
uint32_t m_VertexArrayID = 0;
|
||||
|
||||
// Virtual member functions
|
||||
virtual void ReleaseObject();
|
||||
|
||||
// Member functions
|
||||
GLVertexArray(bool);
|
||||
void ApplyGLStates(GLStates::VertexArrayObject&);
|
||||
void ApplyVertexFormat(GLDevice*);
|
||||
Properties& GetProperties(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
13
src/gx/gll/GLVertexFormat.h
Normal file
13
src/gx/gll/GLVertexFormat.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef GX_GLL_GL_VERTEX_FORMAT_H
|
||||
#define GX_GLL_GL_VERTEX_FORMAT_H
|
||||
|
||||
#include "gx/gll/GLTypes.h"
|
||||
#include <cstdint>
|
||||
|
||||
class GLVertexFormat {
|
||||
public:
|
||||
uint32_t m_Size;
|
||||
GLVertexAttrib m_Attribs[16];
|
||||
};
|
||||
|
||||
#endif
|
||||
17
src/gx/gll/GLVertexShader.cpp
Normal file
17
src/gx/gll/GLVertexShader.cpp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#include "gx/gll/GLVertexShader.h"
|
||||
#include "gx/gll/GL.h"
|
||||
|
||||
GLVertexShader* GLVertexShader::Create() {
|
||||
// TODO
|
||||
// GLPool stuff
|
||||
|
||||
GLVertexShader* shader = new GLVertexShader();
|
||||
|
||||
shader->m_ShaderID = 0;
|
||||
shader->m_RefCount = 1;
|
||||
shader->m_ShaderType = eVertexShader;
|
||||
shader->m_UsingGLSL = 0;
|
||||
shader->var5 = GL_VERTEX_PROGRAM_ARB;
|
||||
|
||||
return shader;
|
||||
}
|
||||
12
src/gx/gll/GLVertexShader.h
Normal file
12
src/gx/gll/GLVertexShader.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef GX_GLL_GL_VERTEX_SHADER_H
|
||||
#define GX_GLL_GL_VERTEX_SHADER_H
|
||||
|
||||
#include "gx/gll/GLShader.h"
|
||||
|
||||
class GLVertexShader : public GLShader {
|
||||
public:
|
||||
// Static functions
|
||||
static GLVertexShader* Create(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
66
src/gx/gll/GLWindow.h
Normal file
66
src/gx/gll/GLWindow.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef GX_GLL_GL_WINDOW_H
|
||||
#define GX_GLL_GL_WINDOW_H
|
||||
|
||||
#include "gx/gll/GLAbstractWindow.h"
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#ifdef __OBJC__
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
@class GLLayerView;
|
||||
@class GLFullscreenWindow;
|
||||
@class NSEvent;
|
||||
#else
|
||||
#include <objc/objc-runtime.h>
|
||||
|
||||
typedef struct objc_object GLLayerView;
|
||||
typedef struct objc_object GLFullscreenWindow;
|
||||
typedef struct objc_object NSView;
|
||||
typedef struct objc_object NSWindow;
|
||||
typedef struct objc_object NSEvent;
|
||||
#endif
|
||||
|
||||
class GLContext;
|
||||
|
||||
struct GLWindowCallbacks {
|
||||
void (*OnResized)(int32_t, int32_t, bool);
|
||||
void (*OnMouseDown)(int16_t, int32_t, int32_t);
|
||||
void (*OnMouseMoved)(int32_t, int32_t);
|
||||
void (*OnMouseUp)(int16_t, int32_t, int32_t);
|
||||
void (*OnKeyDown)(NSEvent*);
|
||||
void (*OnKeyUp)(NSEvent*);
|
||||
};
|
||||
|
||||
class GLWindow : public GLAbstractWindow {
|
||||
public:
|
||||
// Member variables
|
||||
// void** var0; // _vptr$GLAbstractWindow
|
||||
GLContext* m_Context = nullptr;
|
||||
NSWindow* m_Window = nullptr;
|
||||
bool m_Shown = 0;
|
||||
GLLayerView* m_View = nullptr;
|
||||
Class m_ViewClass;
|
||||
GLFullscreenWindow* m_FullscreenWindow = nullptr;
|
||||
GLWindowCallbacks* m_Callbacks;
|
||||
GLWindowCallbacks* m_ActiveCallbacks;
|
||||
|
||||
// Member functions
|
||||
bool CanEnterFullscreenMode(void);
|
||||
void CreateView(void);
|
||||
CGRect GetBackingRect();
|
||||
NSView* GetNSView(void);
|
||||
CGRect GetRect(void);
|
||||
void ExitFullscreenMode(void);
|
||||
void Init(const CGRect&, GLWindowCallbacks*);
|
||||
void Resize(uint32_t, uint32_t);
|
||||
void SetOpenGLContext(GLContext*);
|
||||
void SetViewClass(Class);
|
||||
void Show(void);
|
||||
void Sub70760(void);
|
||||
|
||||
// Virtual member functions
|
||||
virtual void SetCallbacks(GLWindowCallbacks*);
|
||||
virtual void SetTitle(const char*);
|
||||
};
|
||||
|
||||
#endif
|
||||
224
src/gx/gll/GLWindow.mm
Normal file
224
src/gx/gll/GLWindow.mm
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
#include "gx/gll/GLWindow.h"
|
||||
#include "gx/gll/GLContext.h"
|
||||
#include "gx/gll/GLLayerView.h"
|
||||
#include "util/Autorelease.hpp"
|
||||
#include <cmath>
|
||||
|
||||
GLWindowCallbacks DefaultCallbacks = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
bool GLWindow::CanEnterFullscreenMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLWindow::CreateView() {
|
||||
System_Autorelease::ScopedPool autorelease;
|
||||
|
||||
BLIZZARD_ASSERT(this->m_View == nullptr);
|
||||
|
||||
GLLayerView* v1 = [this->m_ViewClass alloc];
|
||||
NSView* v2 = [this->m_Window contentView];
|
||||
|
||||
NSRect v6 = v2.frame;
|
||||
|
||||
this->m_View = [v1 initWithFrame: v6 glWindow: this];
|
||||
|
||||
[this->m_View setAutoresizingMask: 18];
|
||||
|
||||
[[this->m_Window contentView] addSubview: this->m_View];
|
||||
[this->m_Window makeFirstResponder: this->m_View];
|
||||
[this->m_Window setDelegate: this->m_View];
|
||||
}
|
||||
|
||||
CGRect GLWindow::GetBackingRect() {
|
||||
NSRect viewFrame = [this->m_Window contentView].frame;
|
||||
NSRect backingFrame = [this->m_Window convertRectToBacking:viewFrame];
|
||||
|
||||
return CGRectMake(
|
||||
0.0f,
|
||||
0.0f,
|
||||
backingFrame.size.width,
|
||||
backingFrame.size.height
|
||||
);
|
||||
}
|
||||
|
||||
NSView* GLWindow::GetNSView() {
|
||||
return (NSView*)this->m_View;
|
||||
}
|
||||
|
||||
CGRect GLWindow::GetRect() {
|
||||
NSRect screenFrame = [[NSScreen screens] objectAtIndex: 0].frame;
|
||||
NSRect viewFrame = [this->m_Window contentView].frame;
|
||||
NSRect windowFrame = this->m_Window.frame;
|
||||
|
||||
return CGRectMake(
|
||||
windowFrame.origin.x,
|
||||
screenFrame.size.height - (viewFrame.size.height + windowFrame.origin.y),
|
||||
viewFrame.size.width,
|
||||
viewFrame.size.height
|
||||
);
|
||||
}
|
||||
|
||||
void GLWindow::ExitFullscreenMode() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void GLWindow::Init(const CGRect& a2, GLWindowCallbacks* a3) {
|
||||
System_Autorelease::ScopedPool autorelease;
|
||||
|
||||
this->SetCallbacks(a3);
|
||||
|
||||
BLIZZARD_ASSERT(this->m_Window == nullptr);
|
||||
|
||||
NSScreen* primaryScreen = [[NSScreen screens] objectAtIndex:0];
|
||||
|
||||
NSRect frame = primaryScreen.frame;
|
||||
|
||||
NSRect contentRect = NSMakeRect(
|
||||
a2.origin.x,
|
||||
(frame.origin.y + frame.size.height) - (a2.origin.y + a2.size.height),
|
||||
a2.size.width,
|
||||
a2.size.height
|
||||
);
|
||||
|
||||
NSWindow* window = [NSWindow alloc];
|
||||
|
||||
[window
|
||||
initWithContentRect: contentRect
|
||||
styleMask: 15
|
||||
backing: NSBackingStoreBuffered
|
||||
defer: NO];
|
||||
|
||||
this->m_Window = window;
|
||||
|
||||
[window
|
||||
setAcceptsMouseMovedEvents: YES];
|
||||
|
||||
[window
|
||||
setReleasedWhenClosed: NO];
|
||||
|
||||
[window
|
||||
setBackgroundColor: [NSColor blackColor]];
|
||||
|
||||
BLIZZARD_ASSERT(this->m_Window != nullptr);
|
||||
|
||||
// TODO
|
||||
// return 1;
|
||||
}
|
||||
|
||||
void GLWindow::Resize(uint32_t width, uint32_t height) {
|
||||
auto rect = this->GetRect();
|
||||
|
||||
if (std::floor(rect.size.width) != width || std::floor(rect.size.height) != height) {
|
||||
auto size = CGSizeMake(
|
||||
(static_cast<float>(width / 65536) * 65536.0f) + static_cast<uint16_t>(width),
|
||||
(static_cast<float>(height / 65536) * 65536.0f) + static_cast<uint16_t>(height)
|
||||
);
|
||||
|
||||
[this->m_Window setContentSize: size];
|
||||
}
|
||||
}
|
||||
|
||||
void GLWindow::SetCallbacks(GLWindowCallbacks* callbacks) {
|
||||
if (callbacks) {
|
||||
this->m_Callbacks = callbacks;
|
||||
this->m_ActiveCallbacks = callbacks;
|
||||
} else {
|
||||
this->m_Callbacks = &DefaultCallbacks;
|
||||
this->m_ActiveCallbacks = &DefaultCallbacks;
|
||||
}
|
||||
}
|
||||
|
||||
void GLWindow::SetOpenGLContext(GLContext* a2) {
|
||||
BLIZZARD_ASSERT(this->m_View != nullptr);
|
||||
|
||||
System_Autorelease::ScopedPool autorelease;
|
||||
|
||||
if (a2) {
|
||||
if ([a2->m_Context->context view]) {
|
||||
[a2->m_Context->context clearDrawable];
|
||||
}
|
||||
|
||||
if (this->m_Context) {
|
||||
[this->m_Context->m_Context->context clearDrawable];
|
||||
}
|
||||
|
||||
NSOpenGLContext* currentContext = GLContext::GetNSOpenGLCurrentContext();
|
||||
|
||||
if (currentContext) {
|
||||
[currentContext clearDrawable];
|
||||
}
|
||||
|
||||
[a2->m_Context->context setView: this->m_View];
|
||||
|
||||
if (![a2->m_Context->context view]) {
|
||||
puts("*** INVALID VIEW ***");
|
||||
}
|
||||
|
||||
a2->Update();
|
||||
|
||||
this->m_Context = a2;
|
||||
} else {
|
||||
if (!this->m_Context) {
|
||||
this->m_Context = a2;
|
||||
} else {
|
||||
[this->m_Context->m_Context->context clearDrawable];
|
||||
this->m_Context = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLWindow::SetTitle(const char* title) {
|
||||
// TODO
|
||||
// sub_BD280(v5);
|
||||
|
||||
[this->m_Window
|
||||
setTitle: [NSString stringWithUTF8String: title]];
|
||||
|
||||
|
||||
// TODO
|
||||
// sub_BD2C0(v5);
|
||||
}
|
||||
|
||||
void GLWindow::SetViewClass(Class viewClass) {
|
||||
if (![viewClass isSubclassOfClass: [GLLayerView class]]) {
|
||||
// TODO
|
||||
// sub_C2080(v3);
|
||||
}
|
||||
|
||||
this->m_ViewClass = viewClass;
|
||||
}
|
||||
|
||||
void GLWindow::Show() {
|
||||
if (this->m_FullscreenWindow) {
|
||||
[this->m_FullscreenWindow
|
||||
makeKeyAndOrderFront: 0];
|
||||
[this->m_FullscreenWindow
|
||||
makeFirstResponder: (NSView*)this->m_View];
|
||||
|
||||
this->m_Shown = true;
|
||||
} else {
|
||||
this->Sub70760();
|
||||
}
|
||||
}
|
||||
|
||||
void GLWindow::Sub70760() {
|
||||
// TODO
|
||||
// sub_BD280(v4);
|
||||
|
||||
[this->m_Window
|
||||
makeKeyAndOrderFront: 0];
|
||||
|
||||
if (this->GetNSView()) {
|
||||
NSView* view = this->GetNSView();
|
||||
|
||||
[this->m_Window
|
||||
makeFirstResponder: view];
|
||||
}
|
||||
|
||||
this->m_Shown = true;
|
||||
|
||||
// TODO
|
||||
// sub_BD2C0(v4);
|
||||
}
|
||||
117
src/gx/gll/GLWorker.cpp
Normal file
117
src/gx/gll/GLWorker.cpp
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#include "gx/gll/GLWorker.h"
|
||||
#include "gx/gll/GLCommand.h"
|
||||
#include "gx/gll/GLDevice.h"
|
||||
|
||||
void* GLWorker::Worker(void* userArg) {
|
||||
GLWorker* worker = static_cast<GLWorker*>(userArg);
|
||||
|
||||
GLDevice* device = new GLDevice();
|
||||
device->Init(nullptr, "GLWorker", 0x10, GLTF_INVALID);
|
||||
|
||||
auto commandsEnd = worker->m_Commands.end();
|
||||
|
||||
while (!worker->m_UnkA0) {
|
||||
while (1) {
|
||||
pthread_mutex_lock(&worker->m_Mutex1);
|
||||
|
||||
while (worker->m_Commands.begin() == commandsEnd) {
|
||||
pthread_cond_wait(&worker->m_Cond1, &worker->m_Mutex1);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&worker->m_Mutex2);
|
||||
|
||||
if (worker->m_Commands.begin() == commandsEnd) {
|
||||
break;
|
||||
}
|
||||
|
||||
GLCommand* command = worker->m_Commands.front();
|
||||
worker->m_Commands.pop_front();
|
||||
|
||||
pthread_mutex_unlock(&worker->m_Mutex1);
|
||||
|
||||
if (command) {
|
||||
command->Execute(device);
|
||||
delete command;
|
||||
} else {
|
||||
pthread_cond_signal(&worker->m_Cond2);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&worker->m_Mutex2);
|
||||
|
||||
if (worker->m_UnkA0) {
|
||||
goto DONE;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&worker->m_Mutex2);
|
||||
pthread_mutex_unlock(&worker->m_Mutex1);
|
||||
}
|
||||
|
||||
DONE:
|
||||
delete device;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GLWorker::GLWorker(GLDevice* device): m_Commands() {
|
||||
this->m_UnkA0 = 0;
|
||||
this->m_UnkA1 = 0;
|
||||
this->m_Device = device;
|
||||
|
||||
pthread_mutex_init(&this->m_Mutex1, nullptr);
|
||||
pthread_cond_init(&this->m_Cond1, nullptr);
|
||||
pthread_mutex_init(&this->m_Mutex2, nullptr);
|
||||
pthread_cond_init(&this->m_Cond2, nullptr);
|
||||
|
||||
pthread_create(&this->m_Thread, nullptr, &Worker, this);
|
||||
}
|
||||
|
||||
void GLWorker::Lock() {
|
||||
pthread_mutex_lock(&this->m_Mutex1);
|
||||
}
|
||||
|
||||
void GLWorker::Send(GLCommand* command) {
|
||||
this->m_Commands.push_back(command);
|
||||
this->m_UnkA1 = 0;
|
||||
}
|
||||
|
||||
void GLWorker::Signal() {
|
||||
pthread_cond_signal(&this->m_Cond1);
|
||||
}
|
||||
|
||||
void GLWorker::Unlock() {
|
||||
pthread_mutex_unlock(&this->m_Mutex1);
|
||||
}
|
||||
|
||||
void GLWorker::WaitOnGLObjects() {
|
||||
pthread_mutex_lock(&this->m_Mutex1);
|
||||
|
||||
if (this->m_Commands.begin() == this->m_Commands.end()) {
|
||||
GLFlush* command = new GLFlush();
|
||||
this->m_Commands.push_back(command);
|
||||
|
||||
this->m_Commands.push_back(nullptr);
|
||||
} else {
|
||||
auto it = this->m_Commands.begin();
|
||||
|
||||
// TODO some kind of reordering logic for commands
|
||||
|
||||
if (this->m_Commands.begin() == it) {
|
||||
GLFlush* command = new GLFlush();
|
||||
this->m_Commands.push_back(command);
|
||||
|
||||
this->m_Commands.push_back(nullptr);
|
||||
} else {
|
||||
GLFlush* command = new GLFlush();
|
||||
this->m_Commands.insert(it, command);
|
||||
|
||||
this->m_Commands.insert(it, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_cond_signal(&this->m_Cond1);
|
||||
pthread_cond_wait(&this->m_Cond2, &this->m_Mutex1);
|
||||
|
||||
this->m_UnkA1 = 1;
|
||||
|
||||
pthread_mutex_unlock(&this->m_Mutex1);
|
||||
}
|
||||
35
src/gx/gll/GLWorker.h
Normal file
35
src/gx/gll/GLWorker.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef GX_GLL_GL_WORKER_H
|
||||
#define GX_GLL_GL_WORKER_H
|
||||
|
||||
#include <list>
|
||||
#include <pthread.h>
|
||||
|
||||
class GLCommand;
|
||||
class GLDevice;
|
||||
|
||||
class GLWorker {
|
||||
public:
|
||||
// Static functions
|
||||
static void* Worker(void*);
|
||||
|
||||
// Member variables
|
||||
GLDevice* m_Device;
|
||||
std::list<GLCommand*> m_Commands;
|
||||
pthread_mutex_t m_Mutex1;
|
||||
pthread_mutex_t m_Mutex2;
|
||||
pthread_cond_t m_Cond1;
|
||||
pthread_cond_t m_Cond2;
|
||||
pthread_t m_Thread;
|
||||
bool m_UnkA0;
|
||||
bool m_UnkA1;
|
||||
|
||||
// Member functions
|
||||
GLWorker(GLDevice*);
|
||||
void Lock(void);
|
||||
void Send(GLCommand*);
|
||||
void Signal(void);
|
||||
void Unlock(void);
|
||||
void WaitOnGLObjects(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue