2894: Add new renderer(as streamed vertices) for editor r=def- a=Jupeyy

Does not improve performance in editor!

Co-authored-by: Jupeyy <jupjopjap@gmail.com>
This commit is contained in:
bors[bot] 2020-09-24 08:06:42 +00:00 committed by GitHub
commit ceefdacfbc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 619 additions and 264 deletions

View file

@ -6,13 +6,30 @@ uniform sampler2DArray gTextureSampler;
#endif
#endif
#ifdef TW_MODERN_GL
#ifdef TW_TEXTURED
noperspective in vec3 oTexCoord;
#endif
noperspective in vec4 oVertColor;
out vec4 FragClr;
#endif
void main()
{
#ifdef TW_MODERN_GL
#ifdef TW_TEXTURED
vec4 TexColor = texture(gTextureSampler, oTexCoord.xyz).rgba;
FragClr = TexColor.rgba * oVertColor.rgba;
#else
FragClr = oVertColor.rgba;
#endif
#else
#ifdef TW_TEXTURED
vec4 TexColor = texture(gTextureSampler, gl_TexCoord[0].xyz).rgba;
gl_FragColor = TexColor.rgba * gl_Color.rgba;
#else
gl_FragColor = gl_Color.rgba;
#endif
#endif
}

View file

@ -1,11 +1,32 @@
#ifdef TW_MODERN_GL
layout (location = 0) in vec2 inVertex;
layout (location = 1) in vec4 inVertexColor;
layout (location = 2) in vec3 inVertexTexCoord;
#endif
uniform mat4x2 gPos;
#ifdef TW_MODERN_GL
#ifdef TW_TEXTURED
noperspective out vec3 oTexCoord;
#endif
noperspective out vec4 oVertColor;
#endif
void main()
{
#ifdef TW_MODERN_GL
gl_Position = vec4(gPos * vec4(inVertex, 0.0, 1.0), 0.0, 1.0);
#ifdef TW_TEXTURED
oTexCoord = inVertexTexCoord;
#endif
oVertColor = inVertexColor;
#else
gl_Position = vec4(gPos * vec4(gl_Vertex.xy, 0.0, 1.0), 0.0, 1.0);
#ifdef TW_TEXTURED
gl_TexCoord[0] = gl_MultiTexCoord0;
#endif
gl_FrontColor = gl_Color.rgba;
gl_BackColor = gl_Color.rgba;
#endif
}

View file

