Skip to content

Instantly share code, notes, and snippets.

@z0w0
Created March 18, 2011 07:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save z0w0/875732 to your computer and use it in GitHub Desktop.
Save z0w0/875732 to your computer and use it in GitHub Desktop.
A python program with a wx interface for directly rendering and editing Blockland brick files (.blb). @blockland.us
#-------->
# BLB Editor
# by Zack "Zack0Wack0" Corr
# Updated: 04/02/11
#--------
import sys,os,wx
from time import strftime
import wx.stc
from wx import glcanvas
from OpenGL.GL import *
from OpenGL.GLU import gluBuild2DMipmaps
from PIL import Image
name = "BLB Editor"
version = 0.25
title = name + " v" + str(version)
description = "BLB Editor is an application for editing Blockland brick files (.blb). \nIt includes a 3D canvas for rendering your current brick model,\n a styled text editor and a range of other features."
author = "Zack0Wack0"
website = "http://www.zack0wack0.com"
#-------->
# Cross OS Compatibility
#--------
if wx.Platform == '__WXMSW__':
runningOS = "WINDOWS"
faces = { 'times': 'Times New Roman',
'mono' : 'Courier New',
'helv' : 'Arial',
'other': 'Comic Sans MS',
'size' : 10,
'size2': 8,
}
elif wx.Platform == '__WXMAC__':
runningOS = "MAC"
faces = { 'times': 'Times New Roman',
'mono' : 'Monaco',
'helv' : 'Arial',
'other': 'Comic Sans MS',
'size' : 12,
'size2': 10,
}
else:
runningOS = "OTHER" #it's probably linux or something
faces = { 'times': 'Times',
'mono' : 'Courier',
'helv' : 'Helvetica',
'other': 'new century schoolbook',
'size' : 12,
'size2': 10,
}
#-------->
# BLB Handling
#--------
class Handler:
"""Handles all the BLB parsing and writing.""" #lol I never got around to it
def __init__(self):
pass
#-------->
# GUI
#--------
id_file_new = 0
id_file_open = 1
id_file_import = 2
id_file_save = 3
id_file_saveas = 4
id_file_exit = 10
id_view_zoomin = 5
id_view_zoomout = 6
id_view_refresh = 7
id_view_axii = 8
id_view_grid = 9
id_help_about = 11
class Application(wx.App):
"""Controls everything."""
def __init__(self,title,version):
self.saved = False
self.text = ""
self.file = ""
self.directory = ""
self.title = title
self.handler = Handler()
wipe = open("log.txt","w")
wipe.write(strftime("%d/%m/%Y %H:%M:%S") + "\n")
wipe.close()
wx.App.__init__(self,redirect=True,filename="log.txt")
def OnInit(self):
print self.title + " by Zack \"Zack0Wack0\" Corr"
self.frame = wx.Frame(None,-1,self.title,pos=(50,50),size=(640,480),style=wx.DEFAULT_FRAME_STYLE)
try:
self.icon = wx.Icon("icon.ico",wx.BITMAP_TYPE_ICO)
self.frame.SetIcon(self.icon)
except:
pass
self.frame.app = self
self.statusbar = self.frame.CreateStatusBar()
self.menubar = wx.MenuBar()
self.fileMenu = wx.Menu()
self.fileMenuNew = self.fileMenu.Append(id_file_new,"&New\tCtrl+N")
self.Bind(wx.EVT_MENU,self.onNew,id=id_file_new)
self.fileMenuOpen = self.fileMenu.Append(id_file_open,"&Open...\tCtrl+O")
self.Bind(wx.EVT_MENU,self.onOpen,id=id_file_open)
self.fileMenuImport = self.fileMenu.Append(id_file_import,"&Import...\tCtrl+I")
self.Bind(wx.EVT_MENU,self.onImport,id=id_file_import)
self.fileMenuSave = self.fileMenu.Append(id_file_save,"&Save\tCtrl+S")
self.Bind(wx.EVT_MENU,self.onQuickSave,id=id_file_save)
self.fileMenuSaveAs = self.fileMenu.Append(id_file_saveas,"Save &As...")
self.Bind(wx.EVT_MENU,self.onSave,id=id_file_saveas)
self.fileMenu.AppendSeparator()
self.fileMenuExit = self.fileMenu.Append(id_file_exit,"Exit")
self.Bind(wx.EVT_MENU,self.onExit,id=id_file_exit)
self.viewMenu = wx.Menu()
self.viewMenuZoomIn = self.viewMenu.Append(id_view_zoomin,"Zoom &In\tCtrl+=")
self.Bind(wx.EVT_MENU,self.onZoomIn,id=id_view_zoomin)
self.viewMenuZoomOut = self.viewMenu.Append(id_view_zoomout,"Zoom &Out\tCtrl+-")
self.Bind(wx.EVT_MENU,self.onZoomOut,id=id_view_zoomout)
self.viewMenuRefresh = self.viewMenu.Append(id_view_refresh,"&Refresh\tCtrl+R")
self.Bind(wx.EVT_MENU,self.onRefresh,id=id_view_refresh)
self.viewMenuAxii = self.viewMenu.Append(id_view_axii,"&Toggle Axii\tCtrl+M")
self.Bind(wx.EVT_MENU,self.onToggleAxii,id=id_view_axii)
self.viewMenuGrid = self.viewMenu.Append(id_view_grid,"&Toggle Grid\tCtrl+G")
self.Bind(wx.EVT_MENU,self.onToggleGrid,id=id_view_grid)
self.helpMenu = wx.Menu()
self.helpMenuAbout = self.helpMenu.Append(id_help_about,"&About")
self.Bind(wx.EVT_MENU,self.onAbout,id=id_help_about)
self.menubar.Append(self.fileMenu,"File")
self.menubar.Append(self.viewMenu,"View")
self.menubar.Append(self.helpMenu,"Help")
self.frame.SetMenuBar(self.menubar)
self.frame.Bind(wx.EVT_CLOSE,self.onExit)
self.frame.Show(True)
self.frame.SetSize((640, 480))
self.frame.Centre()
self.panel = MainPanel(self.frame,app=self)
self.SetTopWindow(self.frame)
self.newFile(True)
print "Successfully started up."
return True
def openFile(self):
doOpen = True
if self.file != "" and self.saved != True:
doOpen = False
dialog = wx.MessageDialog(self.frame,"You haven't saved your current file. Do you want to save it before opening a new file?","Opening a file",wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION)
result = dialog.ShowModal()
dialog.Destroy()
if result == wx.ID_YES:
self.saveFile()
doOpen = True
elif result == wx.ID_NO:
doOpen = True
if not doOpen:
return
dialog = wx.FileDialog(self.frame,"Open",self.directory,self.file,"Blockland Brick Files (*.blb)|*.blb",wx.OPEN)
if dialog.ShowModal() == wx.ID_OK:
self.file = dialog.GetFilename()
self.directory = dialog.GetDirectory()
try:
reader = open(os.path.join(self.directory,self.file),"r")
text = ""
for line in reader:
text = text + line
self.panel.text.SetText(text)
reader.close()
self.frame.SetStatusText("Opened " + self.file + " at " + strftime("%H:%M:%S") + ".")
self.saved = True
self.frame.SetTitle(self.title + " - " + self.file)
self.refresh(True)
except:
self.frame.SetStatusText("Failed to open.")
dialog.Destroy()
def importFile(self):
pass
def newFile(self,forced=False):
doNewFile = True
if not self.saved and not forced:
doNewFile = False
dialog = wx.MessageDialog(self.frame,"You haven't saved your current file. Do you want to save it now?","New file",wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION)
result = dialog.ShowModal()
dialog.Destroy()
if result == wx.ID_YES:
self.saveFile()
doNewFile = True
elif result == wx.ID_NO:
doNewFile = True
if doNewFile:
self.file = ""
self.directory = ""
self.text = ""
self.saved = True
self.panel.text.SetText("")
self.frame.SetTitle(self.title)
def saveFileAs(self):
dialog = wx.FileDialog(self.frame,"Save As",self.directory,self.file,"Blockland Brick Files (*.blb)|*.blb",wx.SAVE | wx.OVERWRITE_PROMPT)
if dialog.ShowModal() == wx.ID_OK:
self.file = dialog.GetFilename()
self.directory = dialog.GetDirectory()
dialog.Destroy()
self.saveFile()
return
dialog.Destroy()
def saveFile(self):
if self.saved:
return
if self.file != "":
try:
writer = open(os.path.join(self.directory,self.file),"w")
writer.write(self.panel.text.GetText())
writer.close()
self.frame.SetStatusText("Saved " + self.file + " at " + strftime("%H:%M:%S") + ".")
self.saved = True
self.frame.SetTitle(self.title + " - " + self.file)
except:
self.frame.SetStatusText("Failed to save.")
else:
self.saveFileAs()
def exit(self):
self.frame.Destroy()
def about(self):
info = wx.AboutDialogInfo()
try:
info.SetIcon(self.icon)
except:
pass
info.SetName(name)
info.SetVersion(str(version))
info.SetDescription(description)
info.SetWebSite(website)
info.AddDeveloper(author)
wx.AboutBox(info)
def refresh(self,reset=False):
lines = self.panel.text.GetText()
if lines == "":
return
lines = lines.split("\n")
try:
size = lines[0]
size = size.strip().split()
modelSize = [int(size[0]),int(size[1]),int(size[2])]
type = lines[1]
if type == "BRICK":
#doesn't support normal bricks "yet"
return
lines = lines[2:]
except:
return
linecount = -1
polygons = []
for line in lines:
linecount = linecount + 1
if len(line) >= 4:
if line[0:4] == "TEX:" and len(lines)-linecount >= 15:
successes = 0
texture = line[4:]
colour = []
if lines[linecount+1][0:9].strip() == "POSITION:":
pos1 = lines[linecount+2].strip().split()
pos2 = lines[linecount+3].strip().split()
pos3 = lines[linecount+4].strip().split()
pos4 = lines[linecount+5].strip().split()
try:
pos1X = float(pos1[0])
pos1Y = float(pos1[1])
pos1Z = float(pos1[2])
pos1 = [pos1X,pos1Y,pos1Z]
pos2X = float(pos2[0])
pos2Y = float(pos2[1])
pos2Z = float(pos2[2])
pos2 = [pos2X,pos2Y,pos2Z]
pos3X = float(pos3[0])
pos3Y = float(pos3[1])
pos3Z = float(pos3[2])
pos3 = [pos3X,pos3Y,pos3Z]
pos4X = float(pos4[0])
pos4Y = float(pos4[1])
pos4Z = float(pos4[2])
pos4 = [pos4X,pos4Y,pos4Z]
successes = successes + 1
except:
continue
if lines[linecount+6][0:10].strip() == "UV COORDS:":
uv1 = lines[linecount+7].strip().split()
uv2 = lines[linecount+8].strip().split()
uv3 = lines[linecount+9].strip().split()
uv4 = lines[linecount+10].strip().split()
try:
uv1X = float(uv1[0])
uv1Y = float(uv1[1])
uv1 = [uv1X,uv1Y]
uv2X = float(uv2[0])
uv2Y = float(uv2[1])
uv2 = [uv2X,uv2Y]
uv3X = float(uv3[0])
uv3Y = float(uv3[1])
uv3 = [uv3X,uv3Y]
uv4X = float(uv4[0])
uv4Y = float(uv4[1])
uv4 = [uv4X,uv4Y]
successes = successes + 1
except:
continue
if lines[linecount+11][0:7].strip() == "COLORS:" and len(lines)-linecount >= 20:
colour1 = lines[linecount+12].strip().split()
colour2 = lines[linecount+13].strip().split()
colour3 = lines[linecount+14].strip().split()
colour4 = lines[linecount+15].strip().split()
try:
colour1R = float(colour1[0])
colour1G = float(colour1[1])
colour1B = float(colour1[2])
colour1A = float(colour1[3])
colour1 = [colour1R,colour1G,colour1B,colour1A]
colour2R = float(colour2[0])
colour2G = float(colour2[1])
colour2B = float(colour2[2])
colour2A = float(colour2[3])
colour2 = [colour2R,colour2G,colour2B,colour2A]
colour3R = float(colour3[0])
colour3G = float(colour3[1])
colour3B = float(colour3[2])
colour3A = float(colour3[3])
colour3 = [colour3R,colour3G,colour3B,colour3A]
colour4R = float(colour4[0])
colour4G = float(colour4[1])
colour4B = float(colour4[2])
colour4A = float(colour4[3])
colour4 = [colour4R,colour4G,colour4B,colour4A]
colour = [colour1,colour2,colour3,colour4]
successes = successes + 1
except:
continue
if lines[linecount+16][0:8].strip() == "NORMALS:":
normal1 = lines[linecount+17].strip().split()
normal2 = lines[linecount+18].strip().split()
normal3 = lines[linecount+19].strip().split()
normal4 = lines[linecount+20].strip().split()
try:
normal1X = float(normal1[0])
normal1Y = float(normal1[1])
normal1Z = float(normal1[2])
normal1 = [normal1X,normal1Y,normal1Z]
normal2X = float(normal2[0])
normal2Y = float(normal2[1])
normal2Z = float(normal2[2])
normal2 = [normal2X,normal2Y,normal2Z]
normal3X = float(normal3[0])
normal3Y = float(normal3[1])
normal3Z = float(normal3[2])
normal3 = [normal3X,normal3Y,normal3Z]
normal4X = float(normal4[0])
normal4Y = float(normal4[1])
normal4Z = float(normal4[2])
normal4 = [normal4X,normal4Y,normal4Z]
successes = successes + 1
except:
continue
if lines[linecount+11][0:8].strip() == "NORMALS:":
normal1 = lines[linecount+12].strip().split()
normal2 = lines[linecount+13].strip().split()
normal3 = lines[linecount+14].strip().split()
normal4 = lines[linecount+15].strip().split()
try:
normal1X = float(normal1[0])
normal1Y = float(normal1[1])
normal1Z = float(normal1[2])
normal1 = [normal1X,normal1Y,normal1Z]
normal2X = float(normal2[0])
normal2Y = float(normal2[1])
normal2Z = float(normal2[2])
normal2 = [normal2X,normal2Y,normal2Z]
normal3X = float(normal3[0])
normal3Y = float(normal3[1])
normal3Z = float(normal3[2])
normal3 = [normal3X,normal3Y,normal3Z]
normal4X = float(normal4[0])
normal4Y = float(normal4[1])
normal4Z = float(normal4[2])
normal4 = [normal4X,normal4Y,normal4Z]
successes = successes + 1
except:
continue
if successes > 2:
poly = [texture,[pos1,pos2,pos3,pos4],[normal1,normal2,normal3,normal4],[uv1,uv2,uv3,uv4],colour]
polygons.append(poly)
self.panel.canvas.updateModel(polygons,modelSize,reset)
self.panel.canvas.Refresh(False)
if len(polygons) > 0:
self.frame.SetStatusText("Refreshed " + str(len(polygons)) + " polygons at " + strftime("%H:%M:%S") + ".")
def zoomIn(self):
self.panel.canvas.zoomIn()
self.panel.canvas.Refresh(False)
def zoomOut(self):
self.panel.canvas.zoomOut()
self.panel.canvas.Refresh(False)
def toggleGrid(self):
self.panel.canvas.toggleGrid()
self.panel.canvas.Refresh(False)
def toggleAxii(self):
self.panel.canvas.toggleAxii()
self.panel.canvas.Refresh(False)
def onNew(self,event):
self.newFile()
def onOpen(self,event):
self.openFile()
def onImport(self,event):
self.importFile()
def onSave(self,event):
self.saveFileAs()
def onQuickSave(self,event):
self.saveFile()
def onZoomIn(self,event):
self.zoomIn()
def onZoomOut(self,event):
self.zoomOut()
def onToggleGrid(self,event):
self.toggleGrid()
def onToggleAxii(self,event):
self.toggleAxii()
def onRefresh(self,event):
self.refresh()
def onAbout(self,event):
self.about()
def onExit(self,event):
if not self.saved:
close = False
dialog = wx.MessageDialog(self.frame,"You haven't saved your current file. Do you want to save it now?","Exiting program",wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION)
result = dialog.ShowModal()
dialog.Destroy()
if result == wx.ID_YES:
self.saveFile()
close = True
elif result == wx.ID_NO:
close = True
if close:
self.exit()
else:
self.exit()
class MainPanel(wx.Panel):
"""The main GUI."""
def __init__(self,parent,app=None):
wx.Panel.__init__(self,parent,-1)
self.parent = parent
self.box = wx.BoxSizer(wx.HORIZONTAL)
self.canvas = CanvasPanel(self)
self.canvas.SetSize((400,400))
self.box.Add(self.canvas,6,wx.EXPAND)
self.text = TextPanel(self)
self.box.Add(self.text,4,wx.EXPAND)
self.text.EmptyUndoBuffer()
self.text.Colourise(0,-1)
self.text.SetMarginType(1,wx.stc.STC_MARGIN_NUMBER)
self.text.SetMarginWidth(1,25)
self.SetAutoLayout(True)
self.SetSizer(self.box)
class TextPanel(wx.stc.StyledTextCtrl):
def __init__(self,parent,id=-1,pos=wx.DefaultPosition,size=wx.DefaultSize,style=0):
self.keywords = "TEX POSITION UV COORDS NORMALS COVERAGE SPECIAL BRICK"
wx.stc.StyledTextCtrl.__init__(self,parent,id,pos,size,style)
self.parent = parent
self.SetKeyWords(0,self.keywords)
self.SetProperty("fold","1")
self.SetProperty("tab.timmy.whinge.level","1")
self.SetMargins(0,0)
self.SetViewWhiteSpace(False)
self.SetMarginWidth(2,8)
self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT,"face:%(helv)s,size:%(size)d" % faces)
self.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,"back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces)
self.StyleSetSpec(wx.stc.STC_STYLE_CONTROLCHAR,"face:%(other)s" % faces)
self.StyleSetSpec(wx.stc.STC_STYLE_BRACELIGHT,"fore:#FFFFFF,back:#0000FF,bold")
self.StyleSetSpec(wx.stc.STC_STYLE_BRACEBAD,"fore:#000000,back:#FF0000,bold")
self.StyleSetSpec(1,"fore:#00AAFF,face:%(helv)s,size:%(size)d" % faces)
self.SetLexer(wx.stc.STC_LEX_CONTAINER)
self.Bind(wx.EVT_KEY_DOWN,self.onKeyPressed)
self.Bind(wx.stc.EVT_STC_STYLENEEDED,self.onStyleNeeded)
def onKeyPressed(self,event):
event.Skip()
newText = self.GetText()
if self.parent.parent.app.text != newText:
if self.parent.parent.app.saved:
if self.parent.parent.app.file != "":
self.parent.parent.SetTitle(self.parent.parent.app.title + " - *" + self.parent.parent.app.file)
self.parent.parent.app.saved = False
self.parent.parent.app.text = newText
def onStyleNeeded(self,event):
end = event.GetPosition()
start = self.GetEndStyled()
self.StartStyling(start,0x1f)
for i in range(start,end + 1):
c = self.GetCharAt(i)
if 48 <= c <= 57:
self.SetStyling(1,1)
else:
self.SetStyling(1,0)
class CanvasPanel(glcanvas.GLCanvas):
"""The 3D canvas."""
def __init__(self,parent):
glcanvas.GLCanvas.__init__(self,parent,-1)
self.polygons = []
self.parent = parent
self.init = False
self.lastx = self.x = 0
self.lasty = self.y = 0
self.size = None
self.scale = 0.1
self.noRotateFix = False
self.axii = True
self.grid = False
self.gridList = None
self.maxScale = 0.1
self.minScale = 0.05
self.Bind(wx.EVT_ERASE_BACKGROUND,self.onEraseBackground)
self.Bind(wx.EVT_SIZE,self.onSize)
self.Bind(wx.EVT_PAINT,self.onPaint)
self.Bind(wx.EVT_LEFT_DOWN,self.onMouseDown)
self.Bind(wx.EVT_LEFT_UP,self.onMouseUp)
self.Bind(wx.EVT_MOTION,self.onMouseMotion)
self.Bind(wx.EVT_KEY_DOWN,self.onKeyPressed)
def updateModel(self,polygons,modelSize,reset=False):
self.polygons = polygons
self.modelSize = modelSize
volume = self.modelSize[0] * self.modelSize[1]
self.maxScale = (pow(volume,2.1) / pow(volume,2.5)) * 0.75
self.minScale = 0.01
if reset:
glScale(self.maxScale,self.maxScale,self.maxScale)
self.scale = self.maxScale
def loadImage(self,imageFile,sWrap=GL_REPEAT,tWrap=GL_REPEAT,rWrap=GL_REPEAT):
im = Image.open(imageFile)
width = im.size[0]
height = im.size[1]
image = im.tostring("raw","RGBX",0,-1)
id = glGenTextures(1)
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
glBindTexture(GL_TEXTURE_2D,id)
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,image)
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,sWrap)
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,tWrap)
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_R,rWrap)
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE)
return id
def zoomIn(self):
glScale(1.03,1.03,1.03)
self.noRotateFix = True
def zoomOut(self):
glScale(0.97,0.97,0.97)
self.noRotateFix = True
def toggleAxii(self):
if self.axii:
self.axii = False
else:
self.axii = True
def toggleGrid(self):
if self.grid:
self.grid = False
else:
self.grid = True
def onEraseBackground(self,event):
pass
def onSize(self,event):
size = self.size = self.GetClientSize()
if self.GetContext():
self.SetCurrent()
glViewport(0,0,size.width,size.height)
event.Skip()
def onPaint(self,event):
dc = wx.PaintDC(self)
self.SetCurrent()
if not self.init:
self.initCanvas()
self.init = True
self.onDraw()
def onMouseDown(self,event):
self.CaptureMouse()
self.x, self.y = self.lastx, self.lasty = event.GetPosition()
def onMouseUp(self,event):
if self and self.HasCapture():
self.ReleaseMouse()
def onMouseMotion(self,event):
if event.Dragging() and event.LeftIsDown():
self.lastx, self.lasty = self.x, self.y
self.x, self.y = event.GetPosition()
self.Refresh(False)
if event.MiddleIsDown():
wheelRot = event.GetWheelRotation()
if wheelrot != 0:
if wheelrot > 0:
self.zoomIn()
else:
self.zoomOut()
self.Refresh(False)
def onKeyPressed(self,event):
if event.GetKeyCode() == wx.WXK_UP:
if self.zoom >= 6:
return
self.zoom = self.zoom + 1
if event.GetKeyCode() == wx.WXK_DOWN:
if self.zoom <= 0:
return
self.zoom = self.zoom - 1
event.Skip()
def initCanvas(self):
try:
self.texture = {
"TOP": self.loadImage("brickTOP.bmp"),
"SIDE": self.loadImage("brickSIDE.bmp"),
"RAMP": self.loadImage("brickRAMP.bmp"),
"BOTTOMEDGE": self.loadImage("brickBOTTOMEDGE.bmp",GL_CLAMP,GL_CLAMP),
"BOTTOMLOOP": self.loadImage("brickBOTTOMLOOP.bmp"),
"PRINT": self.loadImage("brickPRINT.bmp")
}
self.usesTextures = True
print "Textures loaded successfully."
except Exception as exception:
self.usesTextures = False
print "Textures failed to load. (" + str(exception) + ")"
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glMatrixMode(GL_PROJECTION)
glFrustum(-0.5,0.5,-0.5,0.5,1,3)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0,0,-2)
glRotatef(self.y,1.0,0.0,0.0)
glRotatef(self.x,0.0,1.0,0.0)
glEnable(GL_DEPTH_TEST)
def onDraw(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glDisable(GL_LIGHTING)
useColour = False
glEnable(GL_COLOR_MATERIAL)
faceID = -1
for poly in self.polygons:
faceID += 1
texture = poly[0]
pos1 = poly[1][0]
pos2 = poly[1][1]
pos3 = poly[1][2]
pos4 = poly[1][3]
normal1 = poly[2][0]
normal2 = poly[2][1]
normal3 = poly[2][2]
normal4 = poly[2][3]
uv1 = poly[3][0]
uv2 = poly[3][1]
uv3 = poly[3][2]
uv4 = poly[3][3]
colour = poly[4]
useColour = False
if len(colour) > 0:
colour1 = colour[0]
colour2 = colour[1]
colour3 = colour[2]
colour4 = colour[3]
#due to openGL lamos you can't enable and disable blend during drawing, so sucks for you if you need each vertex a different transparency
if colour1[3] < 1.0:
glEnable(GL_BLEND)
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA,GL_ONE_MINUS_DST_ALPHA)
useColour = True
else:
glColor4f(1,1,1,1)
glEnable(GL_TEXTURE_2D)
if self.usesTextures and not useColour:
glBindTexture(GL_TEXTURE_2D,self.texture[texture])
glBegin(GL_QUADS)
if useColour:
glColor4f(colour1[0],colour1[1],colour1[2],colour1[3])
else:
glTexCoord2f(uv1[0],uv1[1])
glNormal3f(normal1[0],normal1[1],normal1[2])
glVertex3f(pos1[0],pos1[1],(pos1[2]) / 3)
if useColour:
glColor4f(colour2[0],colour2[1],colour2[2],colour2[3])
else:
glTexCoord2f(uv2[0],uv2[1])
glNormal3f(normal2[0],normal2[1],normal2[2])
glVertex3f(pos2[0],pos2[1],(pos2[2]) / 3)
if useColour:
glColor4f(colour3[0],colour3[1],colour3[2],colour3[3])
else:
glTexCoord2f(uv3[0],uv3[1])
glNormal3f(normal3[0],normal3[1],normal3[2])
glVertex3f(pos3[0],pos3[1],(pos3[2]) / 3)
if useColour:
glColor4f(colour4[0],colour4[1],colour4[2],colour4[3])
else:
glTexCoord2f(uv4[0],uv4[1])
glNormal3f(normal4[0],normal4[1],normal4[2])
glVertex3f(pos4[0],pos4[1],(pos4[2]) / 3)
glEnd()
glFlush()
if not useColour:
glDisable(GL_TEXTURE_2D)
else:
glDisable(GL_BLEND)
glDisable(GL_COLOR_MATERIAL)
if self.axii:
glLineWidth(2)
glDisable(GL_LIGHTING)
glBegin(GL_LINES)
glColor4f(1,0,0,1)
glVertex3f(0,0,0)
glVertex3f(10000,0,0)
glColor4f(0,1,0,1)
glVertex3f(0,0,0)
glVertex3f(0,10000,0)
glColor4f(0,0,1,1)
glVertex3f(0,0,0)
glVertex3f(0,0,10000)
glEnd()
glEnable(GL_LIGHTING)
if self.grid:
if self.gridList == None:
self.parent.parent.SetStatusText("Compiling the grid. This could take a while.")
self.gridList = glGenLists(1)
glNewList(self.gridList,GL_COMPILE)
glLineWidth(1)
glBegin(GL_LINES)
for x in range(64):
for y in range(64):
x = float(x)
y = float(y)
glColor4f(0.5,0.5,0.5,1)
a = (x - 32) - 0.5
b = (y - 32) - 0.5
c = x - 0.5
d = y - 0.5
glVertex3f(a,b,0)
glVertex3f(a,d,0)
glVertex3f(a,b,0)
glVertex3f(c,b,0)
glEnd()
glEndList()
glDisable(GL_LIGHTING)
glCallList(self.gridList)
glEnable(GL_LIGHTING)
self.parent.parent.SetStatusText("Finished compiling the grid.")
else:
glDisable(GL_LIGHTING)
glCallList(self.gridList)
glEnable(GL_LIGHTING)
if self.size is None:
self.size = self.GetClientSize()
w, h = self.size
w = max(w,1.0)
h = max(h,1.0)
xScale = 180.0 / w
yScale = 180.0 / h
if not self.noRotateFix:
glRotate((self.y - self.lasty) * yScale,1,0,0)
glRotate((self.x - self.lastx) * xScale,0,1,0)
else:
self.noRotateFix = False
self.SwapBuffers()
#-------->
# Run
#--------
BLBEditor = Application(title,version)
BLBEditor.MainLoop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment