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
#endif #endif
#ifdef TW_MODERN_GL
#ifdef TW_TEXTURED
noperspective in vec3 oTexCoord;
#endif
noperspective in vec4 oVertColor;
out vec4 FragClr;
#endif
void main() 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 #ifdef TW_TEXTURED
vec4 TexColor = texture(gTextureSampler, gl_TexCoord[0].xyz).rgba; vec4 TexColor = texture(gTextureSampler, gl_TexCoord[0].xyz).rgba;
gl_FragColor = TexColor.rgba * gl_Color.rgba; gl_FragColor = TexColor.rgba * gl_Color.rgba;
#else #else
gl_FragColor = gl_Color.rgba; gl_FragColor = gl_Color.rgba;
#endif #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; uniform mat4x2 gPos;
#ifdef TW_MODERN_GL
#ifdef TW_TEXTURED
noperspective out vec3 oTexCoord;
#endif
noperspective out vec4 oVertColor;
#endif
void main() 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); gl_Position = vec4(gPos * vec4(gl_Vertex.xy, 0.0, 1.0), 0.0, 1.0);
#ifdef TW_TEXTURED #ifdef TW_TEXTURED
gl_TexCoord[0] = gl_MultiTexCoord0; gl_TexCoord[0] = gl_MultiTexCoord0;
#endif #endif
gl_FrontColor = gl_Color.rgba; gl_FrontColor = gl_Color.rgba;
gl_BackColor = 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) switch(pBaseCommand->m_Cmd)
{ {
case CCommandProcessorFragment_OpenGL::CMD_INIT: Cmd_Init(static_cast<const SCommand_Init *>(pBaseCommand)); break; case CCommandProcessorFragment_OpenGL::CMD_INIT:
case CCommandProcessorFragment_OpenGL::CMD_SHUTDOWN: Cmd_Shutdown(static_cast<const SCommand_Shutdown *>(pBaseCommand)); break; Cmd_Init(static_cast<const SCommand_Init *>(pBaseCommand));
case CCommandBuffer::CMD_TEXTURE_CREATE: Cmd_Texture_Create(static_cast<const CCommandBuffer::SCommand_Texture_Create *>(pBaseCommand)); break; break;
case CCommandBuffer::CMD_TEXTURE_DESTROY: Cmd_Texture_Destroy(static_cast<const CCommandBuffer::SCommand_Texture_Destroy *>(pBaseCommand)); break; case CCommandProcessorFragment_OpenGL::CMD_SHUTDOWN:
case CCommandBuffer::CMD_TEXTURE_UPDATE: Cmd_Texture_Update(static_cast<const CCommandBuffer::SCommand_Texture_Update *>(pBaseCommand)); break; Cmd_Shutdown(static_cast<const SCommand_Shutdown *>(pBaseCommand));
case CCommandBuffer::CMD_CLEAR: Cmd_Clear(static_cast<const CCommandBuffer::SCommand_Clear *>(pBaseCommand)); break; break;
case CCommandBuffer::CMD_RENDER: Cmd_Render(static_cast<const CCommandBuffer::SCommand_Render *>(pBaseCommand)); break; case CCommandBuffer::CMD_TEXTURE_CREATE:
case CCommandBuffer::CMD_SCREENSHOT: Cmd_Screenshot(static_cast<const CCommandBuffer::SCommand_Screenshot *>(pBaseCommand)); break; 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_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; 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) void CCommandProcessorFragment_OpenGL2::Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand)
{ {
int Index = pCommand->m_BufferIndex; int Index = pCommand->m_BufferIndex;
@ -2104,6 +2174,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand
m_pPrimitiveProgram = new CGLSLPrimitiveProgram; m_pPrimitiveProgram = new CGLSLPrimitiveProgram;
m_pTileProgram = new CGLSLTileProgram; m_pTileProgram = new CGLSLTileProgram;
m_pTileProgramTextured = new CGLSLTileProgram; m_pTileProgramTextured = new CGLSLTileProgram;
m_pPrimitive3DProgram = new CGLSLPrimitiveProgram;
m_pPrimitive3DProgramTextured = new CGLSLPrimitiveProgram;
m_pBorderTileProgram = new CGLSLTileProgram; m_pBorderTileProgram = new CGLSLTileProgram;
m_pBorderTileProgramTextured = new CGLSLTileProgram; m_pBorderTileProgramTextured = new CGLSLTileProgram;
m_pBorderTileLineProgram = 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_LocIsTextured = m_pPrimitiveProgram->GetUniformLoc("isTextured");
m_pPrimitiveProgram->m_LocTextureSampler = m_pPrimitiveProgram->GetUniformLoc("textureSampler"); 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 VertexShader;
CGLSL FragmentShader; CGLSL FragmentShader;
@ -2375,6 +2487,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand
glGenBuffers(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawBufferID); glGenBuffers(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawBufferID);
glGenVertexArrays(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawVertexID); glGenVertexArrays(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawVertexID);
glGenBuffers(1, &m_PrimitiveDrawBufferIDTex3D);
glGenVertexArrays(1, &m_PrimitiveDrawVertexIDTex3D);
m_UsePreinitializedVertexBuffer = g_Config.m_GfxUsePreinitBuffer; m_UsePreinitializedVertexBuffer = g_Config.m_GfxUsePreinitBuffer;
@ -2396,6 +2510,19 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand
m_LastIndexBufferBound[i] = 0; 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 //query the image max size only once
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_MaxTexSize); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_MaxTexSize);
@ -2449,6 +2576,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Shutdown(const SCommand_Shutdown *
m_pQuadProgramTextured->DeleteProgram(); m_pQuadProgramTextured->DeleteProgram();
m_pTileProgram->DeleteProgram(); m_pTileProgram->DeleteProgram();
m_pTileProgramTextured->DeleteProgram(); m_pTileProgramTextured->DeleteProgram();
m_pPrimitive3DProgram->DeleteProgram();
m_pPrimitive3DProgramTextured->DeleteProgram();
m_pTextProgram->DeleteProgram(); m_pTextProgram->DeleteProgram();
m_pSpriteProgram->DeleteProgram(); m_pSpriteProgram->DeleteProgram();
m_pSpriteProgramMultiple->DeleteProgram(); m_pSpriteProgramMultiple->DeleteProgram();
@ -2463,6 +2592,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Shutdown(const SCommand_Shutdown *
delete m_pQuadProgramTextured; delete m_pQuadProgramTextured;
delete m_pTileProgram; delete m_pTileProgram;
delete m_pTileProgramTextured; delete m_pTileProgramTextured;
delete m_pPrimitive3DProgram;
delete m_pPrimitive3DProgramTextured;
delete m_pTextProgram; delete m_pTextProgram;
delete m_pSpriteProgram; delete m_pSpriteProgram;
delete m_pSpriteProgramMultiple; delete m_pSpriteProgramMultiple;
@ -2471,6 +2602,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Shutdown(const SCommand_Shutdown *
glDeleteBuffers(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawBufferID); glDeleteBuffers(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawBufferID);
glDeleteBuffers(1, &m_QuadDrawIndexBufferID); glDeleteBuffers(1, &m_QuadDrawIndexBufferID);
glDeleteVertexArrays(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawVertexID); glDeleteVertexArrays(MAX_STREAM_BUFFER_COUNT, m_PrimitiveDrawVertexID);
glDeleteBuffers(1, &m_PrimitiveDrawBufferIDTex3D);
glDeleteVertexArrays(1, &m_PrimitiveDrawVertexIDTex3D);
for(int i = 0; i < CCommandBuffer::MAX_TEXTURES; ++i) 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); 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; int Count = 0;
switch (PrimitiveType) switch (PrimitiveType)
@ -2755,16 +2888,19 @@ void CCommandProcessorFragment_OpenGL3_3::UploadStreamBufferData(unsigned int Pr
return; return;
}; };
if(AsTex3D)
glBindBuffer(GL_ARRAY_BUFFER, m_PrimitiveDrawBufferIDTex3D);
else
glBindBuffer(GL_ARRAY_BUFFER, m_PrimitiveDrawBufferID[m_LastStreamBuffer]); glBindBuffer(GL_ARRAY_BUFFER, m_PrimitiveDrawBufferID[m_LastStreamBuffer]);
if(!m_UsePreinitializedVertexBuffer) 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 else
{ {
// This is better for some iGPUs. Probably due to not initializing a new buffer in the system memory again and again...(driver dependent) // 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); glUnmapBuffer(GL_ARRAY_BUFFER);
} }
@ -2775,7 +2911,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Render(const CCommandBuffer::SComm
UseProgram(m_pPrimitiveProgram); UseProgram(m_pPrimitiveProgram);
SetState(pCommand->m_State, 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]); 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); 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) void CCommandProcessorFragment_OpenGL3_3::Cmd_Screenshot(const CCommandBuffer::SCommand_Screenshot *pCommand)
{ {
// fetch image data // 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) 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 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]); glBindVertexArray(m_PrimitiveDrawVertexID[m_LastStreamBuffer]);
if(m_LastIndexBufferBound[m_LastStreamBuffer] != m_QuadDrawIndexBufferID) 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 }; 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); 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_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand);
virtual void Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand); virtual void Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand);
virtual void Cmd_Render(const CCommandBuffer::SCommand_Render *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_Screenshot(const CCommandBuffer::SCommand_Screenshot *pCommand);
virtual void Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *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_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_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand) override;
void Cmd_RecreateBufferObject(const CCommandBuffer::SCommand_RecreateBufferObject *pCommand) override; void Cmd_RecreateBufferObject(const CCommandBuffer::SCommand_RecreateBufferObject *pCommand) override;
void Cmd_UpdateBufferObject(const CCommandBuffer::SCommand_UpdateBufferObject *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_LastProgramID;
GLuint m_PrimitiveDrawVertexID[MAX_STREAM_BUFFER_COUNT]; GLuint m_PrimitiveDrawVertexID[MAX_STREAM_BUFFER_COUNT];
GLuint m_PrimitiveDrawVertexIDTex3D;
GLuint m_PrimitiveDrawBufferID[MAX_STREAM_BUFFER_COUNT]; GLuint m_PrimitiveDrawBufferID[MAX_STREAM_BUFFER_COUNT];
GLuint m_PrimitiveDrawBufferIDTex3D;
GLuint m_LastIndexBufferBound[MAX_STREAM_BUFFER_COUNT]; GLuint m_LastIndexBufferBound[MAX_STREAM_BUFFER_COUNT];
@ -334,7 +339,7 @@ protected:
bool IsNewApi() override { return true; } bool IsNewApi() override { return true; }
void UseProgram(CGLSLTWProgram *pProgram); void UseProgram(CGLSLTWProgram *pProgram);
void UploadStreamBufferData(unsigned int PrimitiveType, const void* pVertices, unsigned int PrimitiveCount); 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 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_Init(const SCommand_Init *pCommand) override;
@ -344,6 +349,7 @@ protected:
void Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand) override; void Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand) override;
void Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand) override; void Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand) override;
void Cmd_Render(const CCommandBuffer::SCommand_Render *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_Screenshot(const CCommandBuffer::SCommand_Screenshot *pCommand) override;
void Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand) override; void Cmd_CreateBufferObject(const CCommandBuffer::SCommand_CreateBufferObject *pCommand) override;

