mirror of https://github.com/axmolengine/axmol.git
finish gl backend
This commit is contained in:
parent
e53fa3560b
commit
d2acbe176e
|
@ -485,7 +485,6 @@ void RenderTexture::newImage(std::function<void(Image*)> imageCallback, bool fli
|
|||
auto image = new(std::nothrow) Image();
|
||||
image->initWithRawData(pbd._data.getBytes(), pbd._data.getSize(), pbd._width, pbd._height, 8);
|
||||
imageCallback(image);
|
||||
image->release();
|
||||
}
|
||||
else imageCallback(nullptr);
|
||||
};
|
||||
|
|
|
@ -71,81 +71,6 @@ int ccNextPOT(int x)
|
|||
|
||||
namespace utils
|
||||
{
|
||||
/**
|
||||
* Capture screen implementation, don't use it directly.
|
||||
*/
|
||||
void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename, const unsigned char* imageData, int width, int height)
|
||||
{
|
||||
if(!imageData)
|
||||
{
|
||||
afterCaptured(false, "");
|
||||
return;
|
||||
}
|
||||
|
||||
static bool startedCapture = false;
|
||||
|
||||
if (startedCapture)
|
||||
{
|
||||
CCLOG("Screen capture is already working");
|
||||
if (afterCaptured)
|
||||
{
|
||||
afterCaptured(false, filename);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
startedCapture = true;
|
||||
}
|
||||
|
||||
bool succeed = false;
|
||||
std::string outputFile = "";
|
||||
|
||||
do
|
||||
{
|
||||
Image* image = new (std::nothrow) Image;
|
||||
if (image)
|
||||
{
|
||||
image->initWithRawData(imageData, width * height * 4, width, height, 8);
|
||||
if (FileUtils::getInstance()->isAbsolutePath(filename))
|
||||
{
|
||||
outputFile = filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCASSERT(filename.find('/') == std::string::npos, "The existence of a relative path is not guaranteed!");
|
||||
outputFile = FileUtils::getInstance()->getWritablePath() + filename;
|
||||
}
|
||||
|
||||
// Save image in AsyncTaskPool::TaskType::TASK_IO thread, and call afterCaptured in mainThread
|
||||
static bool succeedSaveToFile = false;
|
||||
std::function<void(void*)> mainThread = [afterCaptured, outputFile](void* /*param*/)
|
||||
{
|
||||
if (afterCaptured)
|
||||
{
|
||||
afterCaptured(succeedSaveToFile, outputFile);
|
||||
}
|
||||
startedCapture = false;
|
||||
};
|
||||
|
||||
AsyncTaskPool::getInstance()->enqueue(AsyncTaskPool::TaskType::TASK_IO, std::move(mainThread), nullptr, [image, outputFile]()
|
||||
{
|
||||
succeedSaveToFile = image->saveToFile(outputFile);
|
||||
delete image;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
CCLOG("Malloc Image memory failed!");
|
||||
if (afterCaptured)
|
||||
{
|
||||
afterCaptured(succeed, outputFile);
|
||||
}
|
||||
startedCapture = false;
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Capture screen interface
|
||||
*/
|
||||
|
@ -164,7 +89,6 @@ void captureScreen(std::function<void(Image*)> imageCallback)
|
|||
auto image = new(std::nothrow) Image();
|
||||
image->initWithRawData(pbd._data.getBytes(), pbd._data.getSize(), pbd._width, pbd._height, 8);
|
||||
imageCallback(image);
|
||||
image->release();
|
||||
}
|
||||
else imageCallback(nullptr);
|
||||
};
|
||||
|
|
|
@ -51,11 +51,14 @@ struct TextureDescriptor
|
|||
SamplerDescriptor samplerDescriptor;
|
||||
};
|
||||
|
||||
class UtilsGL;
|
||||
|
||||
/**
|
||||
* A base texture
|
||||
*/
|
||||
class TextureBackend : public Ref
|
||||
{
|
||||
friend class UtilsGL;
|
||||
public:
|
||||
/**
|
||||
* Update sampler
|
||||
|
@ -98,7 +101,7 @@ public:
|
|||
|
||||
virtual int getCount() const { return 1; };
|
||||
|
||||
virtual uintptr_t getGPUHandler(int index = 0) const { return 0; }
|
||||
virtual uintptr_t getHandler(int index = 0) const { return 0; }
|
||||
|
||||
int getWidth() const { return _width; }
|
||||
int getHeight() const { return _height; }
|
||||
|
|
|
@ -628,32 +628,43 @@ void CommandBufferGL::setScissorRect(bool isEnabled, float x, float y, float wid
|
|||
}
|
||||
}
|
||||
|
||||
void CommandBufferGL::captureScreen(std::function<void(const unsigned char*, int, int)> callback)
|
||||
void CommandBufferGL::capture(TextureBackend* texture, std::function<void(const PixelBufferDescriptor&)> callback)
|
||||
{
|
||||
int bufferSize = _viewPort.w * _viewPort.h *4;
|
||||
std::shared_ptr<GLubyte> buffer(new GLubyte[bufferSize], [](GLubyte* p){ CC_SAFE_DELETE_ARRAY(p); });
|
||||
memset(buffer.get(), 0, bufferSize);
|
||||
if (!buffer)
|
||||
{
|
||||
callback(nullptr, 0, 0);
|
||||
return;
|
||||
}
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(0, 0, _viewPort.w, _viewPort.h, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get());
|
||||
PixelBufferDescriptor pbd;
|
||||
if (!texture) { // screen capture
|
||||
|
||||
std::shared_ptr<GLubyte> flippedBuffer(new GLubyte[bufferSize], [](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); });
|
||||
memset(flippedBuffer.get(), 0, bufferSize);
|
||||
if (!flippedBuffer)
|
||||
{
|
||||
callback(nullptr, 0, 0);
|
||||
return;
|
||||
int bufferSize = _viewPort.w * _viewPort.h * 4;
|
||||
std::unique_ptr<GLubyte[]> buffer(new GLubyte[bufferSize]);
|
||||
memset(buffer.get(), 0, bufferSize);
|
||||
if (!buffer)
|
||||
{
|
||||
callback(pbd);
|
||||
return;
|
||||
}
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(0, 0, _viewPort.w, _viewPort.h, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get());
|
||||
|
||||
GLubyte* flippedBuffer = (GLubyte*)malloc(bufferSize);
|
||||
memset(flippedBuffer, 0, bufferSize);
|
||||
if (!flippedBuffer)
|
||||
{
|
||||
callback(pbd);
|
||||
return;
|
||||
}
|
||||
for (int row = 0; row < _viewPort.h; ++row)
|
||||
{
|
||||
memcpy(flippedBuffer + (_viewPort.h - row - 1) * _viewPort.w * 4, buffer.get() + row * _viewPort.w * 4, _viewPort.w * 4);
|
||||
}
|
||||
|
||||
pbd._width = _viewPort.w;
|
||||
pbd._height = _viewPort.h;
|
||||
pbd._data.fastSet(flippedBuffer, bufferSize);
|
||||
}
|
||||
for (int row = 0; row < _viewPort.h; ++row)
|
||||
{
|
||||
memcpy(flippedBuffer.get() + (_viewPort.h - row - 1) * _viewPort.w * 4, buffer.get() + row * _viewPort.w * 4, _viewPort.w * 4);
|
||||
else {
|
||||
UtilsGL::readPixels(texture, 0, 0, texture->getWidth(), texture->getHeight(), true, pbd);
|
||||
}
|
||||
|
||||
callback(flippedBuffer.get(), _viewPort.w, _viewPort.h);
|
||||
callback(pbd);
|
||||
}
|
||||
|
||||
CC_BACKEND_END
|
||||
|
|
|
@ -167,7 +167,7 @@ public:
|
|||
* Get a screen snapshot
|
||||
* @param callback A callback to deal with screen snapshot image.
|
||||
*/
|
||||
virtual void captureScreen(std::function<void(const unsigned char*, int, int)> callback) override ;
|
||||
virtual void capture(TextureBackend* texture, std::function<void(const PixelBufferDescriptor&)> callback) override;
|
||||
|
||||
private:
|
||||
struct Viewport
|
||||
|
|
|
@ -165,7 +165,7 @@ public:
|
|||
* Get texture object.
|
||||
* @return Texture object.
|
||||
*/
|
||||
inline GLuint getHandler(int index = 0) const { return _textureInfo.textures[index]; }
|
||||
uintptr_t getHandler(int index = 0) const override { return _textureInfo.textures[index]; }
|
||||
|
||||
/**
|
||||
* Set texture to pipeline
|
||||
|
@ -175,8 +175,6 @@ public:
|
|||
|
||||
int getCount() const override { return _textureInfo.maxIdx + 1; }
|
||||
|
||||
uintptr_t getGPUHandler(int index) const override { return _textureInfo.getName(index); }
|
||||
|
||||
private:
|
||||
void initWithZeros();
|
||||
|
||||
|
@ -222,7 +220,7 @@ public:
|
|||
* Get texture object.
|
||||
* @return Texture object.
|
||||
*/
|
||||
inline GLuint getHandler(int index = 0) const { return _textureInfo.textures[index]; }
|
||||
uintptr_t getHandler(int index = 0) const override { return _textureInfo.textures[index]; }
|
||||
|
||||
/**
|
||||
* Set texture to pipeline
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "UtilsGL.h"
|
||||
#include "ProgramGL.h"
|
||||
#include "TextureGL.h"
|
||||
#include "renderer/backend/Types.h"
|
||||
|
||||
#if !defined(GL_COMPRESSED_RGB8_ETC2)
|
||||
|
@ -591,4 +592,46 @@ GLenum UtilsGL::toGLCullMode(CullMode mode)
|
|||
return GL_FRONT;
|
||||
}
|
||||
|
||||
void UtilsGL::readPixels(TextureBackend* texture, std::size_t x, std::size_t y, std::size_t width, std::size_t height, bool flipImage, PixelBufferDescriptor& outbuffer)
|
||||
{
|
||||
GLint defaultFBO = 0;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);
|
||||
GLuint frameBuffer = 0;
|
||||
glGenFramebuffers(1, &frameBuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
texture->getTextureType() == TextureType::TEXTURE_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP,
|
||||
static_cast<GLuint>(texture->getHandler()),
|
||||
0);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
|
||||
auto bytePerRow = width * texture->_bitsPerElement / 8;
|
||||
uint8_t* image = (uint8_t*)malloc(bytePerRow * height);
|
||||
glReadPixels(x,y,width, height,GL_RGBA,GL_UNSIGNED_BYTE, image);
|
||||
|
||||
outbuffer._width = width;
|
||||
outbuffer._height = height;
|
||||
|
||||
if(flipImage)
|
||||
{
|
||||
uint8_t* flippedImage = (uint8_t*)malloc(bytePerRow * height);
|
||||
for (int i = 0; i < height; ++i)
|
||||
{
|
||||
memcpy(&flippedImage[i * bytePerRow],
|
||||
&image[(height - i - 1) * bytePerRow],
|
||||
bytePerRow);
|
||||
}
|
||||
outbuffer._data.fastSet(flippedImage, bytePerRow * height);
|
||||
CC_SAFE_FREE(image);
|
||||
}
|
||||
else
|
||||
{
|
||||
outbuffer._data.fastSet(image, bytePerRow * height);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
|
||||
glDeleteFramebuffers(1, &frameBuffer);
|
||||
}
|
||||
|
||||
CC_BACKEND_END
|
|
@ -162,7 +162,7 @@ struct UtilsGL
|
|||
* @param outbuffer, the output buffer for fill texels data
|
||||
* @remark: !!!this function only can call after endFrame, then it's could be works well.
|
||||
*/
|
||||
static void readPixels(TextureBackend* texture, std::size_t origX, std::size_t origY, std::size_t rectWidth, std::size_t rectHeight, PixelBufferDescriptor& outbuffer);
|
||||
static void readPixels(TextureBackend* texture, std::size_t origX, std::size_t origY, std::size_t rectWidth, std::size_t rectHeight, bool flipImage, PixelBufferDescriptor& outbuffer);
|
||||
};
|
||||
//end of _opengl group
|
||||
/// @}
|
||||
|
|
Loading…
Reference in New Issue