@ -855,14 +855,33 @@ bool CCommandProcessorFragment_OpenGL::RunCommand(const CCommandBuffer::SCommand
{
switch(pBaseCommand->m_Cmd)
{
case CCommandProcessorFragment_OpenGL::CMD_INIT: Cmd_Init(static_cast<const SCommand_Init *>(pBaseCommand)); break;
case CCommandProcessorFragment_OpenGL::CMD_SHUTDOWN: Cmd_Shutdown(static_cast<const SCommand_Shutdown *>(pBaseCommand)); break;
case CCommandBuffer::CMD_TEXTURE_CREATE: Cmd_Texture_Create(static_cast<const CCommandBuffer::SCommand_Texture_Create *>(pBaseCommand)); break;
case CCommandBuffer::CMD_TEXTURE_DESTROY: Cmd_Texture_Destroy(static_cast<const CCommandBuffer::SCommand_Texture_Destroy *>(pBaseCommand)); break;
case CCommandBuffer::CMD_TEXTURE_UPDATE: Cmd_Texture_Update(static_cast<const CCommandBuffer::SCommand_Texture_Update *>(pBaseCommand)); break;
case CCommandBuffer::CMD_CLEAR: Cmd_Clear(static_cast<const CCommandBuffer::SCommand_Clear *>(pBaseCommand)); break;
case CCommandBuffer::CMD_RENDER: Cmd_Render(static_cast<const CCommandBuffer::SCommand_Render *>(pBaseCommand)); break;
case CCommandBuffer::CMD_SCREENSHOT: Cmd_Screenshot(static_cast<const CCommandBuffer::SCommand_Screenshot *>(pBaseCommand)); break;
case CCommandProcessorFragment_OpenGL::CMD_INIT:
Cmd_Init(static_cast<const SCommand_Init *>(pBaseCommand));
break;
case CCommandProcessorFragment_OpenGL::CMD_SHUTDOWN:
Cmd_Shutdown(static_cast<const SCommand_Shutdown *>(pBaseCommand));
break;
case CCommandBuffer::CMD_TEXTURE_CREATE:
Cmd_Texture_Create(static_cast<const CCommandBuffer::SCommand_Texture_Create *>(pBaseCommand));
break;
case CCommandBuffer::CMD_TEXTURE_DESTROY:
Cmd_Texture_Destroy(static_cast<const CCommandBuffer::SCommand_Texture_Destroy *>(pBaseCommand));
break;
case CCommandBuffer::CMD_TEXTURE_UPDATE:
Cmd_Texture_Update(static_cast<const CCommandBuffer::SCommand_Texture_Update *>(pBaseCommand));
break;
case CCommandBuffer::CMD_CLEAR:
Cmd_Clear(static_cast<const CCommandBuffer::SCommand_Clear *>(pBaseCommand));
break;
case CCommandBuffer::CMD_RENDER:
Cmd_Render(static_cast<const CCommandBuffer::SCommand_Render *>(pBaseCommand));
break;
case CCommandBuffer::CMD_RENDER_TEX3D:
Cmd_RenderTex3D(static_cast<const CCommandBuffer::SCommand_RenderTex3D *>(pBaseCommand));
break;
case CCommandBuffer::CMD_SCREENSHOT:
Cmd_Screenshot(static_cast<const CCommandBuffer::SCommand_Screenshot *>(pBaseCommand));
break;
case CCommandBuffer::CMD_CREATE_BUFFER_OBJECT: Cmd_CreateBufferObject(static_cast<const CCommandBuffer::SCommand_CreateBufferObject *>(pBaseCommand)); break;
case CCommandBuffer::CMD_UPDATE_BUFFER_OBJECT: Cmd_UpdateBufferObject(static_cast<const CCommandBuffer::SCommand_UpdateBufferObject *>(pBaseCommand)); break;
@ -1565,6 +1584,57 @@ void CCommandProcessorFragment_OpenGL2::Cmd_Init(const SCommand_Init *pCommand)
}
}
void CCommandProcessorFragment_OpenGL2::Cmd_RenderTex3D(const CCommandBuffer::SCommand_RenderTex3D *pCommand)
{
if(m_HasShaders)
{
CGLSLPrimitiveProgram *pProgram = NULL;
if(pCommand->m_State.m_Texture >= 0 && pCommand->m_State.m_Texture < CCommandBuffer::MAX_TEXTURES)
{
pProgram = m_pPrimitive3DProgramTextured;
}
else
pProgram = m_pPrimitive3DProgram;
UseProgram(pProgram);
SetState(pCommand->m_State, pProgram, true);
}
else
{
CCommandProcessorFragment_OpenGL::SetState(pCommand->m_State, true);
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(pCommand->m_pVertices[0]), pCommand->m_pVertices);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(pCommand->m_pVertices[0]), (uint8_t *)pCommand->m_pVertices + (ptrdiff_t)(sizeof(vec2)));
glTexCoordPointer(3, GL_FLOAT, sizeof(pCommand->m_pVertices[0]), (uint8_t *)pCommand->m_pVertices + (ptrdiff_t)(sizeof(vec2) + sizeof(unsigned char) * 4));
switch(pCommand->m_PrimType)
{
case CCommandBuffer::PRIMTYPE_QUADS:
glDrawArrays(GL_QUADS, 0, pCommand->m_PrimCount * 4);
break;
case CCommandBuffer::PRIMTYPE_TRIANGLES:
glDrawArrays(GL_TRIANGLES, 0, pCommand->m_PrimCount * 3);
break;
default:
dbg_msg("render", "unknown primtype %d\n", pCommand->m_Cmd);
};
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if(m_HasShaders)
{
glUseProgram(0);
}
}
void CCommandProcessorFragment_OpenGL2::Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand)
{
int Index = pCommand->m_BufferIndex;
@ -2104,6 +2174,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand
m_pPrimitiveProgram = new CGLSLPrimitiveProgram;
m_pTileProgram = new CGLSLTileProgram;
m_pTileProgramTextured = new CGLSLTileProgram;
m_pPrimitive3DProgram = new CGLSLPrimitiveProgram;
m_pPrimitive3DProgramTextured = new CGLSLPrimitiveProgram;
m_pBorderTileProgram = new CGLSLTileProgram;
m_pBorderTileProgramTextured = new CGLSLTileProgram;
m_pBorderTileLineProgram = new CGLSLTileProgram;
@ -2138,6 +2210,46 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand
m_pPrimitiveProgram->m_LocIsTextured = m_pPrimitiveProgram->GetUniformLoc("isTextured");
m_pPrimitiveProgram->m_LocTextureSampler = m_pPrimitiveProgram->GetUniformLoc("textureSampler");
}
{
CGLSL PrimitiveVertexShader;
CGLSL PrimitiveFragmentShader;
ShaderCompiler.AddDefine("TW_MODERN_GL", "");
PrimitiveVertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/pipeline.vert", GL_VERTEX_SHADER);
PrimitiveFragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/pipeline.frag", GL_FRAGMENT_SHADER);
ShaderCompiler.ClearDefines();
m_pPrimitive3DProgram->CreateProgram();
m_pPrimitive3DProgram->AddShader(&PrimitiveVertexShader);
m_pPrimitive3DProgram->AddShader(&PrimitiveFragmentShader);
m_pPrimitive3DProgram->LinkProgram();
UseProgram(m_pPrimitive3DProgram);
m_pPrimitive3DProgram->m_LocPos = m_pPrimitive3DProgram->GetUniformLoc("gPos");
}
{
CGLSL PrimitiveVertexShader;
CGLSL PrimitiveFragmentShader;
ShaderCompiler.AddDefine("TW_MODERN_GL", "");
ShaderCompiler.AddDefine("TW_TEXTURED", "");
if(!pCommand->m_pCapabilities->m_2DArrayTextures)
ShaderCompiler.AddDefine("TW_3D_TEXTURED", "");
PrimitiveVertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/pipeline.vert", GL_VERTEX_SHADER);
PrimitiveFragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/pipeline.frag", GL_FRAGMENT_SHADER);
ShaderCompiler.ClearDefines();
m_pPrimitive3DProgramTextured->CreateProgram();
m_pPrimitive3DProgramTextured->AddShader(&PrimitiveVertexShader);
m_pPrimitive3DProgramTextured->AddShader(&PrimitiveFragmentShader);
m_pPrimitive3DProgramTextured->LinkProgram();
UseProgram(m_pPrimitive3DProgramTextured);
m_pPrimitive3DProgramTextured->m_LocPos = m_pPrimitive3DProgramTextured->GetUniformLoc("gPos");
m_pPrimitive3DProgramTextured->m_LocTextureSampler = m_pPrimitive3DProgramTextured->GetUniformLoc("gTextureSampler");
}
{
CGLSL VertexShader;
CGLSL FragmentShader;
@ -2375,6 +2487,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand
glGenBuffers(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawBufferID);
glGenVertexArrays(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawVertexID);
glGenBuffers(1, &m_PrimitiveDrawBufferIDTex3D);
glGenVertexArrays(1, &m_PrimitiveDrawVertexIDTex3D);
m_UsePreinitializedVertexBuffer = g_Config.m_GfxUsePreinitBuffer;
@ -2396,6 +2510,19 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand
m_LastIndexBufferBound[i] = 0;
}
glBindBuffer(GL_ARRAY_BUFFER, m_PrimitiveDrawBufferIDTex3D);
glBindVertexArray(m_PrimitiveDrawVertexIDTex3D);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(CCommandBuffer::SVertexTex3DStream), 0);
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(CCommandBuffer::SVertexTex3DStream), (void *)(sizeof(float) * 2));
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(CCommandBuffer::SVertexTex3DStream), (void *)(sizeof(float) * 2 + sizeof(unsigned char) * 4));
if(m_UsePreinitializedVertexBuffer)
glBufferData(GL_ARRAY_BUFFER, sizeof(CCommandBuffer::SVertexTex3DStream) * CCommandBuffer::MAX_VERTICES, NULL, GL_STREAM_DRAW);
//query the image max size only once
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_MaxTexSize);
@ -2449,6 +2576,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Shutdown(const SCommand_Shutdown *
m_pQuadProgramTextured->DeleteProgram();
m_pTileProgram->DeleteProgram();
m_pTileProgramTextured->DeleteProgram();
m_pPrimitive3DProgram->DeleteProgram();
m_pPrimitive3DProgramTextured->DeleteProgram();
m_pTextProgram->DeleteProgram();
m_pSpriteProgram->DeleteProgram();
m_pSpriteProgramMultiple->DeleteProgram();
@ -2463,6 +2592,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Shutdown(const SCommand_Shutdown *
delete m_pQuadProgramTextured;
delete m_pTileProgram;
delete m_pTileProgramTextured;
delete m_pPrimitive3DProgram;
delete m_pPrimitive3DProgramTextured;
delete m_pTextProgram;
delete m_pSpriteProgram;
delete m_pSpriteProgramMultiple;
@ -2471,6 +2602,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Shutdown(const SCommand_Shutdown *
glDeleteBuffers(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawBufferID);
glDeleteBuffers(1, &m_QuadDrawIndexBufferID);
glDeleteVertexArrays(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawVertexID);
glDeleteBuffers(1, &m_PrimitiveDrawBufferIDTex3D);
glDeleteVertexArrays(1, &m_PrimitiveDrawVertexIDTex3D);
for(int i = 0; i < CCommandBuffer::MAX_TEXTURES; ++i)
{
@ -2740,7 +2873,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Clear(const CCommandBuffer::SComma
glClear(GL_COLOR_BUFFER_BIT);
}
void CCommandProcessorFragment_OpenGL3_3::UploadStreamBufferData(unsigned int PrimitiveType, const void* pVertices, unsigned int PrimitiveCount)
void CCommandProcessorFragment_OpenGL3_3::UploadStreamBufferData(unsigned int PrimitiveType, const void *pVertices, size_t VertSize, unsigned int PrimitiveCount, bool AsTex3D)
{
int Count = 0;
switch (PrimitiveType)
@ -2755,16 +2888,19 @@ void CCommandProcessorFragment_OpenGL3_3::UploadStreamBufferData(unsigned int Pr
return;
};
glBindBuffer(GL_ARRAY_BUFFER, m_PrimitiveDrawBufferID[m_LastStreamBuffer]);
if(AsTex3D)
glBindBuffer(GL_ARRAY_BUFFER, m_PrimitiveDrawBufferIDTex3D);
else
glBindBuffer(GL_ARRAY_BUFFER, m_PrimitiveDrawBufferID[m_LastStreamBuffer]);
if(!m_UsePreinitializedVertexBuffer)
glBufferData(GL_ARRAY_BUFFER, sizeof(CCommandBuffer::SVertex) * Count, pVertices, GL_STREAM_DRAW);
glBufferData(GL_ARRAY_BUFFER, VertSize * Count, pVertices, GL_STREAM_DRAW);
else
{
// This is better for some iGPUs. Probably due to not initializing a new buffer in the system memory again and again...(driver dependent)
void *pData = glMapBufferRange(GL_ARRAY_BUFFER, 0, sizeof(CCommandBuffer::SVertex) * Count, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
void *pData = glMapBufferRange(GL_ARRAY_BUFFER, 0, VertSize * Count, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
mem_copy(pData, pVertices, sizeof(CCommandBuffer::SVertex) * Count);
mem_copy(pData, pVertices, VertSize * Count);
glUnmapBuffer(GL_ARRAY_BUFFER);
}
@ -2775,7 +2911,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Render(const CCommandBuffer::SComm
UseProgram(m_pPrimitiveProgram);
SetState(pCommand->m_State, m_pPrimitiveProgram);
UploadStreamBufferData(pCommand->m_PrimType, pCommand->m_pVertices, pCommand->m_PrimCount);
UploadStreamBufferData(pCommand->m_PrimType, pCommand->m_pVertices, sizeof(CCommandBuffer::SVertex), pCommand->m_PrimCount);
glBindVertexArray(m_PrimitiveDrawVertexID[m_LastStreamBuffer]);
@ -2800,6 +2936,33 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Render(const CCommandBuffer::SComm
m_LastStreamBuffer = (m_LastStreamBuffer + 1 >= MAX_STREAM_BUFFER_COUNT ? 0 : m_LastStreamBuffer + 1);
}
void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderTex3D(const CCommandBuffer::SCommand_RenderTex3D *pCommand)
{
CGLSLPrimitiveProgram *pProg = m_pPrimitive3DProgram;
if(pCommand->m_State.m_Texture >= 0 && pCommand->m_State.m_Texture < CCommandBuffer::MAX_TEXTURES)
pProg = m_pPrimitive3DProgramTextured;
UseProgram(pProg);
SetState(pCommand->m_State, pProg, true);
UploadStreamBufferData(pCommand->m_PrimType, pCommand->m_pVertices, sizeof(CCommandBuffer::SVertexTex3DStream), pCommand->m_PrimCount, true);
glBindVertexArray(m_PrimitiveDrawVertexIDTex3D);
switch(pCommand->m_PrimType)
{
// We don't support GL_QUADS due to core profile
case CCommandBuffer::PRIMTYPE_LINES:
glDrawArrays(GL_LINES, 0, pCommand->m_PrimCount * 2);
break;
case CCommandBuffer::PRIMTYPE_QUADS:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID);
glDrawElements(GL_TRIANGLES, pCommand->m_PrimCount * 6, GL_UNSIGNED_INT, 0);
break;
default:
dbg_msg("render", "unknown primtype %d\n", pCommand->m_Cmd);
};
}
void CCommandProcessorFragment_OpenGL3_3::Cmd_Screenshot(const CCommandBuffer::SCommand_Screenshot *pCommand)
{
// fetch image data
@ -3317,12 +3480,12 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderText(const CCommandBuffer::S
void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderTextStream(const CCommandBuffer::SCommand_RenderTextStream *pCommand)
{
if(pCommand->m_QuadNum == 0)
if(pCommand->m_PrimCount == 0)
{
return; //nothing to draw
}
UploadStreamBufferData(CCommandBuffer::PRIMTYPE_QUADS, pCommand->m_pVertices, pCommand->m_QuadNum);
UploadStreamBufferData(CCommandBuffer::PRIMTYPE_QUADS, pCommand->m_pVertices, sizeof(CCommandBuffer::SVertex), pCommand->m_PrimCount);
glBindVertexArray(m_PrimitiveDrawVertexID[m_LastStreamBuffer]);
if(m_LastIndexBufferBound[m_LastStreamBuffer] != m_QuadDrawIndexBufferID)
@ -3333,7 +3496,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderTextStream(const CCommandBuf
float aTextColor[4] = { 1.f, 1.f, 1.f, 1.f };
RenderText(pCommand->m_State, pCommand->m_QuadNum * 6, pCommand->m_TextTextureIndex, pCommand->m_TextOutlineTextureIndex, pCommand->m_TextureSize, aTextColor, pCommand->m_aTextOutlineColor);
RenderText(pCommand->m_State, pCommand->m_PrimCount * 6, pCommand->m_TextTextureIndex, pCommand->m_TextOutlineTextureIndex, pCommand->m_TextureSize, aTextColor, pCommand->m_aTextOutlineColor);
m_LastStreamBuffer = (m_LastStreamBuffer + 1 >= MAX_STREAM_BUFFER_COUNT ? 0 : m_LastStreamBuffer + 1);
}

View file

@ -177,6 +177,7 @@ protected:
virtual void Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand);
virtual void Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand);
virtual void Cmd_Render(const CCommandBuffer::SCommand_Render *pCommand);
virtual void Cmd_RenderTex3D(const CCommandBuffer::SCommand_RenderTex3D *pCommand) {}
virtual void Cmd_Screenshot(const CCommandBuffer::SCommand_Screenshot *pCommand);
virtual void Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand) {}
@ -241,6 +242,8 @@ protected:
void Cmd_Init(const SCommand_Init *pCommand) override;
void Cmd_RenderTex3D(const CCommandBuffer::SCommand_RenderTex3D *pCommand) override;
void Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand) override;
void Cmd_RecreateBufferObject(const CCommandBuffer::SCommand_RecreateBufferObject *pCommand) override;
void Cmd_UpdateBufferObject(const CCommandBuffer::SCommand_UpdateBufferObject *pCommand) override;
@ -304,7 +307,9 @@ class CCommandProcessorFragment_OpenGL3_3 : public CCommandProcessorFragment_Ope
GLuint m_LastProgramID;
GLuint m_PrimitiveDrawVertexID[MAX_STREAM_BUFFER_COUNT];
GLuint m_PrimitiveDrawVertexIDTex3D;
GLuint m_PrimitiveDrawBufferID[MAX_STREAM_BUFFER_COUNT];
GLuint m_PrimitiveDrawBufferIDTex3D;
GLuint m_LastIndexBufferBound[MAX_STREAM_BUFFER_COUNT];
@ -334,8 +339,8 @@ protected:
bool IsNewApi() override { return true; }
void UseProgram(CGLSLTWProgram *pProgram);
void UploadStreamBufferData(unsigned int PrimitiveType, const void* pVertices, unsigned int PrimitiveCount);
void RenderText(const CCommandBuffer::SState& State, int DrawNum, int TextTextureIndex, int TextOutlineTextureIndex, int TextureSize, const float* pTextColor, const float* pTextOutlineColor);
void UploadStreamBufferData(unsigned int PrimitiveType, const void *pVertices, size_t VertSize, unsigned int PrimitiveCount, bool AsTex3D = false);
void RenderText(const CCommandBuffer::SState &State, int DrawNum, int TextTextureIndex, int TextOutlineTextureIndex, int TextureSize, const float *pTextColor, const float *pTextOutlineColor);
void Cmd_Init(const SCommand_Init *pCommand) override;
void Cmd_Shutdown(const SCommand_Shutdown *pCommand) override;
@ -344,6 +349,7 @@ protected:
void Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand) override;
void Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand) override;
void Cmd_Render(const CCommandBuffer::SCommand_Render *pCommand) override;
void Cmd_RenderTex3D(const CCommandBuffer::SCommand_RenderTex3D *pCommand) override;
void Cmd_Screenshot(const CCommandBuffer::SCommand_Screenshot *pCommand) override;
void Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand) override;

View file

@ -54,133 +54,46 @@ static CVideoMode g_aFakeModes[] = {
void CGraphics_Threaded::FlushVertices(bool KeepVertices)
{
if(m_NumVertices == 0)
return;
size_t VertSize = sizeof(CCommandBuffer::SVertex);
int NumVerts = m_NumVertices;
if(!KeepVertices)
m_NumVertices = 0;
CCommandBuffer::SCommand_Render Cmd;
Cmd.m_State = m_State;
int PrimType, PrimCount, NumVerts;
size_t VertSize = sizeof(CCommandBuffer::SVertex);
FlushVerticesImpl(KeepVertices, PrimType, PrimCount, NumVerts, Cmd, VertSize);
if(m_Drawing == DRAWING_QUADS)
if(Cmd.m_pVertices != NULL)
{
if(g_Config.m_GfxQuadAsTriangle && !m_IsNewOpenGL)
{
Cmd.m_PrimType = CCommandBuffer::PRIMTYPE_TRIANGLES;
Cmd.m_PrimCount = NumVerts/3;
}
else
{
Cmd.m_PrimType = CCommandBuffer::PRIMTYPE_QUADS;
Cmd.m_PrimCount = NumVerts/4;
}
mem_copy(Cmd.m_pVertices, m_aVertices, VertSize * NumVerts);
}
else if(m_Drawing == DRAWING_LINES)
{
Cmd.m_PrimType = CCommandBuffer::PRIMTYPE_LINES;
Cmd.m_PrimCount = NumVerts/2;
}
else
return;
Cmd.m_pVertices = (CCommandBuffer::SVertex *)m_pCommandBuffer->AllocData(VertSize*NumVerts);
if(Cmd.m_pVertices == 0x0)
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pVertices = (CCommandBuffer::SVertex *)m_pCommandBuffer->AllocData(VertSize*NumVerts);
if(Cmd.m_pVertices == 0x0)
{
dbg_msg("graphics", "failed to allocate data for vertices");
return;
}
}
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pVertices = (CCommandBuffer::SVertex *)m_pCommandBuffer->AllocData(VertSize*NumVerts);
if(Cmd.m_pVertices == 0x0)
{
dbg_msg("graphics", "failed to allocate data for vertices");
return;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for render command");
return;
}
}
mem_copy(Cmd.m_pVertices, m_aVertices, VertSize*NumVerts);
}
void CGraphics_Threaded::FlushTextVertices(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float* pOutlineTextColor)
{
if(m_NumVertices == 0)
return;
size_t VertSize = 0;
VertSize = sizeof(CCommandBuffer::SVertex);
int NumVerts = m_NumVertices;
m_NumVertices = 0;
CCommandBuffer::SCommand_RenderTextStream Cmd;
Cmd.m_State = m_State;
int PrimType, PrimCount, NumVerts;
size_t VertSize = sizeof(CCommandBuffer::SVertex);
Cmd.m_TextureSize = TextureSize;
Cmd.m_TextTextureIndex = TextTextureIndex;
Cmd.m_TextOutlineTextureIndex = TextOutlineTextureIndex;
mem_copy(Cmd.m_aTextOutlineColor, pOutlineTextColor, sizeof(Cmd.m_aTextOutlineColor));
Cmd.m_QuadNum = NumVerts / 4;
Cmd.m_pVertices = (CCommandBuffer::SVertex *)m_pCommandBuffer->AllocData(VertSize*NumVerts);
if(Cmd.m_pVertices == 0x0)
FlushVerticesImpl(false, PrimType, PrimCount, NumVerts, Cmd, VertSize);
if(Cmd.m_pVertices != NULL)
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pVertices = (CCommandBuffer::SVertex *)m_pCommandBuffer->AllocData(VertSize*NumVerts);
if(Cmd.m_pVertices == 0x0)
{
dbg_msg("graphics", "failed to allocate data for vertices");
return;
}
mem_copy(Cmd.m_pVertices, m_aVertices, VertSize * NumVerts);
}
}
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
void CGraphics_Threaded::FlushVerticesTex3D()
{
CCommandBuffer::SCommand_RenderTex3D Cmd;
int PrimType, PrimCount, NumVerts;
size_t VertSize = sizeof(CCommandBuffer::SVertexTex3DStream);
FlushVerticesImpl(false, PrimType, PrimCount, NumVerts, Cmd, VertSize);
if(Cmd.m_pVertices != NULL)
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pVertices = (CCommandBuffer::SVertex *)m_pCommandBuffer->AllocData(VertSize*NumVerts);
if(Cmd.m_pVertices == 0x0)
{
dbg_msg("graphics", "failed to allocate data for vertices");
return;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for render command");
return;
}
mem_copy(Cmd.m_pVertices, m_aVerticesTex3D, VertSize * NumVerts);
}
mem_copy(Cmd.m_pVertices, m_aVertices, VertSize*NumVerts);
}
void CGraphics_Threaded::AddVertices(int Count)
@ -190,21 +103,16 @@ void CGraphics_Threaded::AddVertices(int Count)
FlushVertices();
}
void CGraphics_Threaded::Rotate(const CCommandBuffer::SPoint &rCenter, CCommandBuffer::SVertex *pPoints, int NumPoints)
void CGraphics_Threaded::AddVertices(int Count, CCommandBuffer::SVertex *pVertices)
{
float c = cosf(m_Rotation);
float s = sinf(m_Rotation);
float x, y;
int i;
AddVertices(Count);
}
CCommandBuffer::SVertex *pVertices = pPoints;
for(i = 0; i < NumPoints; i++)
{
x = pVertices[i].m_Pos.x - rCenter.x;
y = pVertices[i].m_Pos.y - rCenter.y;
pVertices[i].m_Pos.x = x * c - y * s + rCenter.x;
pVertices[i].m_Pos.y = x * s + y * c + rCenter.y;
}
void CGraphics_Threaded::AddVertices(int Count, CCommandBuffer::SVertexTex3DStream *pVertices)
{
m_NumVertices += Count;
if((m_NumVertices + Count) >= MAX_VERTICES)
FlushVerticesTex3D();
}
CGraphics_Threaded::CGraphics_Threaded()
@ -659,6 +567,18 @@ void CGraphics_Threaded::TextQuadsEnd(int TextureSize, int TextTextureIndex, int
m_Drawing = 0;
}
void CGraphics_Threaded::QuadsTex3DBegin()
{
QuadsBegin();
}
void CGraphics_Threaded::QuadsTex3DEnd()
{
dbg_assert(m_Drawing == DRAWING_QUADS, "called Graphics()->QuadsEnd without begin");
FlushVerticesTex3D();
m_Drawing = 0;
}
void CGraphics_Threaded::QuadsEndKeepVertices()
{
dbg_assert(m_Drawing == DRAWING_QUADS, "called Graphics()->QuadsEndKeepVertices without begin");
@ -813,15 +733,6 @@ void CGraphics_Threaded::ChangeColorOfQuadVertices(int QuadOffset, unsigned char
}
}
void CGraphics_Threaded::SetColor(CCommandBuffer::SVertex *pVertex, int ColorIndex)
{
CCommandBuffer::SVertex *pVert = pVertex;
pVert->m_Color.r = m_aColor[ColorIndex].r;
pVert->m_Color.g = m_aColor[ColorIndex].g;
pVert->m_Color.b = m_aColor[ColorIndex].b;
pVert->m_Color.a = m_aColor[ColorIndex].a;
}
void CGraphics_Threaded::QuadsSetSubset(float TlU, float TlV, float BrU, float BrV)
{
m_aTexture[0].u = TlU; m_aTexture[1].u = BrU;
@ -833,12 +744,17 @@ void CGraphics_Threaded::QuadsSetSubset(float TlU, float TlV, float BrU, float B
void CGraphics_Threaded::QuadsSetSubsetFree(
float x0, float y0, float x1, float y1,
float x2, float y2, float x3, float y3)
float x2, float y2, float x3, float y3, int Index)
{
m_aTexture[0].u = x0; m_aTexture[0].v = y0;
m_aTexture[1].u = x1; m_aTexture[1].v = y1;
m_aTexture[2].u = x2; m_aTexture[2].v = y2;
m_aTexture[3].u = x3; m_aTexture[3].v = y3;
m_aTexture[0].u = x0;
m_aTexture[0].v = y0;
m_aTexture[1].u = x1;
m_aTexture[1].v = y1;
m_aTexture[2].u = x2;
m_aTexture[2].v = y2;
m_aTexture[3].u = x3;
m_aTexture[3].v = y3;
m_CurIndex = Index;
}
void CGraphics_Threaded::QuadsDraw(CQuadItem *pArray, int Num)
@ -854,92 +770,35 @@ void CGraphics_Threaded::QuadsDraw(CQuadItem *pArray, int Num)
void CGraphics_Threaded::QuadsDrawTL(const CQuadItem *pArray, int Num)
{
CCommandBuffer::SPoint Center;
QuadsDrawTLImpl(m_aVertices, pArray, Num);
}
dbg_assert(m_Drawing == DRAWING_QUADS, "called Graphics()->QuadsDrawTL without begin");
void CGraphics_Threaded::QuadsTex3DDrawTL(const CQuadItem *pArray, int Num)
{
int CurNumVert = m_NumVertices;
int VertNum = 0;
if(g_Config.m_GfxQuadAsTriangle && !m_IsNewOpenGL)
{
for(int i = 0; i < Num; ++i)
{
// first triangle
m_aVertices[m_NumVertices + 6*i].m_Pos.x = pArray[i].m_X;
m_aVertices[m_NumVertices + 6*i].m_Pos.y = pArray[i].m_Y;
m_aVertices[m_NumVertices + 6*i].m_Tex = m_aTexture[0];
SetColor(&m_aVertices[m_NumVertices + 6*i], 0);
m_aVertices[m_NumVertices + 6*i + 1].m_Pos.x = pArray[i].m_X + pArray[i].m_Width;
m_aVertices[m_NumVertices + 6*i + 1].m_Pos.y = pArray[i].m_Y;
m_aVertices[m_NumVertices + 6*i + 1].m_Tex = m_aTexture[1];
SetColor(&m_aVertices[m_NumVertices + 6*i + 1], 1);
m_aVertices[m_NumVertices + 6*i + 2].m_Pos.x = pArray[i].m_X + pArray[i].m_Width;
m_aVertices[m_NumVertices + 6*i + 2].m_Pos.y = pArray[i].m_Y + pArray[i].m_Height;
m_aVertices[m_NumVertices + 6*i + 2].m_Tex = m_aTexture[2];
SetColor(&m_aVertices[m_NumVertices + 6*i + 2], 2);
// second triangle
m_aVertices[m_NumVertices + 6*i + 3].m_Pos.x = pArray[i].m_X;
m_aVertices[m_NumVertices + 6*i + 3].m_Pos.y = pArray[i].m_Y;
m_aVertices[m_NumVertices + 6*i + 3].m_Tex = m_aTexture[0];
SetColor(&m_aVertices[m_NumVertices + 6*i + 3], 0);
m_aVertices[m_NumVertices + 6*i + 4].m_Pos.x = pArray[i].m_X + pArray[i].m_Width;
m_aVertices[m_NumVertices + 6*i + 4].m_Pos.y = pArray[i].m_Y + pArray[i].m_Height;
m_aVertices[m_NumVertices + 6*i + 4].m_Tex = m_aTexture[2];
SetColor(&m_aVertices[m_NumVertices + 6*i + 4], 2);
m_aVertices[m_NumVertices + 6*i + 5].m_Pos.x = pArray[i].m_X;
m_aVertices[m_NumVertices + 6*i + 5].m_Pos.y = pArray[i].m_Y + pArray[i].m_Height;
m_aVertices[m_NumVertices + 6*i + 5].m_Tex = m_aTexture[3];
SetColor(&m_aVertices[m_NumVertices + 6*i + 5], 3);
if(m_Rotation != 0)
{
Center.x = pArray[i].m_X + pArray[i].m_Width/2;
Center.y = pArray[i].m_Y + pArray[i].m_Height/2;
Rotate(Center, &m_aVertices[m_NumVertices + 6*i], 6);
}
}
AddVertices(3*2*Num);
VertNum = 6;
}
else
{
for(int i = 0; i < Num; ++i)
{
m_aVertices[m_NumVertices + 4*i].m_Pos.x = pArray[i].m_X;
m_aVertices[m_NumVertices + 4*i].m_Pos.y = pArray[i].m_Y;
m_aVertices[m_NumVertices + 4*i].m_Tex = m_aTexture[0];
SetColor(&m_aVertices[m_NumVertices + 4*i], 0);
m_aVertices[m_NumVertices + 4*i + 1].m_Pos.x = pArray[i].m_X + pArray[i].m_Width;
m_aVertices[m_NumVertices + 4*i + 1].m_Pos.y = pArray[i].m_Y;
m_aVertices[m_NumVertices + 4*i + 1].m_Tex = m_aTexture[1];
SetColor(&m_aVertices[m_NumVertices + 4*i + 1], 1);
m_aVertices[m_NumVertices + 4*i + 2].m_Pos.x = pArray[i].m_X + pArray[i].m_Width;
m_aVertices[m_NumVertices + 4*i + 2].m_Pos.y = pArray[i].m_Y + pArray[i].m_Height;
m_aVertices[m_NumVertices + 4*i + 2].m_Tex = m_aTexture[2];
SetColor(&m_aVertices[m_NumVertices + 4*i + 2], 2);
m_aVertices[m_NumVertices + 4*i + 3].m_Pos.x = pArray[i].m_X;
m_aVertices[m_NumVertices + 4*i + 3].m_Pos.y = pArray[i].m_Y + pArray[i].m_Height;
m_aVertices[m_NumVertices + 4*i + 3].m_Tex = m_aTexture[3];
SetColor(&m_aVertices[m_NumVertices + 4*i + 3], 3);
if(m_Rotation != 0)
{
Center.x = pArray[i].m_X + pArray[i].m_Width/2;
Center.y = pArray[i].m_Y + pArray[i].m_Height/2;
Rotate(Center, &m_aVertices[m_NumVertices + 4*i], 4);
}
}
AddVertices(4*Num);
VertNum = 4;
}
for(int i = 0; i < Num; ++i)
{
for(int n = 0; n < VertNum; ++n)
{
if(HasTextureArrays())
m_aVerticesTex3D[CurNumVert + VertNum * i + n].m_Tex.w = (float)m_CurIndex;
else
m_aVerticesTex3D[CurNumVert + VertNum * i + n].m_Tex.w = ((float)m_CurIndex + 0.5f) / 256.f;
}
}
QuadsDrawTLImpl(m_aVerticesTex3D, pArray, Num);
}
void CGraphics_Threaded::QuadsDrawFreeform(const CFreeformItem *pArray, int Num)

View file

@ -84,6 +84,7 @@ public:
// rendering
CMD_CLEAR,
CMD_RENDER,
CMD_RENDER_TEX3D,
//opengl 2.0+ commands (some are just emulated and only exist in opengl 3.3+)
CMD_CREATE_BUFFER_OBJECT, // create vbo
@ -163,6 +164,8 @@ public:
typedef GL_SColorf SColorf;
typedef GL_SColor SColor;
typedef GL_SVertex SVertex;
typedef GL_SVertexTex3D SVertexTex3D;
typedef GL_SVertexTex3DStream SVertexTex3DStream;
struct SCommand
{
@ -215,6 +218,16 @@ public:
SVertex *m_pVertices; // you should use the command buffer data to allocate vertices for this command
};
struct SCommand_RenderTex3D : public SCommand
{
SCommand_RenderTex3D()
: SCommand(CMD_RENDER_TEX3D) {}
SState m_State;
unsigned m_PrimType;
unsigned m_PrimCount;
SVertexTex3DStream *m_pVertices; // you should use the command buffer data to allocate vertices for this command
};
struct SCommand_CreateBufferObject : public SCommand
{
SCommand_CreateBufferObject() : SCommand(CMD_CREATE_BUFFER_OBJECT) {}
@ -379,7 +392,8 @@ public:
SState m_State;
SVertex *m_pVertices;
int m_QuadNum;
unsigned m_PrimType;
unsigned m_PrimCount;
int m_TextureSize;
@ -644,7 +658,10 @@ class CGraphics_Threaded : public IEngineGraphics
class IStorage *m_pStorage;
class IConsole *m_pConsole;
int m_CurIndex;
CCommandBuffer::SVertex m_aVertices[MAX_VERTICES];
CCommandBuffer::SVertexTex3DStream m_aVerticesTex3D[MAX_VERTICES];
int m_NumVertices;
CCommandBuffer::SColor m_aColor[4];
@ -715,7 +732,26 @@ class CGraphics_Threaded : public IEngineGraphics
void* AllocCommandBufferData(unsigned AllocSize);
void AddVertices(int Count);
void Rotate(const CCommandBuffer::SPoint &rCenter, CCommandBuffer::SVertex *pPoints, int NumPoints);
void AddVertices(int Count, CCommandBuffer::SVertex *pVertices);
void AddVertices(int Count, CCommandBuffer::SVertexTex3DStream *pVertices);
template<typename TName>
void Rotate(const CCommandBuffer::SPoint &rCenter, TName *pPoints, int NumPoints)
{
float c = cosf(m_Rotation);
float s = sinf(m_Rotation);
float x, y;
int i;
TName *pVertices = pPoints;
for(i = 0; i < NumPoints; i++)
{
x = pVertices[i].m_Pos.x - rCenter.x;
y = pVertices[i].m_Pos.y - rCenter.y;
pVertices[i].m_Pos.x = x * c - y * s + rCenter.x;
pVertices[i].m_Pos.y = x * s + y * c + rCenter.y;
}
}
void KickCommandBuffer();
@ -763,10 +799,22 @@ public:
void QuadsEnd() override;
void TextQuadsBegin() override;
void TextQuadsEnd(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) override;
void QuadsTex3DBegin() override;
void QuadsTex3DEnd() override;
void QuadsEndKeepVertices() override;
void QuadsDrawCurrentVertices(bool KeepVertices = true) override;
void QuadsSetRotation(float Angle) override;
template<typename TName>
void SetColor(TName *pVertex, int ColorIndex)
{
TName *pVert = pVertex;
pVert->m_Color.r = m_aColor[ColorIndex].r;
pVert->m_Color.g = m_aColor[ColorIndex].g;
pVert->m_Color.b = m_aColor[ColorIndex].b;
pVert->m_Color.a = m_aColor[ColorIndex].a;
}
void SetColorVertex(const CColorVertex *pArray, int Num) override;
void SetColor(float r, float g, float b, float a) override;
void SetColor(ColorRGBA rgb) override;
@ -776,15 +824,108 @@ public:
void ChangeColorOfCurrentQuadVertices(float r, float g, float b, float a) override;
void ChangeColorOfQuadVertices(int QuadOffset, unsigned char r, unsigned char g, unsigned char b, unsigned char a) override;
void SetColor(CCommandBuffer::SVertex *pVertex, int ColorIndex);
void QuadsSetSubset(float TlU, float TlV, float BrU, float BrV) override;
void QuadsSetSubsetFree(
float x0, float y0, float x1, float y1,
float x2, float y2, float x3, float y3) override;
float x2, float y2, float x3, float y3, int Index = -1) override;
void QuadsDraw(CQuadItem *pArray, int Num) override;
template<typename TName>
void QuadsDrawTLImpl(TName *pVertices, const CQuadItem *pArray, int Num)
{
CCommandBuffer::SPoint Center;
dbg_assert(m_Drawing == DRAWING_QUADS, "called Graphics()->QuadsDrawTL without begin");
if(g_Config.m_GfxQuadAsTriangle && !m_IsNewOpenGL)
{
for(int i = 0; i < Num; ++i)
{
// first triangle
pVertices[m_NumVertices + 6 * i].m_Pos.x = pArray[i].m_X;
pVertices[m_NumVertices + 6 * i].m_Pos.y = pArray[i].m_Y;
pVertices[m_NumVertices + 6 * i].m_Tex = m_aTexture[0];
SetColor(&pVertices[m_NumVertices + 6 * i], 0);
pVertices[m_NumVertices + 6 * i + 1].m_Pos.x = pArray[i].m_X + pArray[i].m_Width;
pVertices[m_NumVertices + 6 * i + 1].m_Pos.y = pArray[i].m_Y;
pVertices[m_NumVertices + 6 * i + 1].m_Tex = m_aTexture[1];
SetColor(&pVertices[m_NumVertices + 6 * i + 1], 1);
pVertices[m_NumVertices + 6 * i + 2].m_Pos.x = pArray[i].m_X + pArray[i].m_Width;
pVertices[m_NumVertices + 6 * i + 2].m_Pos.y = pArray[i].m_Y + pArray[i].m_Height;
pVertices[m_NumVertices + 6 * i + 2].m_Tex = m_aTexture[2];
SetColor(&pVertices[m_NumVertices + 6 * i + 2], 2);
// second triangle
pVertices[m_NumVertices + 6 * i + 3].m_Pos.x = pArray[i].m_X;
pVertices[m_NumVertices + 6 * i + 3].m_Pos.y = pArray[i].m_Y;
pVertices[m_NumVertices + 6 * i + 3].m_Tex = m_aTexture[0];
SetColor(&pVertices[m_NumVertices + 6 * i + 3], 0);
pVertices[m_NumVertices + 6 * i + 4].m_Pos.x = pArray[i].m_X + pArray[i].m_Width;
pVertices[m_NumVertices + 6 * i + 4].m_Pos.y = pArray[i].m_Y + pArray[i].m_Height;
pVertices[m_NumVertices + 6 * i + 4].m_Tex = m_aTexture[2];
SetColor(&pVertices[m_NumVertices + 6 * i + 4], 2);
pVertices[m_NumVertices + 6 * i + 5].m_Pos.x = pArray[i].m_X;
pVertices[m_NumVertices + 6 * i + 5].m_Pos.y = pArray[i].m_Y + pArray[i].m_Height;
pVertices[m_NumVertices + 6 * i + 5].m_Tex = m_aTexture[3];
SetColor(&pVertices[m_NumVertices + 6 * i + 5], 3);
if(m_Rotation != 0)
{
Center.x = pArray[i].m_X + pArray[i].m_Width / 2;
Center.y = pArray[i].m_Y + pArray[i].m_Height / 2;
Rotate(Center, &pVertices[m_NumVertices + 6 * i], 6);
}
}
AddVertices(3 * 2 * Num, pVertices);
}
else
{
for(int i = 0; i < Num; ++i)
{
pVertices[m_NumVertices + 4 * i].m_Pos.x = pArray[i].m_X;
pVertices[m_NumVertices + 4 * i].m_Pos.y = pArray[i].m_Y;
pVertices[m_NumVertices + 4 * i].m_Tex = m_aTexture[0];
SetColor(&pVertices[m_NumVertices + 4 * i], 0);
pVertices[m_NumVertices + 4 * i + 1].m_Pos.x = pArray[i].m_X + pArray[i].m_Width;
pVertices[m_NumVertices + 4 * i + 1].m_Pos.y = pArray[i].m_Y;
pVertices[m_NumVertices + 4 * i + 1].m_Tex = m_aTexture[1];
SetColor(&pVertices[m_NumVertices + 4 * i + 1], 1);
pVertices[m_NumVertices + 4 * i + 2].m_Pos.x = pArray[i].m_X + pArray[i].m_Width;
pVertices[m_NumVertices + 4 * i + 2].m_Pos.y = pArray[i].m_Y + pArray[i].m_Height;
pVertices[m_NumVertices + 4 * i + 2].m_Tex = m_aTexture[2];
SetColor(&pVertices[m_NumVertices + 4 * i + 2], 2);
pVertices[m_NumVertices + 4 * i + 3].m_Pos.x = pArray[i].m_X;
pVertices[m_NumVertices + 4 * i + 3].m_Pos.y = pArray[i].m_Y + pArray[i].m_Height;
pVertices[m_NumVertices + 4 * i + 3].m_Tex = m_aTexture[3];
SetColor(&pVertices[m_NumVertices + 4 * i + 3], 3);
if(m_Rotation != 0)
{
Center.x = pArray[i].m_X + pArray[i].m_Width / 2;
Center.y = pArray[i].m_Y + pArray[i].m_Height / 2;
Rotate(Center, &pVertices[m_NumVertices + 4 * i], 4);
}
}
AddVertices(4 * Num, pVertices);
}
}
void QuadsDrawTL(const CQuadItem *pArray, int Num) override;
void QuadsTex3DDrawTL(const CQuadItem *pArray, int Num) override;
void QuadsDrawFreeform(const CFreeformItem *pArray, int Num) override;
void QuadsText(float x, float y, float Size, const char *pText) override;
@ -799,8 +940,82 @@ public:
void RenderQuadContainerAsSprite(int ContainerIndex, int QuadOffset, float X, float Y, float ScaleX = 1.f, float ScaleY = 1.f) override;
void RenderQuadContainerAsSpriteMultiple(int ContainerIndex, int QuadOffset, int DrawCount, SRenderSpriteInfo *pRenderInfo) override;
template<typename TName>
void FlushVerticesImpl(bool KeepVertices, int &PrimType, int &PrimCount, int &NumVerts, TName &Command, size_t VertSize)
{
Command.m_pVertices = NULL;
if(m_NumVertices == 0)
return;
NumVerts = m_NumVertices;
if(!KeepVertices)
m_NumVertices = 0;
if(m_Drawing == DRAWING_QUADS)
{
if(g_Config.m_GfxQuadAsTriangle && !m_IsNewOpenGL)
{
PrimType = CCommandBuffer::PRIMTYPE_TRIANGLES;
PrimCount = NumVerts / 3;
}
else
{
PrimType = CCommandBuffer::PRIMTYPE_QUADS;
PrimCount = NumVerts / 4;
}
}
else if(m_Drawing == DRAWING_LINES)
{
PrimType = CCommandBuffer::PRIMTYPE_LINES;
PrimCount = NumVerts / 2;
}
else
return;
Command.m_pVertices = (decltype(Command.m_pVertices))m_pCommandBuffer->AllocData(VertSize * NumVerts);
if(Command.m_pVertices == NULL)
{
// kick command buffer and try again
KickCommandBuffer();
Command.m_pVertices = (decltype(Command.m_pVertices))m_pCommandBuffer->AllocData(VertSize * NumVerts);
if(Command.m_pVertices == NULL)
{
dbg_msg("graphics", "failed to allocate data for vertices");
return;
}
}
Command.m_State = m_State;
Command.m_PrimType = PrimType;
Command.m_PrimCount = PrimCount;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Command))
{
// kick command buffer and try again
KickCommandBuffer();
Command.m_pVertices = (decltype(Command.m_pVertices))m_pCommandBuffer->AllocData(VertSize * NumVerts);
if(Command.m_pVertices == NULL)
{
dbg_msg("graphics", "failed to allocate data for vertices");
return;
}
if(!m_pCommandBuffer->AddCommand(Command))
{
dbg_msg("graphics", "failed to allocate memory for render command");
return;
}
}
}
void FlushVertices(bool KeepVertices = false) override;
void FlushTextVertices(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) override;
void FlushVerticesTex3D() override;
void RenderTileLayer(int BufferContainerIndex, float *pColor, char **pOffsets, unsigned int *IndicedVertexDrawNum, size_t NumIndicesOffet) override;
void RenderBorderTiles(int BufferContainerIndex, float *pColor, char *pIndexBufferOffset, float *pOffset, float *pDir, int JumpIndex, unsigned int DrawNum) override;

