Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
So is was wondering is this is recreatable?
While i was debugging a java opengl project i found a shader :
#version 420 core
uniform sampler2D texture1;
uniform sampler2D texture2;
in vec2 uv;
out vec4 fragColor;
void main(){
//fragColor = texture(texture1, uv);
fragColor = texture(texture2, uv);
}
looks simple right but now when I uncommand the //fragColor = texture(texture1, uv) and keep the rest I get the texture1 rendered to the screen. WHY ? my brains says that that's not right, shouldn't it just render texture2 because I override fragColor? IDK can somebody explain this?
UPDATE 1:
I believe its a problem with glsl compilation.
Is it possible to bind a texture to sampler1 when there is not texture bound to sampler0
UPDATE 2:
creating the texture:
in my case its just a texture with 1 sample so TEXTURE_2D
and its format is .png so 4 channels
and there is no interpolation applied
texType = samples > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
int format;
if (channels == 3) {
format = GL_RGB;
} else if (channels == 4) {
format = GL_RGBA;
} else {
throw new AspectGraphicsException("textures can't be initialized with " + channels + " channels");
}
ID = glGenTextures();
glBindTexture(texType, ID);
glTexParameteri(texType,
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(texType,
GL_TEXTURE_MAG_FILTER, interpolation ? GL_LINEAR : GL_NEAREST);
glTexParameteri(texType, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(texType, GL_TEXTURE_WRAP_T, GL_REPEAT);
if (samples > 1) {
if (pixels == null) {
glTexImage2DMultisample(texType, samples, format,
width, height, true);
} else {
throw new AspectGraphicsException("textures with defined with pixels can't be multisampled");
}
} else {
if (pixels == null) {
glTexImage2D(texType, 0, format, width, height,
0, format, GL_UNSIGNED_BYTE, NULL);
} else {
glTexImage2D(texType, 0, format,
width, height, 0, format,
GL_UNSIGNED_BYTE, pixels);
}
}
glBindTexture(texType, 0);
binding the texture:
texType is just GL_TEXTURE_2D
and samplerName is "texture1" or "texture2" (see in the glsl shader)
and the sampler is just for "texture1":0 and for "texture2":1
glActiveTexture(GL_TEXTURE0 + sampler);
glBindTexture(texType, ID);
shader.uniform1i(samplerName, sampler);
It's most likely that you didn't assign a texture unit to your sampler uniforms, so they were both set to point to GL_TEXTURE0. You can specify it in the shader like so:
#version 420 core
layout(binding=0) uniform sampler2D texture1;
layout(binding=1) uniform sampler2D texture2;
// ...
Then you bind the textures with:
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, your_texture);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, other_texture);
glDrawArrays(...);
If done this way, you'll get the right result irrespectively of what uniforms are left out.
See Binding textures to samplers.
Related
I am struggling to render smooth lines using GL_LINES.
I have borrowed the MultisampleConfigChooser from the following link: MultisampleConfigChooser.java
It seemed to find the multisample configuration without any errors.
Here is the code I use to render the lines on the screen:
GLES20.glUseProgram(this.lineDrawProgram);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(
mPositionHandle, 2,
GLES20.GL_FLOAT, false,
6*4, linesData);
linesData.position(2);
GLES20.glEnableVertexAttribArray(mColorHandle);
GLES20.glVertexAttribPointer(
mColorHandle, 4,
GLES20.GL_FLOAT, false,
6*4, linesData);
linesData.position(0);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, matrix, 0);
GLES20.glDrawArrays(GLES20.GL_LINES, 0, this.numLines*2);
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mColorHandle);
Blending is enabled with GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA.
One more mention is that I am drawing the lines to a texture which is bound to an FBO as a color attachment. I have not added any extra code to enable multisampling for the FBO.
Here is the code I use to setup the FBO and texture:
int[] fbo = new int[1];
int[] tex = new int[1];
enGLES20.glGenTextures(1, tex, 0);
GLES20.glGenFramebuffers(1, fbo, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex[0]);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0,GLES20.GL_RGBA, this.width, this.height, 0,GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);
GES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, tex[0], 0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
The resulting lines still look like crap:
Please help me get these lines to look smooth.
BTW there are many different small lines in the screenshot, no curved lines or anything exotic.
I'm pretty new to OpenGL. I thought I understood FBOs, but I have trouble making them work.
My program draws to multisampled fbo basic graphical information (colorFbo).
From colorFbo I blit to postprocessFbo.
Then there's counterFbo with unsigned int values, where I simply fill silhouette of each object with object's id.
I'd like to postprocess the postprocessFbo and counterFbo, however, I don't see any effect of counterFbo... Where's the problem, please?
Here are parts my code:
Initialization:
colorFbo = new Framebuffer(true, false); //multisampled, rgba
counterFbo = new Framebuffer(false, true); //not MS, red
...seting polygonmode, viewport, depthtest, blending...
modelProgram = loadProgram("model");
counterProgram = loadProgram("counter");
...
postprocessProgram = loadProgram("postprocess");
...
postprocessFbo = new Framebuffer(false, false); //not MS, rgba
Render loop:
glBindFramebuffer(GL_FRAMEBUFFER, colorBuffer.fbo());
Main.clear(0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_MULTISAMPLE);
drawing objects using model program...
glBindFramebuffer(GL_FRAMEBUFFER, counterBuffer.fbo());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_MULTISAMPLE);
drawing objects using counter program...
blit colorFbo to postprocessFbo...
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glUseProgram(postprocessProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, postprocessFbo.fboColorTexture());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, counterFbo.fboColorTexture());
glBindVertexArray(screenQuadArray);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Counter fragment shader:
#version 330
out uint counter;
in vec3 vPosition;
uniform uint id;
void main() {
counter = id;
}
Postprocess fragment shader:
#version 330
uniform sampler2D colorTex;
uniform usampler2D counterTex;
out vec4 finalColor;
in vec2 texCoord;
void main() {
finalColor = texture(colorTex, vec2(tex));
uint id = texture(counterTex, vec2(tex)).s;
if (id > 0) {
finalColor = black;
}
}
Framebuffer constructor:
public Framebuffer(boolean multisampled, boolean redOnly) {
int internalFormat = redOnly ? GL_R32UI : GL_RGBA;
int format = redOnly ? GL_RED_INTEGER : GL_RGBA;
int dataType = redOnly ? GL_UNSIGNED_INT : GL_UNSIGNED_BYTE;
int interpolation = redOnly ? GL_NEAREST : GL_LINEAR;
int textureType = multisampled ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
// Prepare FBO textures
fboColorTexture = glGenTextures();
fboDepthStencilTexture = glGenTextures();
if (multisampled) {
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, fboColorTexture);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, SAMPLES, internalFormat, Main.width(), Main.height(), false);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, fboDepthStencilTexture);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, SAMPLES, GL_DEPTH24_STENCIL8, Main.width(), Main.height(), false);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
} else {
glBindTexture(GL_TEXTURE_2D, fboColorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, Main.width(), Main.height(), 0, format, dataType, (float[]) null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, interpolation);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, interpolation);
glBindTexture(GL_TEXTURE_2D, fboDepthStencilTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, Main.width(), Main.height(), 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, (float[]) null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
}
fbo = glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureType, fboColorTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, textureType, fboDepthStencilTexture, 0);
glDrawBuffers(GL_COLOR_ATTACHMENT0);
int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
System.err.println("Framebuffer not complete.");
System.exit(1);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
You seem to be missing assigning the texture unit to the texture name. So when I load textures I normally do this in the initialization ...
uColorTex = glGetUniformLocation(shaders.shaderProgram, "colorTex");
uCounterTex = glGetUniformLocation(shaders.shaderProgram, "counterTex");
... and when drawing ...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, postprocessFbo.fboColorTexture());
glUniform1i(uColourTex, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, counterFbo.fboColorTexture());
glUniform1i(uCounterTex, 1);
The issue was in counter program itself (in glVertexAttribPointer), which I didn't write about.
I needed only position in the counter program, so I wrote this:
glVertexAttribPointer(positionAttribLoc, 3, GL_FLOAT, false, FLOAT_VEC3_SIZE, 0);
But I forgot, that the data is always in the same position, so I can't "save space", because I'm only binding, the vertex data stays the same:
glVertexAttribPointer(positionAttribLoc, 3, GL_FLOAT, false, SIZEOF_MODEL_VERTEX, 0);
Thanks for the answers, and sorry I didn't show more code, I thought the issue could be anywhere and didn't want to overwhelm anyone reading with too much code.
I am trying to implement shadow-mapping in my scene, but all I get is zeros in my fragment shader when I call texture() (I've tested it with == 0.0). My question: Am I sending the depth texture to the shader correctly?
Here is my fragment shader code:
bool getShadow() {
vec4 lightProjPositionScaled = lightProjPosition/lightProjPosition.w;
vec2 texCoords = lightProjPositionScaled.xy*0.5 + 0.5; // bias
return lightProjPositionScaled.z + 0.0005 > texture(shadowMap, texCoords).x;
}
Here is my relevant java codeInit (edited due to BDL's comment)
gl.glEnable(GL2.GL_TEXTURE_2D);
// generate stuff
IntBuffer ib = IntBuffer.allocate(1);
gl.glGenFramebuffers(1, ib);
frameBuffer = ib.get(0);
ib = IntBuffer.allocate(1);
gl.glGenTextures(1, ib);
shadowMap = ib.get(0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBuffer);
gl.glBindTexture(GL2.GL_TEXTURE, shadowMap);
gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT, 1024, 1024, 0, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, null);
gl.glDrawBuffer(GL2.GL_NONE);
gl.glReadBuffer(GL2.GL_NONE);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
// prevents 'shadow acne'
gl.glPolygonOffset(2.5f, 0);
// prevents multiple shadows
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE);
// prevents (or expects!!!) pixel-y textures
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
// store one value in all four components of pixel
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_DEPTH_TEXTURE_MODE, GL2.GL_INTENSITY);
Display (1st pass, for shadows):
// render shadows
gl.glUseProgram(shadowProgram);
gl.glUniformMatrix4fv(lightMatrixLocShadow, 1, false, lightMatrix.getMatrix(), 0); // yep (haha change viewMatrix -> lightMatrix)
gl.glUniformMatrix4fv(projMatrixLocShadow, 1, false, projMatrix.getMatrix(), 0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, sha.frameBuffer);
gl.glViewport(0, 0, 1024, 1024);
gl.glClear(GL2.GL_DEPTH_BUFFER_BIT);
renderScene(gl, sunMatrix);
gl.glCopyTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT, 0, 0, 1024, 1024, 0);
gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
Display (2nd pass, for rendering the scene):
// render display (regular)
gl.glUseProgram(displayProgram);
gl.glDrawBuffer(GL2.GL_FRONT);
gl.glReadBuffer(GL2.GL_FRONT);
gl.glUniformMatrix4fv(viewMatrixLoc, 1, false, viewMatrix.getMatrix(), 0);
gl.glUniformMatrix4fv(projMatrixLocDisplay, 1, false, projMatrix.getMatrix(), 0);
gl.glUniformMatrix4fv(lightMatrixLocDisplay, 1, false, lightMatrix.getMatrix(), 0);
gl.glUniform4fv(sunPositionLoc, 1, sunWorldPosition, 0); // send sun's position to shader
gl.glUniform1f(sunBrightnessLoc, sunBrightness);
gl.glUniform1i(shadowMapLoc, 0);
gl.glViewport(0, 0, screenWidth, screenHeight);
// day-night cycle
float[] color = SkyManager.getSkyColor(time);
gl.glClearColor(color[0], color[1], color[2], 1);
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glActiveTexture(GL2.GL_TEXTURE0);
gl.glBindTexture(GL2.GL_TEXTURE_2D, sha.shadowMap);
renderScene(gl, sunMatrix);
Another strange outcome is that only fragments on the z=0 plane relative to the light matrix (the light's rotating, and the plane rotates with it) are lit. All other fragments, behind and in front of the light, are shadowed.
One issue was with the line gl.glBindTexture(GL2.GL_TEXTURE, shadowMap);
I was binding the texture to GL_TEXTURE instead of GL_TEXTURE_2D.
I am using template matching on openCV java to identify if a subimage exist in larger image. I want to get coordinates of match only if exact subimage is available in larger image. I am using this code but getting a lot of false positive. Attached is the subimage and larger image. Subimage is not present in larger image but i am getting match at (873,715) larger image subimage
public void run(String inFile, String templateFile, String outFile,
int match_method) {
System.out.println("Running Template Matching");
Mat img = Imgcodecs.imread(inFile);
Mat templ = Imgcodecs.imread(templateFile);
// / Create the result matrix
int result_cols = img.cols() - templ.cols() + 1;
int result_rows = img.rows() - templ.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
// / Do the Matching and Normalize
Imgproc.matchTemplate(img, templ, result, match_method);
// Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new
// Mat());
Imgproc.threshold(result, result, 0.1, 1.0, Imgproc.THRESH_TOZERO);
// / Localizing the best match with minMaxLoc
MinMaxLocResult mmr = Core.minMaxLoc(result);
Point matchLoc;
if (match_method == Imgproc.TM_SQDIFF
|| match_method == Imgproc.TM_SQDIFF_NORMED) {
matchLoc = mmr.minLoc;
} else {
matchLoc = mmr.maxLoc;
}
double threashhold = 1.0;
if (mmr.maxVal > threashhold) {
System.out.println(matchLoc.x+" "+matchLoc.y);
Imgproc.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(),
matchLoc.y + templ.rows()), new Scalar(0, 255, 0));
}
// Save the visualized detection.
Imgcodecs.imwrite(outFile, img);
}
Here is an answer of the same question: Determine if an image exists within a larger image, and if so, find it, using Python
You will have to convert the python code to Java
I am not familiar with OpenCV in Java but OpenCV C++.
I don't think following code is necessary.
Imgproc.threshold(result, result, 0.1, 1.0, Imgproc.THRESH_TOZERO);
The min/max values of 'Mat result' will be between -1 and 1 if you uses normalized option. Therefore, your following code will not work because your threshold is 1.0 if you use normalized option.
if (mmr.maxVal > threshold)
Also, if you use CV_TM_SQDIFF, above code should be
if (mmr.minVal < threshold)
with proper threshold.
How about drawing minMaxLoc before comparing minVal/maxVal with threshold? to see it gives correct result? because match at (873,715) is ridiculous.
I'm new to android SDK and programming using OGLES2.0. my problem is, most of the programs are not running on my PC.
I'm using Android virtual Device Nexus 4 with 512 Mb Ram, VM Heap 64, Internal Storage 512 and Android 4.3 with API 18 (No SD Card).
A sample code which I'm trying to run is
package com.example.mynewsample;
//
// Book: OpenGL(R) ES 2.0 Programming Guide
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
// ISBN-10: 0321502795
// ISBN-13: 9780321502797
// Publisher: Addison-Wesley Professional
// URLs: http://safari.informit.com/9780321563835
// http://www.opengles-book.com
//
// Hello_Triangle
//
// This is a simple example that draws a single triangle with
// a minimal vertex/fragment shader. The purpose of this
// example is to demonstrate the basic concepts of
// OpenGL ES 2.0 rendering.
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.util.Log;
public class myTriangleRenderer implements GLSurfaceView.Renderer
{
///
// Constructor
//
public myTriangleRenderer(Context context)
{
mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mVertices.put(mVerticesData).position(0);
}
///
// Create a shader object, load the shader source, and
// compile the shader.
//
private int LoadShader(int type, String shaderSrc)
{
int shader;
int[] compiled = new int[1];
// Create the shader object
shader = GLES20.glCreateShader(type);
if (shader == 0)
return 0;
// Load the shader source
GLES20.glShaderSource(shader, shaderSrc);
// Compile the shader
GLES20.glCompileShader(shader);
// Check the compile status
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0)
{
Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
return 0;
}
return shader;
}
///
// Initialize the shader and program object
//
public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
{
String vShaderStr =
"attribute vec4 vPosition; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = vPosition; \n"
+ "} \n";
String fShaderStr =
"precision mediump float; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n"
+ "} \n";
int vertexShader;
int fragmentShader;
int programObject;
int[] linked = new int[1];
// Load the vertex/fragment shaders
vertexShader = LoadShader(GLES20.GL_VERTEX_SHADER, vShaderStr);
fragmentShader = LoadShader(GLES20.GL_FRAGMENT_SHADER, fShaderStr);
// Create the program object
programObject = GLES20.glCreateProgram();
if (programObject == 0)
return;
GLES20.glAttachShader(programObject, vertexShader);
GLES20.glAttachShader(programObject, fragmentShader);
// Bind vPosition to attribute 0
GLES20.glBindAttribLocation(programObject, 0, "vPosition");
// Link the program
GLES20.glLinkProgram(programObject);
// Check the link status
GLES20.glGetProgramiv(programObject, GLES20.GL_LINK_STATUS, linked, 0);
if (linked[0] == 0)
{
Log.e(TAG, "Error linking program:");
Log.e(TAG, GLES20.glGetProgramInfoLog(programObject));
GLES20.glDeleteProgram(programObject);
return;
}
// Store the program object
mProgramObject = programObject;
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
// /
// Draw a triangle using the shader pair created in onSurfaceCreated()
//
public void onDrawFrame(GL10 glUnused)
{
// Set the viewport
GLES20.glViewport(0, 0, mWidth, mHeight);
// Clear the color buffer
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// Use the program object
GLES20.glUseProgram(mProgramObject);
// Load the vertex data
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, mVertices);
GLES20.glEnableVertexAttribArray(0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
}
// /
// Handle surface changes
//
public void onSurfaceChanged(GL10 glUnused, int width, int height)
{
mWidth = width;
mHeight = height;
}
// Member variables
private int mProgramObject;
private int mWidth;
private int mHeight;
private FloatBuffer mVertices;
private static String TAG = "HelloTriangleRenderer";
private final float[] mVerticesData =
{ 0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f };
}
I had tried different virtual devices, but each time it says Unfortunately stops running.
I am getting this with all OGLES2.0 programs, that won't use CANVAS. A Canvas Program is running accurately.
My experience thus far has always been that the Android emulator does not fully support OpenGL ES 2.0, only ES 1.x. By far the easiest approach is to test on a physical device.
However please checkout this question which suggests it can now be done:
Android OpenGL ES 2.0 emulator
OpenGL ES 2.0 emulation on AVDs actually works pretty well now since the Jelly Bean version. However, the critical factor is the underlying OpenGL driver you have installed on your host development system. It really must be a recent Nvidia or AMD driver. Also, installing Intel's HAXM makes it run much faster. See the third article here:
http://montgomery1.com/opengl/