View file

@ -54,134 +54,47 @@ static CVideoMode g_aFakeModes[] = {
void CGraphics_Threaded::FlushVertices(bool KeepVertices) 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; 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;
}
}
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); mem_copy(Cmd.m_pVertices, m_aVertices, VertSize * NumVerts);
} }
}
void CGraphics_Threaded::FlushTextVertices(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float* pOutlineTextColor) 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; 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_TextureSize = TextureSize;
Cmd.m_TextTextureIndex = TextTextureIndex; Cmd.m_TextTextureIndex = TextTextureIndex;
Cmd.m_TextOutlineTextureIndex = TextOutlineTextureIndex; Cmd.m_TextOutlineTextureIndex = TextOutlineTextureIndex;
mem_copy(Cmd.m_aTextOutlineColor, pOutlineTextColor, sizeof(Cmd.m_aTextOutlineColor)); mem_copy(Cmd.m_aTextOutlineColor, pOutlineTextColor, sizeof(Cmd.m_aTextOutlineColor));
Cmd.m_QuadNum = NumVerts / 4; FlushVerticesImpl(false, PrimType, PrimCount, NumVerts, Cmd, VertSize);
if(Cmd.m_pVertices != NULL)
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); mem_copy(Cmd.m_pVertices, m_aVertices, VertSize * NumVerts);
} }
}
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)
{
mem_copy(Cmd.m_pVertices, m_aVerticesTex3D, VertSize * NumVerts);
}
}
void CGraphics_Threaded::AddVertices(int Count) void CGraphics_Threaded::AddVertices(int Count)
{ {
@ -190,21 +103,16 @@ void CGraphics_Threaded::AddVertices(int Count)
FlushVertices(); 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); AddVertices(Count);
float s = sinf(m_Rotation);
float x, y;
int i;
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() CGraphics_Threaded::CGraphics_Threaded()
@ -659,6 +567,18 @@ void CGraphics_Threaded::TextQuadsEnd(int TextureSize, int TextTextureIndex, int
m_Drawing = 0; 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() void CGraphics_Threaded::QuadsEndKeepVertices()
{ {
dbg_assert(m_Drawing == DRAWING_QUADS, "called Graphics()->QuadsEndKeepVertices without begin"); 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) void CGraphics_Threaded::QuadsSetSubset(float TlU, float TlV, float BrU, float BrV)
{ {
m_aTexture[0].u = TlU; m_aTexture[1].u = BrU; 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( void CGraphics_Threaded::QuadsSetSubsetFree(
float x0, float y0, float x1, float y1, 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[0].u = x0;
m_aTexture[1].u = x1; m_aTexture[1].v = y1; m_aTexture[0].v = y0;
m_aTexture[2].u = x2; m_aTexture[2].v = y2; m_aTexture[1].u = x1;
m_aTexture[3].u = x3; m_aTexture[3].v = y3; 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) 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) 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) if(g_Config.m_GfxQuadAsTriangle && !m_IsNewOpenGL)
{ {
for(int i = 0; i < Num; ++i) VertNum = 6;
{
// 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);
} }
else else
{ {
VertNum = 4;
}
for(int i = 0; i < Num; ++i) for(int i = 0; i < Num; ++i)
{ {
m_aVertices[m_NumVertices + 4*i].m_Pos.x = pArray[i].m_X; for(int n = 0; n < VertNum; ++n)
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; if(HasTextureArrays())
Center.y = pArray[i].m_Y + pArray[i].m_Height/2; m_aVerticesTex3D[CurNumVert + VertNum * i + n].m_Tex.w = (float)m_CurIndex;
else
Rotate(Center, &m_aVertices[m_NumVertices + 4*i], 4); m_aVerticesTex3D[CurNumVert + VertNum * i + n].m_Tex.w = ((float)m_CurIndex + 0.5f) / 256.f;
} }
} }
AddVertices(4*Num); QuadsDrawTLImpl(m_aVerticesTex3D, pArray, Num);
}
} }
void CGraphics_Threaded::QuadsDrawFreeform(const CFreeformItem *pArray, int Num) void CGraphics_Threaded::QuadsDrawFreeform(const CFreeformItem *pArray, int Num)

View file

@ -84,6 +84,7 @@ public:
// rendering // rendering
CMD_CLEAR, CMD_CLEAR,
CMD_RENDER, CMD_RENDER,
CMD_RENDER_TEX3D,
//opengl 2.0+ commands (some are just emulated and only exist in opengl 3.3+) //opengl 2.0+ commands (some are just emulated and only exist in opengl 3.3+)
CMD_CREATE_BUFFER_OBJECT, // create vbo CMD_CREATE_BUFFER_OBJECT, // create vbo
@ -163,6 +164,8 @@ public:
typedef GL_SColorf SColorf; typedef GL_SColorf SColorf;
typedef GL_SColor SColor; typedef GL_SColor SColor;
typedef GL_SVertex SVertex; typedef GL_SVertex SVertex;
typedef GL_SVertexTex3D SVertexTex3D;
typedef GL_SVertexTex3DStream SVertexTex3DStream;
struct SCommand struct SCommand
{ {
@ -215,6 +218,16 @@ public:
SVertex *m_pVertices; // you should use the command buffer data to allocate vertices for this command 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 struct SCommand_CreateBufferObject : public SCommand
{ {
SCommand_CreateBufferObject() : SCommand(CMD_CREATE_BUFFER_OBJECT) {} SCommand_CreateBufferObject() : SCommand(CMD_CREATE_BUFFER_OBJECT) {}
@ -379,7 +392,8 @@ public:
SState m_State; SState m_State;
SVertex *m_pVertices; SVertex *m_pVertices;
int m_QuadNum; unsigned m_PrimType;
unsigned m_PrimCount;
int m_TextureSize; int m_TextureSize;
@ -644,7 +658,10 @@ class CGraphics_Threaded : public IEngineGraphics
class IStorage *m_pStorage; class IStorage *m_pStorage;
class IConsole *m_pConsole; class IConsole *m_pConsole;
int m_CurIndex;
CCommandBuffer::SVertex m_aVertices[MAX_VERTICES]; CCommandBuffer::SVertex m_aVertices[MAX_VERTICES];
CCommandBuffer::SVertexTex3DStream m_aVerticesTex3D[MAX_VERTICES];
int m_NumVertices; int m_NumVertices;
CCommandBuffer::SColor m_aColor[4]; CCommandBuffer::SColor m_aColor[4];
@ -715,7 +732,26 @@ class CGraphics_Threaded : public IEngineGraphics
void* AllocCommandBufferData(unsigned AllocSize); void* AllocCommandBufferData(unsigned AllocSize);
void AddVertices(int Count); 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(); void KickCommandBuffer();
@ -763,10 +799,22 @@ public:
void QuadsEnd() override; void QuadsEnd() override;
void TextQuadsBegin() override; void TextQuadsBegin() override;
void TextQuadsEnd(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) override; void TextQuadsEnd(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) override;
void QuadsTex3DBegin() override;
void QuadsTex3DEnd() override;
void QuadsEndKeepVertices() override; void QuadsEndKeepVertices() override;
void QuadsDrawCurrentVertices(bool KeepVertices = true) override; void QuadsDrawCurrentVertices(bool KeepVertices = true) override;
void QuadsSetRotation(float Angle) 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 SetColorVertex(const CColorVertex *pArray, int Num) override;
void SetColor(float r, float g, float b, float a) override; void SetColor(float r, float g, float b, float a) override;
void SetColor(ColorRGBA rgb) override; void SetColor(ColorRGBA rgb) override;
@ -776,15 +824,108 @@ public:
void ChangeColorOfCurrentQuadVertices(float r, float g, float b, float a) override; 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 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 QuadsSetSubset(float TlU, float TlV, float BrU, float BrV) override;
void QuadsSetSubsetFree( void QuadsSetSubsetFree(
float x0, float y0, float x1, float y1, 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; 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 QuadsDrawTL(const CQuadItem *pArray, int Num) override;
void QuadsTex3DDrawTL(const CQuadItem *pArray, int Num) override;
void QuadsDrawFreeform(const CFreeformItem *pArray, int Num) override; void QuadsDrawFreeform(const CFreeformItem *pArray, int Num) override;
void QuadsText(float x, float y, float Size, const char *pText) 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 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; 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 FlushVertices(bool KeepVertices = false) override;
void FlushTextVertices(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) 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 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; 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; int m_Red, m_Green, m_Blue;
}; };
struct GL_SPoint { float x, y; }; struct GL_SPoint
struct GL_STexCoord { float u, v; }; {
struct GL_STexCoord3D { float u, v, w; }; float x, y;
struct GL_SColorf { float r, g, b, a; }; };
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 //use normalized color values
struct GL_SColor { unsigned char r, g, b, a; }; struct GL_SColor { unsigned char r, g, b, a; };
@ -118,6 +136,13 @@ struct GL_SVertexTex3D
GL_STexCoord3D m_Tex; GL_STexCoord3D m_Tex;
}; };
struct GL_SVertexTex3DStream
{
GL_SPoint m_Pos;
GL_SColor m_Color;
GL_STexCoord3D m_Tex;
};
struct SGraphicsWarning struct SGraphicsWarning
{ {
SGraphicsWarning() : m_WasShown(false) {} SGraphicsWarning() : m_WasShown(false) {}
@ -206,6 +231,7 @@ public:
virtual void FlushVertices(bool KeepVertices = false) = 0; virtual void FlushVertices(bool KeepVertices = false) = 0;
virtual void FlushTextVertices(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) = 0; virtual void FlushTextVertices(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) = 0;
virtual void FlushVerticesTex3D() = 0;
// specific render functions // specific render functions
virtual void RenderTileLayer(int BufferContainerIndex, float *pColor, char **pOffsets, unsigned int *IndicedVertexDrawNum, size_t NumIndicesOffet) = 0; 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 QuadsEnd() = 0;
virtual void TextQuadsBegin() = 0; virtual void TextQuadsBegin() = 0;
virtual void TextQuadsEnd(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) = 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 QuadsEndKeepVertices() = 0;
virtual void QuadsDrawCurrentVertices(bool KeepVertices = true) = 0; virtual void QuadsDrawCurrentVertices(bool KeepVertices = true) = 0;
virtual void QuadsSetRotation(float Angle) = 0; virtual void QuadsSetRotation(float Angle) = 0;
virtual void QuadsSetSubset(float TopLeftU, float TopLeftV, float BottomRightU, float BottomRightV) = 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 struct CQuadItem
{ {
@ -263,6 +291,8 @@ public:
virtual void QuadsDraw(CQuadItem *pArray, int Num) = 0; virtual void QuadsDraw(CQuadItem *pArray, int Num) = 0;
virtual void QuadsDrawTL(const 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 struct CFreeformItem
{ {
float m_X0, m_Y0, m_X1, m_Y1, m_X2, m_Y2, m_X3, m_Y3; float m_X0, m_Y0, m_X1, m_Y1, m_X2, m_Y2, m_X3, m_Y3;

View file

@ -276,6 +276,9 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, Color
a = aChannels[3]; a = aChannels[3];
} }
if(Graphics()->IsTileBufferingEnabled())
Graphics()->QuadsTex3DBegin();
else
Graphics()->QuadsBegin(); Graphics()->QuadsBegin();
Graphics()->SetColor(Color.r * r, Color.g * g, Color.b * b, Color.a * a); Graphics()->SetColor(Color.r * r, Color.g * g, Color.b * b, Color.a * a);
@ -356,6 +359,18 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, Color
float x3 = Nudge + Px0/TexSize+Frac; float x3 = Nudge + Px0/TexSize+Frac;
float y3 = Nudge + Py1/TexSize-Frac; float y3 = Nudge + Py1/TexSize-Frac;
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) if(Flags & TILEFLAG_VFLIP)
{ {
x0 = x2; x0 = x2;
@ -386,15 +401,27 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, Color
y1 = Tmp; y1 = Tmp;
} }
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); Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3);
IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale);
Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsDrawTL(&QuadItem, 1);
} }
} }
}
x += pTiles[c].m_Skip; x += pTiles[c].m_Skip;
} }
} }
if(Graphics()->IsTileBufferingEnabled())
Graphics()->QuadsTex3DEnd();
else
Graphics()->QuadsEnd(); Graphics()->QuadsEnd();
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); 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_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; ImgInfo.m_pData = 0;
pEditor->SortImages(); pEditor->SortImages();
for(int i = 0; i < pEditor->m_Map.m_lImages.size(); ++i) 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); 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; ImgInfo.m_pData = 0;
str_copy(pImg->m_aName, aBuf, sizeof(pImg->m_aName)); str_copy(pImg->m_aName, aBuf, sizeof(pImg->m_aName));
pImg->m_AutoMapper.Load(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_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_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_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_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, 0); 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, 0); 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, 0); 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, 0); m_TuneTexture = Graphics()->LoadTexture("editor/tune.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, TextureLoadFlag);
m_TilesetPicker.m_pEditor = this; m_TilesetPicker.m_pEditor = this;
m_TilesetPicker.MakePalette(); 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)) if(m_pEditor->Graphics()->LoadPNG(&ImgInfo, aBuf, IStorage::TYPE_ALL))
{ {
*pImg = ImgInfo; *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; ImgInfo.m_pData = 0;
pImg->m_External = 1; pImg->m_External = 1;
} }
@ -688,7 +691,10 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
void *pData = DataFile.GetData(pItem->m_ImageData); void *pData = DataFile.GetData(pItem->m_ImageData);
pImg->m_pData = malloc(pImg->m_Width * pImg->m_Height * 4); pImg->m_pData = malloc(pImg->m_Width * pImg->m_Height * 4);
mem_copy(pImg->m_pData, pData, 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); 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 // 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_PopupEventType = m_pEditor->POPEVENT_IMAGEDIV16;
m_pEditor->m_PopupEventActivated = true; 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) 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); 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) 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) 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); 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) 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); str_format(aBuf, sizeof(aBuf), "editor/entities/%s.png", Name);
pEditor->Graphics()->UnloadTexture(pEditor->m_EntitiesTexture); 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--; g_UiNumPopups--;
} }
} }