View file

@ -96,10 +96,28 @@ public:
int m_Red, m_Green, m_Blue;
};
struct GL_SPoint { float x, y; };
struct GL_STexCoord { float u, v; };
struct GL_STexCoord3D { float u, v, w; };
struct GL_SColorf { float r, g, b, a; };
struct GL_SPoint
{
float x, y;
};
struct GL_STexCoord
{
float u, v;
};
struct GL_STexCoord3D
{
GL_STexCoord3D &operator=(const GL_STexCoord &TexCoord)
{
u = TexCoord.u;
v = TexCoord.v;
return *this;
}
float u, v, w;
};
struct GL_SColorf
{
float r, g, b, a;
};
//use normalized color values
struct GL_SColor { unsigned char r, g, b, a; };
@ -118,6 +136,13 @@ struct GL_SVertexTex3D
GL_STexCoord3D m_Tex;
};
struct GL_SVertexTex3DStream
{
GL_SPoint m_Pos;
GL_SColor m_Color;
GL_STexCoord3D m_Tex;
};
struct SGraphicsWarning
{
SGraphicsWarning() : m_WasShown(false) {}
@ -206,6 +231,7 @@ public:
virtual void FlushVertices(bool KeepVertices = false) = 0;
virtual void FlushTextVertices(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) = 0;
virtual void FlushVerticesTex3D() = 0;
// specific render functions
virtual void RenderTileLayer(int BufferContainerIndex, float *pColor, char **pOffsets, unsigned int *IndicedVertexDrawNum, size_t NumIndicesOffet) = 0;
@ -247,11 +273,13 @@ public:
virtual void QuadsEnd() = 0;
virtual void TextQuadsBegin() = 0;
virtual void TextQuadsEnd(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) = 0;
virtual void QuadsTex3DBegin() = 0;
virtual void QuadsTex3DEnd() = 0;
virtual void QuadsEndKeepVertices() = 0;
virtual void QuadsDrawCurrentVertices(bool KeepVertices = true) = 0;
virtual void QuadsSetRotation(float Angle) = 0;
virtual void QuadsSetSubset(float TopLeftU, float TopLeftV, float BottomRightU, float BottomRightV) = 0;
virtual void QuadsSetSubsetFree(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) = 0;
virtual void QuadsSetSubsetFree(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, int Index = -1) = 0;
struct CQuadItem
{
@ -263,6 +291,8 @@ public:
virtual void QuadsDraw(CQuadItem *pArray, int Num) = 0;
virtual void QuadsDrawTL(const CQuadItem *pArray, int Num) = 0;
virtual void QuadsTex3DDrawTL(const CQuadItem *pArray, int Num) = 0;
struct CFreeformItem
{
float m_X0, m_Y0, m_X1, m_Y1, m_X2, m_Y2, m_X3, m_Y3;

View file

@ -255,7 +255,7 @@ void CRenderTools::RenderTileRectangle(int RectX, int RectY, int RectW, int Rect
}
void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, ColorRGBA Color, int RenderFlags,
ENVELOPE_EVAL pfnEval, void *pUser, int ColorEnv, int ColorEnvOffset)
ENVELOPE_EVAL pfnEval, void *pUser, int ColorEnv, int ColorEnvOffset)
{
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
@ -276,8 +276,11 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, Color
a = aChannels[3];
}
Graphics()->QuadsBegin();
Graphics()->SetColor(Color.r*r, Color.g*g, Color.b*b, Color.a*a);
if(Graphics()->IsTileBufferingEnabled())
Graphics()->QuadsTex3DBegin();
else
Graphics()->QuadsBegin();
Graphics()->SetColor(Color.r * r, Color.g * g, Color.b * b, Color.a * a);
int StartY = (int)(ScreenY0/Scale)-1;
int StartX = (int)(ScreenX0/Scale)-1;
@ -356,7 +359,19 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, Color
float x3 = Nudge + Px0/TexSize+Frac;
float y3 = Nudge + Py1/TexSize-Frac;
if(Flags&TILEFLAG_VFLIP)
if(Graphics()->IsTileBufferingEnabled())
{
x0 = 0;
y0 = 0;
x1 = x0 + 1;
y1 = y0;
x2 = x0 + 1;
y2 = y0 + 1;
x3 = x0;
y3 = y0 + 1;
}
if(Flags & TILEFLAG_VFLIP)
{
x0 = x2;
x1 = x3;
@ -386,16 +401,28 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, Color
y1 = Tmp;
}
Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3);
IGraphics::CQuadItem QuadItem(x*Scale, y*Scale, Scale, Scale);
Graphics()->QuadsDrawTL(&QuadItem, 1);
if(Graphics()->IsTileBufferingEnabled())
{
Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3, Index);
IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale);
Graphics()->QuadsTex3DDrawTL(&QuadItem, 1);
}
else
{
Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3);
IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale);
Graphics()->QuadsDrawTL(&QuadItem, 1);
}
}
}
x += pTiles[c].m_Skip;
}
}
Graphics()->QuadsEnd();
if(Graphics()->IsTileBufferingEnabled())
Graphics()->QuadsTex3DEnd();
else
Graphics()->QuadsEnd();
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
}

