我在这里有一个简单的问题。我使用纹理来渲染位图,一切都很好。但是我想在所述纹理上绘制一条线。我知道vert / tex坐标是如何工作的,但由于某些未知原因我无法实现这一点。在调用之后,我正在调用绘制我的线条,将位图绘制到纹理,但只有位图显示为静止。实现这一目标的最佳方法是什么?我正在使用texure2D在我的片段着色器中绘制位图,是否需要添加一些东西来绘制具有指定颜色的线条?任何帮助将不胜感激。
感谢。
与位图纹理相关的代码:
private final String vertexTextureShaderCode =
"attribute vec4 aPosition;"+ // Position of out Vertex
"attribute vec2 aTexPosition;"+ // Position of our texture contained in the vertex
"varying vec2 vTexPosition;"+ //
"void main(){"+
" gl_Position = aPosition;"+
" vTexPosition = aTexPosition;"+
"}";
private final String fragmentTextureShaderCode =
"precision mediump float;" +
"uniform sampler2D uTexture;" + // Our Background Image ( Our uploaded image)
"varying vec2 vTexPosition;" +
"void main() {" +
" gl_FragColor = texture2D(uTexture, vTexPosition);" +
"}";
public void draw(float[] m ,ImageEffectFactory effectFactory,int currentEffect){
// add program to OpenGl ES Environment;
this.imageEffectFactory = effectFactory;
boolean effectChanged = false;
if(currentEffect != mCurrentEffect){
mCurrentEffect = currentEffect;
effectChanged = true;
}
int whichTexture = 0;
if(currentEffect > 0 && currentEffect < 6){
whichTexture = 1;
if(effectChanged) {
imageEffectFactory.applyEffect(mTexturePointer, ImageEffectFactory.FILTER.values()[currentEffect], mTextureImageWidth, mTextureImageHeight);
effectChanged = false;
}
}
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLES20.glUseProgram(mProgram);
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glViewport(0,0,mViewWidth, mViewHeight);
// get handle to vertex shader vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
mTextureHandle = GLES20.glGetUniformLocation(mProgram, "uTexture");
mTexturePositionHandle = GLES20.glGetAttribLocation(mProgram, "aTexPosition");
GLES20.glVertexAttribPointer(mTexturePositionHandle, 2, GLES20.GL_FLOAT, false, 0, mTextureBuffer);
GLES20.glEnableVertexAttribArray(mTexturePositionHandle);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexturePointer[whichTexture]);
GLES20.glUniform1i(mTextureHandle,0);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, vertexBuffer);
// enable a handle to the triangle vertice
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Draw the square
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertexCount);
// Disbale the vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
正如我所提到的,这很好用。我试图加载的位图将显示并看起来很完美。但是在绘制之后我试图绘制线条。以下是该行的设置:
private static final String vsShader =
"uniform mat4 uMVPMatrix;"+
"attribute vec4 vPosition; " +
"void main() { " +
" gl_Position = uMVPMatrix * vPosition;" +
" }";
private static final String fsShader =
"precision mediump float;"
+ "uniform vec4 vColor;"
+ "void main() {"
+ "gl_FragColor = vColor;" +
"}";
private float[] pathCoords = {
-0.5f, 0.5f,0.0f,
-0.5f, -0.5f, 0.0f
};
private short[] pathDrawOrder = {0,1};
private float[] color = {1.0f, 0.0f, 0.0f, 1.0f}; // - red for testing
private final FloatBuffer mVertBuffer;
private final ShortBuffer mDrawListBuffer;
private int mCropProgram;
private int vPositionHandle;
private int vColorHandle;
private int uMVPMatrixHandle;
public CropFrameRect(Context context){
this.context = context;
// Allocat a byteBuffer for our Vertex Array;
ByteBuffer bb = ByteBuffer.allocateDirect(pathCoords.length * 4);
// ORder those Bytes correctly depending on the device (ie. BIG-ENDIAN vs. LITTLE-ENDIAN
bb.order(ByteOrder.nativeOrder());
// Lets now store those vertex points into a FloatBuffer please.
mVertBuffer = bb.asFloatBuffer();
mVertBuffer.put(pathCoords);
mVertBuffer.position(0);
ByteBuffer dlb = ByteBuffer.allocateDirect(pathDrawOrder.length*2);
dlb.order(ByteOrder.nativeOrder());
mDrawListBuffer = dlb.asShortBuffer();
mDrawListBuffer.put(pathDrawOrder);
mDrawListBuffer.position(0);
int vertexShader = ImageGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vsShader);
int fragmentShader = ImageGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fsShader);
// We've compiled our vertex and our texture shader programs. Let us create the program..
mCropProgram = GLES20.glCreateProgram();
// Attach the vertex shader string
GLES20.glAttachShader(mCropProgram, vertexShader);
// Attach the shader program string
GLES20.glAttachShader(mCropProgram, fragmentShader);
// Link the program code to the OpenGL Context
GLES20.glLinkProgram(mCropProgram);
Log.d(TAG, "Crop Program Linked: " + mCropProgram);
}
public void draw(float[] matrix){
GLES20.glUseProgram(mCropProgram);
vPositionHandle = GLES20.glGetAttribLocation(mCropProgram, "vPosition");
GLES20.glEnableVertexAttribArray(vPositionHandle);
GLES20.glVertexAttribPointer(vPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, mVertBuffer);
// set the color
vColorHandle = GLES20.glGetUniformLocation(mCropProgram, "vColor");
GLES20.glUniform4fv(vColorHandle, 1, color, 0);
// set the Matrix projection for the View;
uMVPMatrixHandle = GLES20.glGetUniformLocation(mCropProgram, "uMVPMatrix");
GLES20.glUniformMatrix4fv(uMVPMatrixHandle, 1, false, matrix, 0);
GLES20.glLineWidth(2.7f);
// Draw those elements
GLES20.glDrawElements(GLES20.GL_LINES, pathDrawOrder.length, GLES20.GL_UNSIGNED_SHORT, mDrawListBuffer);
GLES20.glDisableVertexAttribArray(vPositionHandle);
GLES20.glDisable(vColorHandle);
}
答案 0 :(得分:0)
首先,一些关于你正在做的事情的代码可能证明是有用的。如果纹理显示正确,我只能猜测绘制线条有问题。但是图纸失败的原因很多。
第二个问题标题是“如何在纹理上绘制线条”,而描述似乎是在询问如何在绘制的纹理上绘制线条。注意这两个是非常不同的,因为绘制纹理是很常见的。
因此,如果您已成功将纹理绘制到视图中但未能在其上绘制线条,那么我想最好开始调试该问题。您应该首先尝试绘制没有纹理的线条,看看它是否绘制。 如果没有:
(0,0), (1,1)
并将它们绘制成一条线。除了清除缓冲区之外,不应该绘制任何其他内容并且不应该调用openGL。在此工作之后,您可以从此开始向上构建并查看您的错误所在。如果它直接从删除调用中绘制以绘制纹理,那么我最好的猜测是你启用了深度测试,并且该行位于纹理后面。尝试禁用深度测试或尝试将线条靠近一点。
答案 1 :(得分:0)
您必须为此代码更改fragmentTextureShaderCode。
private final String fragmentTextureShaderCode =
"precision mediump float;" +
"vec2 u_line_prop" + //line slope and bias
"uniform vec2 u_resolution;" + //width, height GlSurfaceTexture
"uniform sampler2D uTexture;" + // Our Background Image ( Our uploaded image)
"varying vec2 vTexPosition;" +
// Plot a line on Y using a value between 0.0-1.0
"float plotLine(vec2 st, float pct){" +
" return smoothstep( pct-0.02, pct, st.y) -" +
" smoothstep( pct, pct+0.02, st.y);" +
"}" +
"void main() {" +
" vec2 st = gl_FragCoord.xy/u_resolution.xy;" +
" st.x *= u_resolution.x/u_resolution.y;" +
//line formula
" float y = st.x*u_line_prop.x+u_line_prop.y;" +
" float pct = plotLine(st,y);" +
" colorLine = texture2D(uTexture, vTexPosition);" +
" vec4 colorLine = vec4 (1.0,1.0, 0.0,1.0) ;" +
" gl_FragColor = mix(colorTexture, colorLine, pct);"
"}";
然后你必须更正你的java代码以传输另外两个向量:
您可以在线Shaders editor查看类似代码的工作原理