Feature/draw in rect (#19664)

* Texture2D draw in point and draw in rectangle tests work

* optimize code

* fix compile error

* make initProgam() private
This commit is contained in:
coulsonwang 2019-05-17 09:14:14 +08:00 committed by minggo
parent 65fda3df81
commit 9c0033e1e7
4 changed files with 100 additions and 84 deletions

View File

@ -45,7 +45,10 @@ THE SOFTWARE.
#include "base/CCNinePatchImageParser.h"
#include "renderer/backend/Device.h"
#include "renderer/backend/StringUtils.h"
#include "renderer/backend/ProgramState.h"
#include "renderer/ccShaders.h"
#include "renderer/CCTextureUtils.h"
#include "renderer/CCRenderer.h"
#if CC_ENABLE_CACHE_TEXTURE_DATA
#include "renderer/CCTextureCache.h"
@ -223,6 +226,7 @@ Texture2D::~Texture2D()
CC_SAFE_DELETE(_ninePatchInfo);
CC_SAFE_RELEASE(_texture);
CC_SAFE_RELEASE(_programState);
}
Texture2D::PixelFormat Texture2D::getPixelFormat() const
@ -637,66 +641,6 @@ bool Texture2D::initWithBackendTexture(backend::Texture *texture)
return true;
}
//// implementation Texture2D (Drawing)
//
//void Texture2D::drawAtPoint(const Vec2& point)
//{
// GLfloat coordinates[] = {
// 0.0f, _maxT,
// _maxS,_maxT,
// 0.0f, 0.0f,
// _maxS,0.0f };
//
// GLfloat width = (GLfloat)_pixelsWide * _maxS,
// height = (GLfloat)_pixelsHigh * _maxT;
//
// GLfloat vertices[] = {
// point.x, point.y,
// width + point.x, point.y,
// point.x, height + point.y,
// width + point.x, height + point.y };
//
// glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
// glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORD);
// _shaderProgram->use();
// _shaderProgram->setUniformsForBuiltins();
//
// glActiveTexture(GL_TEXTURE0);
// glBindTexture(GL_TEXTURE_2D, _name);
//
// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, 0, coordinates);
//
// glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
//}
//
//void Texture2D::drawInRect(const Rect& rect)
//{
// GLfloat coordinates[] = {
// 0.0f, _maxT,
// _maxS,_maxT,
// 0.0f, 0.0f,
// _maxS,0.0f };
//
// GLfloat vertices[] = { rect.origin.x, rect.origin.y, /*0.0f,*/
// rect.origin.x + rect.size.width, rect.origin.y, /*0.0f,*/
// rect.origin.x, rect.origin.y + rect.size.height, /*0.0f,*/
// rect.origin.x + rect.size.width, rect.origin.y + rect.size.height, /*0.0f*/ };
//
// glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
// glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_TEX_COORD);
// _shaderProgram->use();
// _shaderProgram->setUniformsForBuiltins();
//
// glActiveTexture(GL_TEXTURE0);
// glBindTexture(GL_TEXTURE_2D, _name);
//
// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, 0, coordinates);
// glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
//}
bool Texture2D::hasMipmaps() const
{
return _hasMipmaps;
@ -927,6 +871,84 @@ void Texture2D::generateMipmap()
_hasMipmaps = true;
}
void Texture2D::initProgram()
{
if(_programState != nullptr)
return;
auto& pipelineDescriptor = _customCommand.getPipelineDescriptor();
//create program state
_programState = new (std::nothrow) cocos2d::backend::ProgramState(
positionTexture_vert, positionTexture_frag);
_mvpMatrixLocation = _programState->getUniformLocation("u_MVPMatrix");
_textureLocation = _programState->getUniformLocation("u_texture");
pipelineDescriptor.programState = _programState;
//setup vertex layout
auto& vertexLayout = pipelineDescriptor.vertexLayout;
auto& attributes = _programState->getProgram()->getActiveAttributes();
auto iter = attributes.find("a_position");
if(iter != attributes.end())
vertexLayout.setAttribute("a_position", iter->second.location, backend::VertexFormat::FLOAT2, 0, false);
iter = attributes.find("a_texCoord");
if(iter != attributes.end())
vertexLayout.setAttribute("a_texCoord", iter->second.location, backend::VertexFormat::FLOAT2, 2 * sizeof(float), false);
vertexLayout.setLayout(4 * sizeof(float), backend::VertexStepMode::VERTEX);
//create vertex buffer
_customCommand.setDrawType(CustomCommand::DrawType::ARRAY);
_customCommand.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE_STRIP);
_customCommand.createVertexBuffer(4 * sizeof(float), 4, CustomCommand::BufferUsage::DYNAMIC);
//setup blend state
BlendFunc blendFunc;
if(hasPremultipliedAlpha())
{
blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
}
else
{
blendFunc = BlendFunc::ALPHA_NON_PREMULTIPLIED;
}
auto& blendDescriptor = pipelineDescriptor.blendDescriptor;
blendDescriptor.blendEnabled = true;
blendDescriptor.sourceRGBBlendFactor = blendDescriptor.sourceAlphaBlendFactor = blendFunc.src;
blendDescriptor.destinationRGBBlendFactor = blendDescriptor.destinationAlphaBlendFactor = blendFunc.dst;
_programState->setTexture(_textureLocation, 0, _texture);
}
void Texture2D::drawAtPoint(const Vec2 &point, float globalZOrder)
{
float width = (float)_pixelsWide * _maxS;
float height = (float)_pixelsHigh * _maxT;
Rect rect = { point.x, point.y, width, height };
drawInRect(rect, globalZOrder);
}
void Texture2D::drawInRect(const Rect& rect, float globalZOrder)
{
initProgram();
_customCommand.init(globalZOrder);
auto director = Director::getInstance();
const auto& modelView = director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
const auto& projection = director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
Mat4 matrixMVP = projection * modelView;
float vertexData[] = {
rect.origin.x, rect.origin.y, 0.0f, _maxT,
rect.size.width + rect.origin.x, rect.origin.y, _maxS, _maxT,
rect.origin.x, rect.size.height + rect.origin.y, 0.0f, 0.0f,
rect.size.width + rect.origin.x, rect.size.height + rect.origin.y, _maxS, 0.0f };
_programState->setUniform(_mvpMatrixLocation, matrixMVP.m, sizeof(matrixMVP.m));
_customCommand.updateVertexBuffer(vertexData, sizeof(vertexData));
Director::getInstance()->getRenderer()->addCommand(&_customCommand);
}
NS_CC_END

