Использую ShapeRenderer из Libgdx чтобы нарисовать прямоугольник и с помощью шейдеров рисую волны.
В игре двигаю объекты для создания эффекта паралакса, с помощью транслейта матрицы проекции.
Транслейчу матрицу у ShapeRenderer - рисуемый прямоугольник двигается,
почему рисуемые волны через шейдеры в прямоугольнике не двигаются ?
в фрагментном шейдере учитывать матрицу проекции ?
Благодарен за любую помощь
package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector2;
public class MyGdxGame extends ApplicationAdapter implements
InputProcessor
{
private float mX;
private float mY;
private ShaderProgram mGradientShader;
private Matrix4 mProjection = new Matrix4();
private ShapeRenderer mShapeRender;
public MyGdxGame()
{
}
private float iGlobalTime = 0.0f;
private Vector2 mScreenResolution;
@Override
public void create ()
{
final float screenWidth = Gdx.graphics.getWidth();
final float screenHeight = Gdx.graphics.getHeight();
mScreenResolution = new Vector2( screenWidth, screenHeight );
mX = screenWidth / 2.0f;
mY = screenHeight / 2.0f;
String vertexShader = Gdx.files.local( "vertex.glsl" ).readString();
String fragmentShader = Gdx.files.local( "fragment.glsl" ).readString();
ShaderProgram.pedantic = false;
mGradientShader = new ShaderProgram( vertexShader, fragmentShader );
String s = "";
if( false == mGradientShader.isCompiled() )
{
s = mGradientShader.getLog();
Gdx.app.log( "Asteroid", s );
}
mProjection.setToOrtho2D( 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight() );
mShapeRender = new ShapeRenderer( 19, mGradientShader );
Gdx.input.setInputProcessor( this );
}
@Override
public void render ()
{
Gdx.gl.glClearColor( 1, 0, 0, 1 );
Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT );
Gdx.gl.glBlendFunc( GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA );
Gdx.gl.glEnable( GL20.GL_BLEND );
mProjection.translate( 1.0f, 0.0f, 0.0f );
final int width = 400;
final int height = 400;
mGradientShader.begin();
mGradientShader.setUniformf( "u_parentAlpha", 1.0f );
mGradientShader.setUniformf( "iGlobalTime", iGlobalTime );
mGradientShader.setUniformf( "iResolution", mScreenResolution );
mGradientShader.setUniformf( "u_size", width, height );
mGradientShader.setUniformMatrix("u_projTrans", mProjection );
mGradientShader.setUniformf("u_center", mX, mY );
mGradientShader.end();
mShapeRender.begin( ShapeType.Filled );
mShapeRender.rect( mX - width / 2.0f, mY - height / 2.0f, width - 100, height );
mShapeRender.end();
iGlobalTime += Gdx.graphics.getDeltaTime();
}
@Override
public boolean keyDown(int keycode) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean keyUp(int keycode) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean keyTyped(char character) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
mX = screenX;
mY = Gdx.graphics.getHeight() - screenY;
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
mX = screenX;
mY = Gdx.graphics.getHeight() - screenY;
return false;
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean scrolled(int amount) {
// TODO Auto-generated method stub
return false;
}
}
//###########################Vertex shader
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 v_color;
varying vec2 v_texCoords;
void main()
{
v_color = a_color;
v_color.a = v_color.a * (255.0/254.0);
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position ;
}
//###########################Fragment shader
#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
varying LOWP vec4 v_color;
varying vec2 v_texCoords;
uniform sampler2D u_texture;
uniform float u_outterRadius;
uniform vec2 u_center;
uniform float u_parentAlpha;
uniform float iGlobalTime;
uniform vec2 iResolution;
uniform vec2 u_size;
float speed = 0.03;
float invAr = iResolution.y / iResolution.x;
void main()
{
//determine origin
vec2 position = ( gl_FragCoord.xy - u_center ) / u_size.xy;
//determine the vector length of the center position
float len = length( abs( position ) );
float softness = 0.01;
float waves_count = 2.0;
float wave_spliter = 0.05;
vec2 center = u_center / iResolution;
vec2 uv = gl_FragCoord.xy / iResolution.xy;
// vec3 col = vec4( uv, 0.5 + 0.5 * sin( iGlobalTime ), 0.0 ).xyz;
// vec3 col = vec4( uv, 0.5, 0.0 ).xyz;
vec3 col = vec3( 0.5, 0.5, 0.5 );
vec3 texcol;
float x = ( center.x - uv.x );
float y = ( center.y - uv.y ) * invAr;
float r = ( - 1.0 ) * sqrt( x * x + y * y ); //uncoment this line to symmetric ripples
//float r = ( - 1.0 ) * ( x * x + y * y);
float z = 1.0 + 0.5 * sin( ( r - iGlobalTime * speed ) / 0.003 );
texcol.x = z;
texcol.y = z;
texcol.z = z;
gl_FragColor = vec4( col * texcol, z * ( 1.0 - 2.0 * len ) );
}
Ответ
Спасибо за помощь
Я нашел решение:
private Vector3 mMatrixGetTranslation = new Vector3();
в render ()
mProjection.getTranslation( mMatrixGetTranslation );
float tranX = ( Gdx.graphics.getWidth() + mMatrixGetTranslation.x * Gdx.graphics.getWidth() ) / 2.0f;
float tranY = ( Gdx.graphics.getHeight() + mMatrixGetTranslation.y * Gdx.graphics.getHeight() ) / 2.0f;
и наконец
mGradientShader.setUniformf("u_center", mX + tranX, mY + tranY );
Комментариев нет:
Отправить комментарий