View file

@ -3623,7 +3623,10 @@ void CEditor::ReplaceImage(const char *pFileName, int StorageType, void *pUser)
}
pImg->m_AutoMapper.Load(pImg->m_aName);
pImg->m_Texture = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0);
int TextureLoadFlag = pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0)
TextureLoadFlag = 0;
pImg->m_Texture = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, TextureLoadFlag, pFileName);
ImgInfo.m_pData = 0;
pEditor->SortImages();
for(int i = 0; i < pEditor->m_Map.m_lImages.size(); ++i)
@ -3674,7 +3677,10 @@ void CEditor::AddImage(const char *pFileName, int StorageType, void *pUser)
DilateImage((unsigned char *)ImgInfo.m_pData, ImgInfo.m_Width, ImgInfo.m_Height, ColorChannelCount);
}
pImg->m_Texture = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0);
int TextureLoadFlag = pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0)
TextureLoadFlag = 0;
pImg->m_Texture = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, TextureLoadFlag, pFileName);
ImgInfo.m_pData = 0;
str_copy(pImg->m_aName, aBuf, sizeof(pImg->m_aName));
pImg->m_AutoMapper.Load(pImg->m_aName);
@ -6421,13 +6427,14 @@ void CEditor::Init()
m_CheckerTexture = Graphics()->LoadTexture("editor/checker.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_BackgroundTexture = Graphics()->LoadTexture("editor/background.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_CursorTexture = Graphics()->LoadTexture("editor/cursor.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_EntitiesTexture = Graphics()->LoadTexture("editor/entities/DDNet.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
int TextureLoadFlag = Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
m_EntitiesTexture = Graphics()->LoadTexture("editor/entities/DDNet.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, TextureLoadFlag);
m_FrontTexture = Graphics()->LoadTexture("editor/front.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_TeleTexture = Graphics()->LoadTexture("editor/tele.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_SpeedupTexture = Graphics()->LoadTexture("editor/speedup.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_SwitchTexture = Graphics()->LoadTexture("editor/switch.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_TuneTexture = Graphics()->LoadTexture("editor/tune.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_FrontTexture = Graphics()->LoadTexture("editor/front.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, TextureLoadFlag);
m_TeleTexture = Graphics()->LoadTexture("editor/tele.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, TextureLoadFlag);
m_SpeedupTexture = Graphics()->LoadTexture("editor/speedup.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, TextureLoadFlag);
m_SwitchTexture = Graphics()->LoadTexture("editor/switch.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, TextureLoadFlag);
m_TuneTexture = Graphics()->LoadTexture("editor/tune.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, TextureLoadFlag);
m_TilesetPicker.m_pEditor = this;
m_TilesetPicker.MakePalette();

View file

@ -673,7 +673,10 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
if(m_pEditor->Graphics()->LoadPNG(&ImgInfo, aBuf, IStorage::TYPE_ALL))
{
*pImg = ImgInfo;
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0);
int TextureLoadFlag = m_pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0)
TextureLoadFlag = 0;
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, TextureLoadFlag, aBuf);
ImgInfo.m_pData = 0;
pImg->m_External = 1;
}
@ -686,9 +689,12 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
// copy image data
void *pData = DataFile.GetData(pItem->m_ImageData);
pImg->m_pData = malloc(pImg->m_Width*pImg->m_Height*4);
mem_copy(pImg->m_pData, pData, pImg->m_Width*pImg->m_Height*4);
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, CImageInfo::FORMAT_AUTO, 0);
pImg->m_pData = malloc(pImg->m_Width * pImg->m_Height * 4);
mem_copy(pImg->m_pData, pData, pImg->m_Width * pImg->m_Height * 4);
int TextureLoadFlag = m_pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
if(pImg->m_Width % 16 != 0 || pImg->m_Height % 16 != 0)
TextureLoadFlag = 0;
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, CImageInfo::FORMAT_AUTO, TextureLoadFlag);
}
// copy image name

View file

@ -936,6 +936,9 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox)
{
m_pEditor->m_PopupEventType = m_pEditor->POPEVENT_IMAGEDIV16;
m_pEditor->m_PopupEventActivated = true;
m_Texture = IGraphics::CTextureHandle();
m_Image = -1;
}
}
}