View File

@ -34,6 +34,7 @@ THE SOFTWARE.
#include "base/CCRef.h"
#include "math/CCGeometry.h"
#include "base/ccTypes.h"
#include "renderer/CCCustomCommand.h"
NS_CC_BEGIN
@ -50,6 +51,7 @@ namespace ui
namespace backend {
class Texture2D;
class Texture;
class ProgramState;
}
/**
@ -245,9 +247,9 @@ public:
These functions require GL_TEXTURE_2D and both GL_VERTEX_ARRAY and GL_TEXTURE_COORD_ARRAY client states to be enabled.
*/
/** Draws a texture at a given point. */
// void drawAtPoint(const Vec2& point);
void drawAtPoint(const Vec2& point, float globalZOrder);
/** Draws a texture inside a rect.*/
// void drawInRect(const Rect& rect);
void drawInRect(const Rect& rect, float globalZOrder);
/**
Extensions to make it easy to create a Texture2D object from an image file.
@ -380,6 +382,7 @@ public:
Texture2D* getAlphaTexture() const;
bool getAlphaTextureName() const;
public:
/** Get pixel info map, the key-value pairs is PixelFormat and PixelFormatInfo.*/
static const PixelFormatInfoMap& getPixelFormatInfoMap();
@ -427,10 +430,9 @@ private:
* @param capInsets The parsed capInset from a .9 patch image.
*/
void addSpriteFrameCapInset(SpriteFrame* spritframe, const Rect& capInsets);
void initProgram();
protected:
/** pixel format of the texture */
Texture2D::PixelFormat _pixelFormat;
@ -472,6 +474,10 @@ protected:
std::string _filePath;
Texture2D* _alphaTexture;
backend::ProgramState* _programState = nullptr;
backend::UniformLocation _mvpMatrixLocation;
backend::UniformLocation _textureLocation;
CustomCommand _customCommand;
};

