Files
stk-code_catmod/src/graphics/stk_billboard.cpp
Benau 497f1e2785 Clean up billboard texture code
Todo: compress them in STKTexture class
2017-01-04 14:35:49 +08:00

123 lines
4.4 KiB
C++

// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef SERVER_ONLY
#include "graphics/stk_billboard.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/shared_gpu_objects.hpp"
#include "graphics/texture_shader.hpp"
#include <ISceneManager.h>
using namespace irr;
static GLuint billboardvao = 0;
class BillboardShader : public TextureShader<BillboardShader, 1, core::matrix4,
core::matrix4, core::vector3df,
core::dimension2df>
{
public:
BillboardShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "billboard.vert",
GL_FRAGMENT_SHADER, "billboard.frag");
assignUniforms("ModelViewMatrix", "ProjectionMatrix", "Position",
"Size");
assignSamplerNames(0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED);
} // BillboardShader
}; // BillboardShader
// ============================================================================
static void createBillboardVAO()
{
glGenVertexArrays(1, &billboardvao);
glBindVertexArray(billboardvao);
glBindBuffer(GL_ARRAY_BUFFER, SharedGPUObjects::getBillboardVBO());
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(3);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
(GLvoid*) (2 * sizeof(float)));
glBindVertexArray(0);
} // createBillboardVAO
// ----------------------------------------------------------------------------
STKBillboard::STKBillboard(irr::scene::ISceneNode* parent,
irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position,
const irr::core::dimension2d<irr::f32>& size,
irr::video::SColor colorTop,
irr::video::SColor colorBottom)
: IBillboardSceneNode(parent, mgr, id, position),
CBillboardSceneNode(parent, mgr, id, position, size,
colorTop, colorBottom)
{
if (!billboardvao)
createBillboardVAO();
} // STKBillboard
// ----------------------------------------------------------------------------
void STKBillboard::OnRegisterSceneNode()
{
if (IsVisible)
{
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
}
ISceneNode::OnRegisterSceneNode();
} // OnRegisterSceneNode
// ----------------------------------------------------------------------------
void STKBillboard::render()
{
if (irr_driver->getPhase() != TRANSPARENT_PASS)
return;
core::vector3df pos = getAbsolutePosition();
glBindVertexArray(billboardvao);
video::ITexture *tex = Material.getTexture(0);
if (!tex )
return;
::Material* material = material_manager->getMaterialFor(tex,
video::E_MATERIAL_TYPE::EMT_ONETEXTURE_BLEND);
if (material->getShaderType() == Material::SHADERTYPE_ADDITIVE)
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
BillboardShader::getInstance()->use();
BillboardShader::getInstance()->setTextureUnits(tex->getOpenGLTextureName());
BillboardShader::getInstance()->setUniforms(irr_driver->getViewMatrix(),
irr_driver->getProjMatrix(),
pos, Size);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
} // render
#endif // !SERVER_ONLY