Right way to draw to screen?
Posted: Sun Feb 17, 2013 1:17 am
[EDIT: A week after posting this, I realized the answer, and feel compelled to share in case anybody ever wonders the same thing I wondered. The correct way to draw a pixel is to use drawQuad-- you can keep track of your glScale() and scale your quadrant appropriately, if you really, really need 1 pixel. For my particular problem, the right answer is not to draw lines with end points determined by trig functions, but to glTranslate to my center point, then glRotate to an appropriate angle, drawing a very thin quad from -0.5*length, radius to 0.5*length, radius+width. Do this through your full 2pi and you get your circle. Note that my original method gives a polygon contained in a circle, and the method in this edit gives a polygon that contains a circle, but you can tweak your radius to make these the same thing.]
I've been experimenting with drawing to the screen lately-- have found a way to do it, but I doubt it's The Right Way. Looking for feedback-- "yeah, that's good enough," "no, you should do it this way," etc.
Here's what I got:
in mod/class/uiset/minimalist.lua/_M:displayResources:
Basically what I'm doing is using drawing a texture to a single pixel in lieu of drawing directly to that pixel. DrawArc should demonstrate why I can't just rescale the texture to do this-- I want to make curved lines, of various radii and angles, to represent some in-game stats. (With rotation and small enough pie slices, I could approximate this with textures, but that seems clunky.)
Not sure if it's a big deal from a performance standpoint, not sure if there are some better functions I can access that I just haven't noticed.
I've been experimenting with drawing to the screen lately-- have found a way to do it, but I doubt it's The Right Way. Looking for feedback-- "yeah, that's good enough," "no, you should do it this way," etc.
Here's what I got:
in mod/class/uiset/minimalist.lua/_M:displayResources:
Code: Select all
local drawLine = function (xStart, yStart, xEnd, yEnd, dotDensity, color, shader)
--draws a line of a certain dot density
local x, y = xStart, yStart
local length = math.sqrt((x-xEnd)^2+(y-yEnd)^2)
local step = 0
local xSlope, ySlope = (xEnd - xStart)/length, (yEnd -yStart)/length
while step < length do
shat[1]:toScreenPrecise(x, y, 1/dotDensity, 1/dotDensity, 0, 1, 0, 1, color[1], color[2], color[3], 1)
step = step + 1/dotDensity
x = x+xSlope
y = y+ySlope
end
end
local fixAngles = function (angle)
while angle >= 2*math.pi do
angle = angle - 2*math.pi
end
while angle < 0 do
angle = angle + 2*math.pi
end
return angle
end
local polarToCartesian = function (angle, radius)
return radius*math.cos(fixAngles(angle)), radius*math.sin(fixAngles(angle))
end
local drawArc = function (xCenter, yCenter, radius, angleStart, angleEnd, numCorners, dotDensity, color, shader)
--draws an arc centered on, of radius, starting at angle, ending at angle, represented by a segment of a polygon of a certain number of corners,of certain density and color;
--angle 0 is East, angle pi/2 is South
if numCorners < 3 then return nil end
local start, stop = fixAngles(angleStart), angleEnd
if stop <= start then stop = stop + 2*math.pi end
local corners = math.ceil(numCorners*(stop-start)/(2*math.pi))
--this is the number of actual lines our arc will be composed of, whereas numCorners is the number of corners if the arc were to describe an entire circle
for count = 1, corners do
local angleNext = start+(2*math.pi/numCorners)
if angleNext > stop then angleNext = stop end
local xStart, yStart = polarToCartesian(start, radius)
local xStop, yStop = polarToCartesian(angleNext, radius)
drawLine(xStart+xCenter, yStart+yCenter, xStop+xCenter, yStop+yCenter, dotDensity, color, shader)
start = angleNext
end
return true
end
--test my function
drawArc(160, 160, 40, 0, math.pi, 12, 1, hate_c)
Not sure if it's a big deal from a performance standpoint, not sure if there are some better functions I can access that I just haven't noticed.