I was able to get pointers to missing opengl functions with
wglGetProcAddress on win.
Now it takes
10^-5 seconds to get pixel from PBO (not sure how inaccurate such small values are), with
glReadPixels as soon as drawing is complete and reading from PBO only when needed.
Probably it can be optimized more by manually creating framebuffer with params optimized for reading as opposed to 'for render', but at the same time I know that nvidia drivers are good at overriding hints when the usage doesn't match them, so it's also possible that the canvas was automatically optimized for reading.
Tried if I have the same issue with missing functions on linux, and there was no issue: just
ffi.load("GL") is enough. It ran 19 fps without requesting pixels and 17fps with requesting pixels. But since it was on VM, I can't really make any conclusions.
Tried it for android, and it says there's no "libGL.so". Made it fallback to
Canvas:newImageData if opengl loading wasn't successful. Anyways, android is to slow to run the game, so I tried it just out of curiosity.
Not sure if it's good enough, there's still a chance that I'll be forced to use the solution which doesn't involve reading pixels from framebuffers.
-- creating pbo
Code: Select all
ffi.GLL.glGenBuffers(1, PBO_id)
ffi.GLL.glBindBuffer(ffi.GL.GL_PIXEL_PACK_BUFFER, PBO_id[0])
ffi.GLL.glBufferData(ffi.GL.GL_PIXEL_PACK_BUFFER, memsize, nil, ffi.GL.GL_STREAM_READ)
ffi.GLL.glBindBuffer(ffi.GL.GL_PIXEL_PACK_BUFFER, 0)
-- requesting data from canvas
Code: Select all
love.graphics.setCanvas(zBuffer)
ffi.GLL.glBindBuffer(ffi.GL.GL_PIXEL_PACK_BUFFER, PBO_id[0])
ffi.GL.glReadPixels(love.mouse.getX(),love.mouse.getY(), 1,1, ffi.GL.GL_RGBA, ffi.GL.GL_UNSIGNED_BYTE, nil)
ffi.GLL.glBindBuffer(ffi.GL.GL_PIXEL_PACK_BUFFER, 0)
love.graphics.setCanvas()
--getting data from pixel buffer object
Code: Select all
ffi.GLL.glBindBuffer(ffi.GL.GL_PIXEL_PACK_BUFFER, PBO_id[0])
zImage2 = ffi.cast("unsigned char *", ffi.GLL.glMapBuffer(ffi.GL.GL_PIXEL_PACK_BUFFER,ffi.GL.GL_READ_ONLY))
ffi.GLL.glUnmapBuffer(ffi.GL.GL_PIXEL_PACK_BUFFER)
ffi.GLL.glBindBuffer(ffi.GL.GL_PIXEL_PACK_BUFFER, 0)
id = zImage2[0]
-- getting missing functions
Code: Select all
if ffi.GL and ffi.os == "Windows" then
ffi.cdef[[
typedef int (__stdcall *PROC)();
typedef char* LPCSTR;
PROC wglGetProcAddress(LPCSTR name);
]]
local nameHolder = ffi.new("char[100]")
ffi.GLL = {}
local function loadProc(definition, name)
ffi.copy(nameHolder, name)
ffi.GLL[name] = ffi.cast(definition, ffi.GL.wglGetProcAddress(nameHolder))
local asInt = ffi.cast("int",ffi.GLL[name])
if asInt >=-1 and asInt <=3 then
print("wglGetProcAddress returned nothing for "..name)
io.stdout:flush()
error("wglGetProcAddress returned nothing")
end
end
loadProc("void (*)(GLsizei, GLuint *)", "glGenBuffers")
loadProc("void (*)(GLenum, GLuint)", "glBindBuffer")
loadProc("void (*)(GLenum target, GLsizeiptr size, GLvoid* data, GLenum usage)", "glBufferData")
loadProc("void* (*)(GLenum target, GLenum access)", "glMapBuffer")
loadProc("GLboolean (*)(GLenum target)", "glUnmapBuffer")
else
ffi.GLL = ffi.GL
end