View File

@ -1769,7 +1769,7 @@ void TextureDrawAtPoint::onEnter()
_tex1 = Director::getInstance()->getTextureCache()->addImage("Images/grossinis_sister1.png");
_Tex2F = Director::getInstance()->getTextureCache()->addImage("Images/grossinis_sister2.png");
_tex1->retain();
_Tex2F->retain();
}
@ -1794,11 +1794,7 @@ void TextureDrawAtPoint::draw(Renderer *renderer, const Mat4 &transform, uint32_
{
TextureDemo::draw(renderer, transform, flags);
_renderCmd.init(_globalZOrder, transform, flags);
//TODO: impl new CustomRenderer
//_renderCmd.func = CC_CALLBACK_0(TextureDrawAtPoint::onDraw, this, transform, flags);
//renderer->addCommand(&_renderCmd);
onDraw(transform, flags);
}
void TextureDrawAtPoint::onDraw(const Mat4 &transform, uint32_t flags)
@ -1810,9 +1806,8 @@ void TextureDrawAtPoint::onDraw(const Mat4 &transform, uint32_t flags)
auto s = Director::getInstance()->getWinSize();
//TODO: minggo
// _tex1->drawAtPoint(Vec2(s.width/2-50, s.height/2 - 50));
// _Tex2F->drawAtPoint(Vec2(s.width/2+50, s.height/2 - 50));
_tex1->drawAtPoint(Vec2(s.width/2-50, s.height/2 - 50), _globalZOrder);
_Tex2F->drawAtPoint(Vec2(s.width/2+50, s.height/2 - 50), _globalZOrder);
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}
@ -1838,11 +1833,7 @@ TextureDrawInRect::~TextureDrawInRect()
void TextureDrawInRect::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
TextureDemo::draw(renderer, transform, flags);
_renderCmd.init(_globalZOrder, transform, flags);
_renderCmd.func = CC_CALLBACK_0(TextureDrawInRect::onDraw, this, transform, flags);
//TODO: impl new CustomRenderer
//renderer->addCommand(&_renderCmd);
onDraw(transform, flags);
}
void TextureDrawInRect::onDraw(const Mat4 &transform, uint32_t flags)
@ -1857,9 +1848,8 @@ void TextureDrawInRect::onDraw(const Mat4 &transform, uint32_t flags)
auto rect1 = Rect( s.width/2 - 80, 20, _tex1->getContentSize().width * 0.5f, _tex1->getContentSize().height *2 );
auto rect2 = Rect( s.width/2 + 80, s.height/2, _tex1->getContentSize().width * 2, _tex1->getContentSize().height * 0.5f );
//TODO: minggo
// _tex1->drawInRect(rect1);
// _Tex2F->drawInRect(rect2);
_tex1->drawInRect(rect1, _globalZOrder);
_Tex2F->drawInRect(rect2, _globalZOrder);
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}

View File

@ -475,7 +475,6 @@ public:
protected:
void onDraw(const cocos2d::Mat4& transform, uint32_t flags);
cocos2d::CustomCommand _renderCmd;
cocos2d::Texture2D* _tex1, *_Tex2F;
};
@ -491,7 +490,6 @@ public:
protected:
void onDraw(const cocos2d::Mat4& transform, uint32_t flags);
cocos2d::CustomCommand _renderCmd;
cocos2d::Texture2D* _tex1, *_Tex2F;
};