View file

@ -1117,7 +1117,7 @@ int CEditor::PopupEvent(CEditor *pEditor, CUIRect View, void *pContext)
else if(pEditor->m_PopupEventType == POPEVENT_PREVENTUNUSEDTILES)
pEditor->UI()->DoLabel(&Label, "Unused tiles can't be placed by default because they could get a use later and then destroy your map.\nActivate the 'Unused' switch to be able to place every tile.", 10.0f, -1, Label.w-10.0f);
else if(pEditor->m_PopupEventType == POPEVENT_IMAGEDIV16)
pEditor->UI()->DoLabel(&Label, "The width or height of this image is not divisible by 16. This is required for images used in tile layers for Teeworlds 0.7 compatibility.", 10.0f, -1, Label.w - 10.0f);
pEditor->UI()->DoLabel(&Label, "The width or height of this image is not divisible by 16. This is required for images used in tile layers.", 10.0f, -1, Label.w - 10.0f);
else if(pEditor->m_PopupEventType == POPEVENT_IMAGE_MAX)
pEditor->UI()->DoLabel(&Label, "The client only allows a maximum of 64 images.", 10.0f, -1, Label.w - 10.0f);
else if(pEditor->m_PopupEventType == POPEVENT_PLACE_BORDER_TILES)
@ -1773,7 +1773,8 @@ int CEditor::PopupEntities(CEditor *pEditor, CUIRect View, void *pContext)
str_format(aBuf, sizeof(aBuf), "editor/entities/%s.png", Name);
pEditor->Graphics()->UnloadTexture(pEditor->m_EntitiesTexture);
pEditor->m_EntitiesTexture = pEditor->Graphics()->LoadTexture(aBuf, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
int TextureLoadFlag = pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
pEditor->m_EntitiesTexture = pEditor->Graphics()->LoadTexture(aBuf, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, TextureLoadFlag);
g_UiNumPopups--;
}
}