ObjectDynamicPtr dynamic;
TextureRenderPtr texture_render;
TexturePtr texture;
void fun1() // 放到init中
{
int width = 128;
int height = 128;
texture_render = TextureRender::create();
texture_render->create2D(width, height);
texture = Texture::create();
//texture->create2D(width, height, Texture::FORMAT_RGBA32F,Texture::USAGE_READWRITE | Texture::USAGE_RENDER);
texture->create2D(width, height, Texture::FORMAT_RGBA32F, Texture::USAGE_READWRITE | Texture::USAGE_RENDER);
MaterialPtr mat = Materials::get()->loadMaterial("MediaHelperShader/material/MediaHelperShader.basemat");
String name1 = mat->getName();
if (!mat.get())
{
int tt = 0;
return ;
}
dynamic = ObjectDynamic::create(ObjectDynamic::DYNAMIC_VERTEX | ObjectDynamic::DYNAMIC_INDICES);
int ret = dynamic->setMaterial("11", "*");
dynamic->setSurfaceProperty("surface_base", "*");
dynamic->setSurfaceMode(ObjectDynamic::MODE_TRIANGLES, 0);
dynamic->setInstancing(0);
//dynamic->setEnabled(0);
const ObjectDynamic::Attribute attributes[] = {
{ 0, ObjectDynamic::TYPE_FLOAT, 4 },
{ 16, ObjectDynamic::TYPE_FLOAT, 2 }
};
dynamic->setVertexFormat(attributes, 2);
int num = dynamic->getNumIndices();
dynamic->addVertexFloat(0, vec4(-1, 1, 1, 1).get(), 4);
dynamic->setVertexFloat(1, vec2(1,0).get(), 2);
dynamic->addVertexFloat(0, vec4(1, 1, 1, 1).get(), 4);
dynamic->setVertexFloat(1, vec2(1, 1).get(), 2);
dynamic->addVertexFloat(0, vec4(1, -1, 1, 1).get(), 4);
dynamic->setVertexFloat(1, vec2(0, 1).get(), 2);
dynamic->addVertexFloat(0, vec4(-1, -1, 1, 1).get(), 4);
dynamic->setVertexFloat(1, vec2(0, 0).get(), 2);
num = dynamic->getNumIndices();
dynamic->addIndex(0);
dynamic->addIndex(2);
dynamic->addIndex(1);
dynamic->addIndex(0);
dynamic->addIndex(3);
dynamic->addIndex(2);
//dynamic->setNumVertex(100);
//for (int i = 0; i < 100; i++)
//{
// int x = i / 10;
// int y = i % 10;
// dynamic->setVertexFloat(i,0, vec4((x-4.5f)/4.5f, (y-4.5f)/4.5f, 1, 1).get(), 4);
// dynamic->setVertexFloat(i,1, vec2(x/10.0f, y/10.0f).get(), 2);
//
// if (x> 0 && y > 0) {
// dynamic->addIndex(x * 10 + y);
// dynamic->addIndex((x - 1) * 10 + y - 1);
// dynamic->addIndex((x) * 10 + y - 1);
//
// dynamic->addIndex((x - 1) * 10 + y);
// dynamic->addIndex((x - 1) * 10 + y - 1);
// dynamic->addIndex(x * 10 + y);
// }
//}
num = dynamic->getNumVertex();
num = dynamic->getNumIndices();
dynamic->flushIndices();
dynamic->flushVertex();
//dynamic->setBoundBox();
return;
}
void save() //放到update中
{
if (App::get()->clearKeyState(' '))
{
dynamic->setEnabled(1);
texture_render->setColorTexture(0, texture);
texture_render->enable();
RenderState::get()->clearBuffer(RenderState::BUFFER_COLOR, vec4::ZERO);
//node->render(Render::PASS_OBJECT_POST, 0);
dynamic->render(Render::PASS_AMBIENT, 0);
texture_render->disable();
texture_render->unbindColorTexture();
dynamic->setEnabled(0);
ImagePtr img = Image::create();
texture->getImage(img);
img->save("E:/temp1/out.png");
}
}
注意上面兩種方式添加頂點。需要注意add和set函數的使用。
//mediahelpershader.basemat
<?xml version="1.0" encoding="utf-8"?>
<base_material name="MediaHelperShader" editable="1" version="2.7.2.1">
<blend src="one" dest="one"/>
<options depth_mask="0" cast_shadow="0" cast_world_shadow="0" transparent="2"/>
<shader pass="ambient" node="object_dynamic" vertex="MediaHelperShader/shader/vertex.shader" fragment="MediaHelperShader/shader/fragment.shader"/>
<texture name="albedo" shader="all" unit="0">E:/workSpace/unigine/unigine_projects/unigine_project_testttttttt/data/pics/chessPic2.png</texture>
</base_material>
//fragment.shader
#include <core/shaders/common/common.h>
#include <core/shaders/common/fragment.h>
INIT_TEXTURE(0,TEX)
STRUCT(FRAGMENT_IN)
INIT_POSITION
INIT_IN(float2,0)
END
MAIN_BEGIN(FRAGMENT_OUT,FRAGMENT_IN)
//OUT_COLOR = TEXTURE(TEX,IN_DATA(0));
//OUT_COLOR.a =1.0f;
OUT_COLOR = float4(IN_DATA(0),1.0f,1.0f);
//OUT_COLOR = float4(1.0f,1.0f,0.0f,1.0f);
MAIN_END
//end
//vertext.shader
#include <core/shaders/common/common.h>
STRUCT(VERTEX_IN)
INIT_ATTRIBUTE(float4,0,POSITION) // Vertex position
INIT_ATTRIBUTE(float2,1,TEXCOORD0) // Vertex texcoord (uv)
END
STRUCT(VERTEX_OUT)
INIT_POSITION
INIT_OUT(float2,0)
END
MAIN_BEGIN(VERTEX_OUT,VERTEX_IN)
//float4 row_0 = s_transform[0];
//float4 row_1 = s_transform[1];
//float4 row_2 = s_transform[2];
//float4 in_vertex = float4(IN_ATTRIBUTE(0).xyz,1.0f);
//float4 position = mul4(row_0,row_1,row_2,in_vertex);
//OUT_POSITION = getPosition(position);
OUT_POSITION = float4(IN_ATTRIBUTE(0).xyz,1.0f);
OUT_DATA(0) = IN_ATTRIBUTE(1);
MAIN_END
//end
注意shader文件 結尾需要的空格
在init中render可以渲染vs和ps,但是ps中的紋理無法獲取,需要在update或者render中才能獲取到紋理。對於其他類型的object,暫時沒有試驗成功。
another
#include "UVMapper.h"
#include "UnigineMaterials.h"
#include "UnigineApp.h"
#include "UnigineRenderState.h"
#include "UnigineFfp.h"
using namespace Unigine;
using namespace Math;
UVMapper::UVMapper()
{
init();
}
void UVMapper::init()
{
m_uvTexture = Texture::create();
m_uvTexture->create2D(m_uvWidth, m_uvHeight, Texture::FORMAT_RGBA8, Texture::USAGE_RENDER); //will get the rg32F out
m_uvTextureRender = TextureRender::create();
m_uvTextureRender->create2D(m_uvWidth, m_uvHeight);
//create shader without material
if (App::get()->isD3D11Initialized()) {
m_vertexShaderText =
"struct VERTEX_IN {\n"
" float4 position : POSITION;\n" //without considered camera transform and projection ,so it's only for 2D texture Orthographic projection,and the in position should be ([-1,1],[-1,1],1);
" float4 texcoord : TEXCOORD0;\n"//texturecoord should be ([0,1],[0,1])
" float4 color : COLOR0;\n"//useless ,just for useing the ffp vetex,or will get failed
"};\n"
"struct VERTEX_OUT {\n"
" float4 position : SV_POSITION;\n"
" float2 texcoord : TEXCOORD0;\n"
"};\n"
"VERTEX_OUT main(VERTEX_IN IN) {\n"
" VERTEX_OUT OUT;\n"
" OUT.position = IN.position;\n"
" OUT.texcoord = IN.texcoord.xy;\n"
" return OUT;\n"
"}\n";
m_fragmentShaderText =
"##pragma warning(disable : 3571)\n"
"SamplerState s_sampler_0 : register(s0);\n"
"Texture2D s_texture_0 : register(t0);\n"
"struct FRAGMEMENT_IN {\n"
" float4 position : SV_POSITION;\n"
" float2 texcoord : TEXCOORD0;\n"
"};\n"
"float4 main(FRAGMEMENT_IN IN) : SV_TARGET {\n"
" return float4(IN.texcoord,0.0f,1.0f);\n" //must set alpha not 0 in hlsl ,or the other value will be set to 0,it's not occur in glsl!!!!!
"}\n";
}
else
{
m_vertexShaderText =
"##version 150\n"
"in vec4 s_attribute_0;\n"
"in vec4 s_attribute_1;\n"
"in vec4 s_attribute_2;\n"
"out vec2 s_texcoord;\n"
"void main() {\n"
" gl_Position = s_attribute_0;\n"
" s_texcoord = s_attribute_1.xy;\n"
"}\n";
m_fragmentShaderText =
"##version 150\n"
"uniform sampler2D s_texture_0;\n"
"in vec2 s_texcoord;\n"
"out vec4 s_frag_color;\n"
"void main() {\n"
" s_frag_color = vec4(s_texcoord,0.0f,1.0f);\n"
"}\n";
}
m_shader = Shader::create(m_vertexShaderText, m_fragmentShaderText, NULL);
}
UVMapper::~UVMapper()
{
}
void UVMapper::renderUV(Unigine::Vector<Unigine::Ffp::Vertex> &vertexArray, Unigine::Vector<unsigned short> &indicesArray)
{
Ffp* ffp = Ffp::get();
RenderState *render_state = RenderState::get();
//the code below may be neccessory to add lock in multithread
render_state->saveState();//save render state
render_state->clearStates();
int ffpMode = ffp->getMode();//when call in callbacks , render be invalid
//save ffp status ,as maybe others will use
bool ffpEnabled = ffp->isEnabled();
if (ffp->isEnabled())
{
if (ffp->getMode() != Ffp::MODE_DEFAULT)
{
ffp->setMode(Ffp::MODE_DEFAULT);
}
}
else {
ffp->enable();//Ffp::MODE_SOLID //may be there was savestate in the enable
}
m_shader->bind(); //bind shader ,or will use the latest shader.!!!!!!!! must set after the ffp->enable ,as may be there was savestate in the enable
m_uvTextureRender->setColorTexture(0, m_uvTexture); //set the render target through texturerender
m_uvTextureRender->enable(); //start render;
render_state->clearBuffer(RenderState::BUFFER_COLOR, vec4(0.0f));
ffp->setOrtho(m_uvWidth, m_uvHeight); //set render range
ffp->beginTriangles();
for (int i = 0; i < vertexArray.size(); i++)
{
ffp->addVertex(vertexArray[i].xyz[0], vertexArray[i].xyz[1]);
ffp->setTexCoord(vertexArray[i].texcoord[0], vertexArray[i].texcoord[1]);
}
for (int i = 0; i < indicesArray.size(); i++)
{
ffp->addIndex(indicesArray[i]);
}
//ffp->addVertex(vertexArray.get(), vertexArray.size()); //set vertexs
//ffp->addIndices(indicesArray.get(), indicesArray.size()); //set arrays
ffp->endTriangles(); //render will finished here
m_uvTextureRender->disable(); //end render
m_uvTextureRender->unbindColorTexture(0); //unbind the texture
m_shader->unbind(); //unbind shader
if (ffpEnabled)
{
ffp->setMode(ffpMode);
}
else
{
ffp->disable();
}
render_state->clearStates();
render_state->restoreState(); //set render state back;
}
void UVMapper::uvTest()
{
ImagePtr img = Image::create();
m_uvTexture->getImage(img);
img->save("E:/temp1/out.png");
int twidth = img->getWidth();
int theight = img->getHeight();
vec2* ptr = (vec2 *)img->getPixels();
for (int i = 0; i < img->getWidth(); i++)
{
Log::message("(%f,%f)", ptr[i].x, ptr[i].y);
}
}