mirror of
https://github.com/lalbornoz/roar.git
synced 2024-11-22 15:26:37 +00:00
Initial text support implementation, pt. III.
Generate TTF texture ad hoc.
This commit is contained in:
parent
22c4904c20
commit
e656f549ff
13
ENNTool.py
13
ENNTool.py
@ -8,10 +8,12 @@
|
|||||||
# 1) -A: render frame #1, render frame #2, ...
|
# 1) -A: render frame #1, render frame #2, ...
|
||||||
# 2) -o: support at least {GIF,MP4,WEBM}
|
# 2) -o: support at least {GIF,MP4,WEBM}
|
||||||
# 3) -s: effects: rotate, smash into bricks, swirl, wave, ...
|
# 3) -s: effects: rotate, smash into bricks, swirl, wave, ...
|
||||||
# 4) XXX autodetect video width from widest mircart
|
# 4) Feature: include ETA @ progress bar
|
||||||
# 5) XXX convert TTF to texture PNG & coords TXT, render accordingly
|
# 5) Feature: autodetect video width from widest mircart
|
||||||
# 6) XXX dont stall GPU w/ glReadPixels(), switch to asynchronous model w/ FBO or PBO (http://www.songho.ca/opengl/gl_fbo.html, http://www.songho.ca/opengl/gl_pbo.html)
|
# 6) Feature: render mircart as 3D blocks vs flat surface
|
||||||
# 7) XXX render mircart as 3D blocks vs flat surface
|
# 7) Optimisation: dont stall GPU w/ glReadPixels(), switch to asynchronous model w/ FBO or PBO (http://www.songho.ca/opengl/gl_fbo.html, http://www.songho.ca/opengl/gl_pbo.html)
|
||||||
|
# 8) OpenGL: use VAOs + glVertexAttribFormat + glVertexAttribBinding
|
||||||
|
# 9) OpenGL: use glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) & multiply texel * bgcolour (https://learnopengl.com/Advanced-OpenGL/Blending)
|
||||||
#
|
#
|
||||||
|
|
||||||
from getopt import getopt, GetoptError
|
from getopt import getopt, GetoptError
|
||||||
@ -21,6 +23,7 @@ import os, sys, time
|
|||||||
import wx
|
import wx
|
||||||
|
|
||||||
from ENNToolGLCanvasPanel import ENNToolGLCanvasPanel
|
from ENNToolGLCanvasPanel import ENNToolGLCanvasPanel
|
||||||
|
from ENNToolGLTTFTexture import ENNToolGLTTFTexture
|
||||||
from ENNToolMiRCARTImporter import ENNToolMiRCARTImporter
|
from ENNToolMiRCARTImporter import ENNToolMiRCARTImporter
|
||||||
|
|
||||||
class ENNToolApp(object):
|
class ENNToolApp(object):
|
||||||
@ -91,7 +94,7 @@ class ENNToolApp(object):
|
|||||||
MiRCART += ENNToolMiRCARTImporter(inFile).outMap
|
MiRCART += ENNToolMiRCARTImporter(inFile).outMap
|
||||||
|
|
||||||
curY, rotateX, rotateY, translateY = 0, 0, 0, scrollRate
|
curY, rotateX, rotateY, translateY = 0, 0, 0, scrollRate
|
||||||
artTextureId, artInfo = panelGLCanvas.initTexture(texturePathName)
|
artTextureId, artInfo = ENNToolGLTTFTexture(MiRCART, optdict["-R"], optdict["-r"]).getParams()
|
||||||
artVbo, artVboLen, lastY, numVertices = panelGLCanvas.renderMiRCART(artInfo, MiRCART, cubeSize=optdict["-R"])
|
artVbo, artVboLen, lastY, numVertices = panelGLCanvas.renderMiRCART(artInfo, MiRCART, cubeSize=optdict["-R"])
|
||||||
if "-v" in optdict:
|
if "-v" in optdict:
|
||||||
print("{} vertices".format(numVertices))
|
print("{} vertices".format(numVertices))
|
||||||
|
@ -10,18 +10,14 @@
|
|||||||
# Wed, 27 Jun 2018 16:02:12 +0200 [3] <https://www.khronos.org/opengl/wiki/How_lighting_works#Good_Settings.>
|
# Wed, 27 Jun 2018 16:02:12 +0200 [3] <https://www.khronos.org/opengl/wiki/How_lighting_works#Good_Settings.>
|
||||||
# Wed, 27 Jun 2018 16:02:13 +0200 [4] <https://www.khronos.org/opengl/wiki/Common_Mistakes>
|
# Wed, 27 Jun 2018 16:02:13 +0200 [4] <https://www.khronos.org/opengl/wiki/Common_Mistakes>
|
||||||
# Wed, 27 Jun 2018 16:02:14 +0200 [5] <https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout>
|
# Wed, 27 Jun 2018 16:02:14 +0200 [5] <https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout>
|
||||||
# Thu, 28 Jun 2018 17:03:16 +0200 [6] <https://stackoverflow.com/questions/384759/how-to-convert-a-pil-image-into-a-numpy-array>
|
# Thu, 28 Jun 2018 18:32:50 +0200 [6] <https://stackoverflow.com/questions/18935203/shader-position-vec4-or-vec3>
|
||||||
# Thu, 28 Jun 2018 17:04:59 +0200 [7] <https://www.khronos.org/opengl/wiki/Common_Mistakes#y-axis>
|
|
||||||
# Thu, 28 Jun 2018 18:32:50 +0200 [8] <https://stackoverflow.com/questions/18935203/shader-position-vec4-or-vec3>
|
|
||||||
#
|
#
|
||||||
|
|
||||||
from OpenGL.GL import *
|
from OpenGL.GL import *
|
||||||
from OpenGL.GL import shaders
|
from OpenGL.GL import shaders
|
||||||
from PIL import Image
|
|
||||||
import cv2, numpy
|
import cv2, numpy
|
||||||
import ctypes, os, sys, time
|
import ctypes, os, sys, time
|
||||||
import wx, wx.glcanvas
|
import wx, wx.glcanvas
|
||||||
import yaml
|
|
||||||
|
|
||||||
from ENNToolMiRCARTColours import ENNToolMiRCARTColoursFloat
|
from ENNToolMiRCARTColours import ENNToolMiRCARTColoursFloat
|
||||||
|
|
||||||
@ -53,11 +49,7 @@ class ENNToolGLCanvasPanel(wx.glcanvas.GLCanvas, wx.Panel):
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 texel = texture2D(texture, fgTexCoord);
|
vec4 texel = texture2D(texture, fgTexCoord);
|
||||||
if (texel.a > 0.0) {
|
|
||||||
gl_FragColor = vec4(texel.r, texel.g, texel.b, 1.0);
|
gl_FragColor = vec4(texel.r, texel.g, texel.b, 1.0);
|
||||||
} else {
|
|
||||||
gl_FragColor = bgColour;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
""", GL_FRAGMENT_SHADER)
|
""", GL_FRAGMENT_SHADER)
|
||||||
vs = shaders.compileShader("""
|
vs = shaders.compileShader("""
|
||||||
@ -82,37 +74,12 @@ class ENNToolGLCanvasPanel(wx.glcanvas.GLCanvas, wx.Panel):
|
|||||||
""", GL_VERTEX_SHADER)
|
""", GL_VERTEX_SHADER)
|
||||||
self.shader = shaders.compileProgram(vs, fs)
|
self.shader = shaders.compileProgram(vs, fs)
|
||||||
# }}}
|
# }}}
|
||||||
# {{{ initTexture(self, pathName, infoPathName=os.path.join("assets", "textures.yaml")): XXX
|
|
||||||
def initTexture(self, pathName, infoPathName=os.path.join("assets", "textures.yaml")):
|
|
||||||
with open(infoPathName, "r") as fileObject:
|
|
||||||
artInfo = yaml.load(fileObject)
|
|
||||||
|
|
||||||
# [6], [7]
|
|
||||||
artTextureId = glGenTextures(1)
|
|
||||||
artTextureImage = Image.open(pathName).transpose(Image.FLIP_TOP_BOTTOM)
|
|
||||||
artTextureImageData = numpy.array(artTextureImage)
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, artTextureId)
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
|
||||||
|
|
||||||
# [2]
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
|
||||||
|
|
||||||
# [4][5]
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
|
||||||
artTextureImage.size[0], artTextureImage.size[1],
|
|
||||||
0, GL_RGBA, GL_UNSIGNED_BYTE, artTextureImageData)
|
|
||||||
glBindTexture(GL_TEXTURE_2D, artTextureId)
|
|
||||||
return artTextureId, artInfo
|
|
||||||
# }}}
|
|
||||||
# {{{ initVideoWriter(self): XXX
|
# {{{ initVideoWriter(self): XXX
|
||||||
def initVideoWriter(self, fourcc="XVID", fps=25):
|
def initVideoWriter(self, fourcc="XVID", fps=25):
|
||||||
fourcc = cv2.VideoWriter_fourcc(*list(fourcc))
|
fourcc = cv2.VideoWriter_fourcc(*list(fourcc))
|
||||||
self.videoWriter = cv2.VideoWriter(self.videoPath, fourcc, fps, (self.width, self.height), True)
|
self.videoWriter = cv2.VideoWriter(self.videoPath, fourcc, fps, (self.width, self.height), True)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# {{{ renderFrame(self, artTextureId, artVbo, artVboLen): XXX
|
# {{{ renderFrame(self, artTextureId, artVbo, artVboLen): XXX
|
||||||
def renderFrame(self, artTextureId, artVbo, artVboLen):
|
def renderFrame(self, artTextureId, artVbo, artVboLen):
|
||||||
glEnableClientState(GL_VERTEX_ARRAY)
|
glEnableClientState(GL_VERTEX_ARRAY)
|
||||||
@ -136,7 +103,7 @@ class ENNToolGLCanvasPanel(wx.glcanvas.GLCanvas, wx.Panel):
|
|||||||
glUniformMatrix4fv(glGetUniformLocation(self.shader, "projection"), 1, GL_FALSE, projection)
|
glUniformMatrix4fv(glGetUniformLocation(self.shader, "projection"), 1, GL_FALSE, projection)
|
||||||
glUniform1i(glGetUniformLocation(self.shader, "texture"), 0)
|
glUniform1i(glGetUniformLocation(self.shader, "texture"), 0)
|
||||||
|
|
||||||
# [8]
|
# [6]
|
||||||
glEnableVertexAttribArray(0)
|
glEnableVertexAttribArray(0)
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, False, 48, ctypes.c_void_p(0))
|
glVertexAttribPointer(0, 3, GL_FLOAT, False, 48, ctypes.c_void_p(0))
|
||||||
glEnableVertexAttribArray(1)
|
glEnableVertexAttribArray(1)
|
||||||
@ -168,43 +135,39 @@ class ENNToolGLCanvasPanel(wx.glcanvas.GLCanvas, wx.Panel):
|
|||||||
if centre and (len(artMap[numRow]) < canvasCols):
|
if centre and (len(artMap[numRow]) < canvasCols):
|
||||||
curPos[0] += (((canvasCols - len(artMap[numRow])) * cubeSize[0]) / 2)
|
curPos[0] += (((canvasCols - len(artMap[numRow])) * cubeSize[0]) / 2)
|
||||||
for numCol in range(len(artMap[numRow])):
|
for numCol in range(len(artMap[numRow])):
|
||||||
cubeColour = [*ENNToolMiRCARTColoursFloat[artMap[numRow][numCol][1]], 1.0]
|
cubeFg = artMap[numRow][numCol][0]
|
||||||
if artMap[numRow][numCol][0] != artMap[numRow][numCol][1]:
|
cubeBg = artMap[numRow][numCol][1]
|
||||||
colColour = artMap[numRow][numCol][0]
|
cubeBgFloat = [*ENNToolMiRCARTColoursFloat[cubeBg], 1.0]
|
||||||
|
cubeAttrs = artMap[numRow][numCol][2]
|
||||||
cubeChar = artMap[numRow][numCol][3]
|
cubeChar = artMap[numRow][numCol][3]
|
||||||
if ord(cubeChar) >= 128:
|
artCell = artInfo[cubeFg][cubeBg][cubeAttrs][cubeChar]
|
||||||
print("dont have {}".format(cubeChar))
|
|
||||||
cubeChar = " "
|
|
||||||
else:
|
|
||||||
colColour = artMap[numRow][numCol][1]
|
|
||||||
cubeChar = " "
|
|
||||||
|
|
||||||
# Top Right
|
# Top Right
|
||||||
vertices += curPos
|
vertices += curPos
|
||||||
vertices += [0.0, 0.0, 1.0]
|
vertices += [0.0, 0.0, 1.0]
|
||||||
vertices += cubeColour
|
vertices += cubeBgFloat
|
||||||
vertices += [float(((ord(cubeChar) + 1) * artInfo["rowWidth"]) / artInfo["texWidth"]), ((colColour + 1) * artInfo["rowHeight"]) / float(artInfo["texHeight"])]
|
vertices += artCell[0:2]
|
||||||
numVertices += 1
|
numVertices += 1
|
||||||
|
|
||||||
# Top Left
|
# Top Left
|
||||||
vertices += [curPos[0]-cubeSize[0], curPos[1], curPos[2]]
|
vertices += [curPos[0]-cubeSize[0], curPos[1], curPos[2]]
|
||||||
vertices += [0.0, 0.0, 1.0]
|
vertices += [0.0, 0.0, 1.0]
|
||||||
vertices += cubeColour
|
vertices += cubeBgFloat
|
||||||
vertices += [float(((ord(cubeChar) + 0) * artInfo["rowWidth"]) / artInfo["texWidth"]), ((colColour + 1) * artInfo["rowHeight"]) / float(artInfo["texHeight"])]
|
vertices += artCell[2:4]
|
||||||
numVertices += 1
|
numVertices += 1
|
||||||
|
|
||||||
# Bottom Left
|
# Bottom Left
|
||||||
vertices += [curPos[0]-cubeSize[0], curPos[1]-cubeSize[1], curPos[2]]
|
vertices += [curPos[0]-cubeSize[0], curPos[1]-cubeSize[1], curPos[2]]
|
||||||
vertices += [0.0, 0.0, 1.0]
|
vertices += [0.0, 0.0, 1.0]
|
||||||
vertices += cubeColour
|
vertices += cubeBgFloat
|
||||||
vertices += [float(((ord(cubeChar) + 0) * artInfo["rowWidth"]) / artInfo["texWidth"]), ((colColour) * artInfo["rowHeight"]) / float(artInfo["texHeight"])]
|
vertices += artCell[4:6]
|
||||||
numVertices += 1
|
numVertices += 1
|
||||||
|
|
||||||
# Bottom Right
|
# Bottom Right
|
||||||
vertices += [curPos[0], curPos[1]-cubeSize[1], curPos[2]]
|
vertices += [curPos[0], curPos[1]-cubeSize[1], curPos[2]]
|
||||||
vertices += [0.0, 0.0, 1.0]
|
vertices += [0.0, 0.0, 1.0]
|
||||||
vertices += cubeColour
|
vertices += cubeBgFloat
|
||||||
vertices += [float(((ord(cubeChar) + 1) * artInfo["rowWidth"]) / artInfo["texWidth"]), ((colColour) * artInfo["rowHeight"]) / float(artInfo["texHeight"])]
|
vertices += artCell[6:8]
|
||||||
numVertices += 1
|
numVertices += 1
|
||||||
|
|
||||||
curPos[0] += cubeSize[0]
|
curPos[0] += cubeSize[0]
|
||||||
@ -226,6 +189,7 @@ class ENNToolGLCanvasPanel(wx.glcanvas.GLCanvas, wx.Panel):
|
|||||||
screenshot = numpy.flipud(numpy.frombuffer(screenshot, numpy.uint8).reshape((self.height, self.width, 3)))
|
screenshot = numpy.flipud(numpy.frombuffer(screenshot, numpy.uint8).reshape((self.height, self.width, 3)))
|
||||||
self.videoWriter.write(screenshot)
|
self.videoWriter.write(screenshot)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# {{{ __init__(self, parent, size, defaultPos=(24,24), videoPath=None): initialisation method
|
# {{{ __init__(self, parent, size, defaultPos=(24,24), videoPath=None): initialisation method
|
||||||
def __init__(self, parent, size, defaultPos=(24,24), videoPath=None):
|
def __init__(self, parent, size, defaultPos=(24,24), videoPath=None):
|
||||||
super().__init__(parent, pos=defaultPos, size=size)
|
super().__init__(parent, pos=defaultPos, size=size)
|
||||||
|
142
ENNToolGLTTFTexture.py
Normal file
142
ENNToolGLTTFTexture.py
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
|
||||||
|
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
|
# This project is licensed under the terms of the MIT license.
|
||||||
|
#
|
||||||
|
# References:
|
||||||
|
# Thu, 28 Jun 2018 17:03:16 +0200 [1] <https://stackoverflow.com/questions/384759/how-to-convert-a-pil-image-into-a-numpy-array>
|
||||||
|
# Thu, 28 Jun 2018 17:04:59 +0200 [2] <https://www.khronos.org/opengl/wiki/Common_Mistakes#y-axis>
|
||||||
|
# Wed, 27 Jun 2018 16:02:12 +0200 [3] <https://www.khronos.org/opengl/wiki/How_lighting_works#Good_Settings.>
|
||||||
|
# Wed, 27 Jun 2018 16:02:13 +0200 [4] <https://www.khronos.org/opengl/wiki/Common_Mistakes>
|
||||||
|
# Wed, 27 Jun 2018 16:02:14 +0200 [5] <https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout>
|
||||||
|
#
|
||||||
|
|
||||||
|
from collections import defaultdict
|
||||||
|
from OpenGL.GL import *
|
||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
import numpy
|
||||||
|
import os, string, sys
|
||||||
|
|
||||||
|
from ENNToolMiRCARTColours import ENNToolMiRCARTColours
|
||||||
|
from ENNToolMiRCARTImporter import ENNToolMiRCARTImporter
|
||||||
|
|
||||||
|
class ENNToolGLTTFTexture(object):
|
||||||
|
"""XXX"""
|
||||||
|
|
||||||
|
# {{{ _defaultDict(*args): XXX
|
||||||
|
@staticmethod
|
||||||
|
def _defaultDict(*args):
|
||||||
|
return defaultdict(*args)
|
||||||
|
# }}}
|
||||||
|
# {{{ _nestedDict(): XXX
|
||||||
|
@staticmethod
|
||||||
|
def _nestedDict():
|
||||||
|
return defaultdict(ENNToolGLTTFTexture._nestedDict)
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
# {{{ _drawCharList(self, artInfo, charList, pilFontBold, pilFontNormal, pilFontSize, pilImageDraw, pilImageSize): XXX
|
||||||
|
def _drawCharList(self, artInfo, charList, pilFontBold, pilFontNormal, pilFontSize, pilImageDraw, pilImageSize):
|
||||||
|
curPos = [0, 0]
|
||||||
|
for newChar in charList:
|
||||||
|
pilFont, underLine = pilFontNormal, False
|
||||||
|
if newChar[2] & ENNToolMiRCARTImporter._CellState.CS_BOLD:
|
||||||
|
pilFont = pilFontBold
|
||||||
|
if newChar[2] & ENNToolMiRCARTImporter._CellState.CS_UNDERLINE:
|
||||||
|
underLine = True
|
||||||
|
pilImageDraw.rectangle((*curPos, curPos[0] + pilFontSize[0], curPos[1] + pilFontSize[1] - 1),
|
||||||
|
fill=(*ENNToolMiRCARTColours[newChar[1]], 255))
|
||||||
|
pilImageDraw.text(curPos, newChar[3], (*ENNToolMiRCARTColours[newChar[0]], 255), pilFont)
|
||||||
|
if underLine:
|
||||||
|
pilImageDraw.line(
|
||||||
|
xy=(curPos[0], curPos[1] + (pilFontSize[1] - 2),
|
||||||
|
curPos[0] + pilFontSize[0], curPos[1] + pilFontSize[1]),
|
||||||
|
fill=(*ENNToolMiRCARTColours[newChar[0]], 255))
|
||||||
|
|
||||||
|
artInfo[newChar[0]][newChar[1]][newChar[2]][newChar[3]] = []
|
||||||
|
# Top Right
|
||||||
|
artInfo[newChar[0]][newChar[1]][newChar[2]][newChar[3]] += [float(curPos[0] + pilFontSize[0]) / pilImageSize[0], 0.0]
|
||||||
|
# Top Left
|
||||||
|
artInfo[newChar[0]][newChar[1]][newChar[2]][newChar[3]] += [float(curPos[0]) / pilImageSize[0], 0.0]
|
||||||
|
# Bottom Left
|
||||||
|
artInfo[newChar[0]][newChar[1]][newChar[2]][newChar[3]] += [float(curPos[0]) / pilImageSize[0], float(pilFontSize[1]) / pilImageSize[1]]
|
||||||
|
# Bottom Right
|
||||||
|
artInfo[newChar[0]][newChar[1]][newChar[2]][newChar[3]] += [float(curPos[0] + pilFontSize[0]) / pilImageSize[0], float(pilFontSize[1]) / pilImageSize[1]]
|
||||||
|
|
||||||
|
curPos[0] += pilFontSize[0]
|
||||||
|
return artInfo
|
||||||
|
# }}}
|
||||||
|
# {{{ _initArtInfoCharList(self): XXX
|
||||||
|
def _initArtInfoCharList(self, artMap):
|
||||||
|
artInfo, charList = ENNToolGLTTFTexture._nestedDict(), []
|
||||||
|
for numRow in range(len(artMap)):
|
||||||
|
for numCol in range(len(artMap[numRow])):
|
||||||
|
artFg = artMap[numRow][numCol][0]
|
||||||
|
artBg = artMap[numRow][numCol][1]
|
||||||
|
artAttrs = artMap[numRow][numCol][2]
|
||||||
|
artChar = artMap[numRow][numCol][3]
|
||||||
|
if artInfo[artFg][artBg][artAttrs][artChar] == {}:
|
||||||
|
artInfo[artFg][artBg][artAttrs][artChar] = None
|
||||||
|
charList += [[artFg, artBg, artAttrs, artChar]]
|
||||||
|
return artInfo, charList
|
||||||
|
# }}}
|
||||||
|
# {{{ _initFonts(self): XXX
|
||||||
|
def _initFonts(self):
|
||||||
|
fontBoldPathName = os.path.join("assets", "DejaVuSansMono-Bold.ttf")
|
||||||
|
fontNormalPathName = os.path.join("assets", "DejaVuSansMono.ttf")
|
||||||
|
fontSize = int("26")
|
||||||
|
pilFontBold = ImageFont.truetype(fontBoldPathName, fontSize)
|
||||||
|
pilFontNormal = ImageFont.truetype(fontNormalPathName, fontSize)
|
||||||
|
pilFontSize = list(pilFontNormal.getsize("_")) # XXX
|
||||||
|
return pilFontBold, pilFontNormal, pilFontSize
|
||||||
|
# }}}
|
||||||
|
# {{{ _initImage(self, charList, pilFontSize): XXX
|
||||||
|
def _initImage(self, charList, pilFontSize):
|
||||||
|
pilImageSize = (pilFontSize[0] * len(charList), pilFontSize[1])
|
||||||
|
pilImage = Image.new("RGBA", pilImageSize, (0, 0, 0, 0))
|
||||||
|
pilImageDraw = ImageDraw.Draw(pilImage)
|
||||||
|
return pilImage, pilImageDraw, pilImageSize
|
||||||
|
# }}}
|
||||||
|
# {{{ _initTexture(self, pilImage): XXX
|
||||||
|
def _initTexture(self, pilImage):
|
||||||
|
# [1], [2]
|
||||||
|
artTextureId = glGenTextures(1)
|
||||||
|
artTextureImage = pilImage
|
||||||
|
artTextureImageData = numpy.array(artTextureImage)
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, artTextureId)
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
||||||
|
|
||||||
|
# [3]
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
||||||
|
|
||||||
|
# [4][5]
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||||
|
artTextureImage.size[0], artTextureImage.size[1],
|
||||||
|
0, GL_RGBA, GL_UNSIGNED_BYTE, artTextureImageData)
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D)
|
||||||
|
|
||||||
|
return artTextureId
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
# {{{ getParams(self): XXX
|
||||||
|
def getParams(self):
|
||||||
|
return self.artTextureId, self.artInfo
|
||||||
|
# }}}
|
||||||
|
# {{{ __init__(self): initialisation method
|
||||||
|
def __init__(self, artMap, cubeSize, videoSize):
|
||||||
|
artInfo, charList = self._initArtInfoCharList(artMap)
|
||||||
|
pilFontBold, pilFontNormal, pilFontSize = self._initFonts()
|
||||||
|
pilImage, pilImageDraw, pilImageSize = self._initImage(charList, pilFontSize)
|
||||||
|
artInfo = self._drawCharList(artInfo, charList,
|
||||||
|
pilFontBold, pilFontNormal, pilFontSize,
|
||||||
|
pilImageDraw, pilImageSize)
|
||||||
|
artTextureId = self._initTexture(pilImage)
|
||||||
|
self.artTextureId = artTextureId
|
||||||
|
self.artInfo = artInfo
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
@ -1,78 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
#
|
|
||||||
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
|
|
||||||
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
|
||||||
# This project is licensed under the terms of the MIT license.
|
|
||||||
#
|
|
||||||
|
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
|
||||||
import os, string, yaml, sys
|
|
||||||
|
|
||||||
from ENNToolMiRCARTColours import ENNToolMiRCARTColours
|
|
||||||
from ENNToolMiRCARTImporter import ENNToolMiRCARTImporter
|
|
||||||
|
|
||||||
#
|
|
||||||
# Entry point
|
|
||||||
def main(*argv):
|
|
||||||
fontNormalPathName = os.path.join("assets", "DejaVuSansMono.ttf")
|
|
||||||
fontBoldPathName = os.path.join("assets", "DejaVuSansMono-Bold.ttf")
|
|
||||||
fontSize = int("26")
|
|
||||||
outInfoFileName = os.path.join("assets", "textures.yaml")
|
|
||||||
outFileName = os.path.join("assets", "DejaVuSansMono.png")
|
|
||||||
if not os.path.exists(os.path.dirname(outInfoFileName)):
|
|
||||||
os.makedirs(os.path.dirname(outInfoFileName))
|
|
||||||
if not os.path.exists(os.path.dirname(outFileName)):
|
|
||||||
os.makedirs(os.path.dirname(outFileName))
|
|
||||||
|
|
||||||
pilFontNormal = ImageFont.truetype(fontNormalPathName, fontSize)
|
|
||||||
pilFontBold = ImageFont.truetype(fontBoldPathName, fontSize)
|
|
||||||
pilFontSize = list(pilFontNormal.getsize(" "))
|
|
||||||
pilFontSize[0] += (8 - (pilFontSize[0] % 8))
|
|
||||||
pilFontSize[1] = pilFontSize[0] * 2
|
|
||||||
pilImageSize = (pilFontSize[0] * 128, (pilFontSize[1] * 16 * 4))
|
|
||||||
print("font size: {}, image size: {}".format(pilFontSize, pilImageSize))
|
|
||||||
|
|
||||||
curPos = [0, 0]
|
|
||||||
pilImage = Image.new("RGBA", pilImageSize, (0, 0, 0, 0))
|
|
||||||
pilImageDraw = ImageDraw.Draw(pilImage)
|
|
||||||
|
|
||||||
pilImageTmp = Image.new("RGBA", pilFontSize, (0, 0, 0, 0))
|
|
||||||
pilImageTmpDraw = ImageDraw.Draw(pilImageTmp)
|
|
||||||
|
|
||||||
for fontAttr in [ENNToolMiRCARTImporter._CellState.CS_BOLD | ENNToolMiRCARTImporter._CellState.CS_UNDERLINE,
|
|
||||||
ENNToolMiRCARTImporter._CellState.CS_UNDERLINE,
|
|
||||||
ENNToolMiRCARTImporter._CellState.CS_BOLD,
|
|
||||||
ENNToolMiRCARTImporter._CellState.CS_NONE]:
|
|
||||||
for fontColour in reversed(range(16)):
|
|
||||||
for fontChar in [chr(n) for n in range(128)]:
|
|
||||||
pilFont, underLine = pilFontNormal, False
|
|
||||||
if fontAttr & ENNToolMiRCARTImporter._CellState.CS_BOLD:
|
|
||||||
pilFont = pilFontBold
|
|
||||||
if fontAttr & ENNToolMiRCARTImporter._CellState.CS_UNDERLINE:
|
|
||||||
underLine = True
|
|
||||||
if fontChar in string.printable:
|
|
||||||
pilImageTmpDraw.text((0, 0), fontChar,
|
|
||||||
(*ENNToolMiRCARTColours[fontColour], 255), pilFont)
|
|
||||||
pilImage.paste(pilImageTmp, tuple(curPos))
|
|
||||||
pilImageTmpDraw.rectangle((0, 0, pilFontSize[0], pilFontSize[1]),
|
|
||||||
fill=(0, 0, 0, 0))
|
|
||||||
if underLine:
|
|
||||||
pilImageDraw.line(
|
|
||||||
xy=(curPos[0], curPos[1] + (pilFontSize[1] - 2),
|
|
||||||
curPos[0] + pilFontSize[0], curPos[1] + (pilFontSize[1] - 2)),
|
|
||||||
fill=(*ENNToolMiRCARTColours[fontColour], 255))
|
|
||||||
curPos[0] += pilFontSize[0]
|
|
||||||
curPos[0], curPos[1] = 0, curPos[1] + pilFontSize[1]
|
|
||||||
pilImage.save(outFileName)
|
|
||||||
artInfo = {}
|
|
||||||
artInfo["rowHeight"] = pilFontSize[1]
|
|
||||||
artInfo["rowWidth"] = pilFontSize[0]
|
|
||||||
artInfo["texHeight"] = pilImageSize[1]
|
|
||||||
artInfo["texWidth"] = pilImageSize[0]
|
|
||||||
with open(outInfoFileName, "w") as fileObject:
|
|
||||||
yaml.dump(artInfo, fileObject)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main(*sys.argv)
|
|
||||||
|
|
||||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
|
@ -2,4 +2,4 @@
|
|||||||
Copyright (c) 2018 Lucio Andrés Illanes Albornoz <<lucio@lucioillanes.de>>
|
Copyright (c) 2018 Lucio Andrés Illanes Albornoz <<lucio@lucioillanes.de>>
|
||||||
This project is licensed under the terms of the MIT licence.
|
This project is licensed under the terms of the MIT licence.
|
||||||
* Prerequisites on Windows: install Python v3.5.x and script dependencies w/ the following elevated command prompt command line:
|
* Prerequisites on Windows: install Python v3.5.x and script dependencies w/ the following elevated command prompt command line:
|
||||||
`pip install chardet numpy opencv-python Pillow PyOpenGL PyYAML wxPython`
|
`pip install chardet numpy opencv-python Pillow PyOpenGL wxPython`
|
||||||
|
@ -1 +0,0 @@
|
|||||||
DejaVuSansMono.png
|
|
@ -1 +0,0 @@
|
|||||||
{rowHeight: 48, rowWidth: 24, texHeight: 3072, texWidth: 3072}
|
|
Loading…
Reference in New Issue
Block a user