First of all, there are too few colleagues in OpenGL, especially ndk, in China.
There are many problems encountered in this process, and these problems need to be found on the book, on the Internet, on a variety of materials, and the book is called at the java layer, the lack of various file cases on the internet, only by studying at the java layer and finding the required knowledge points in various cases can google search foreign websites solve the problem.
Next body
------------------------------
To learn about ndk, we should all start with google's configuration case: GL2JNIActivity
This case is to add a green triangle to a color-changing background.
Because I started to learn texture textures, I planned to change triangles to textures.
First, you need to configure the texture
Modify the Renderer class in GL2JNIView. java
Private static class Renderer implements GLSurfaceView. renderer {public void onDrawFrame (GL10 gl) {GL2JNILib. step ();} public void onSurfaceChanged (GL10 gl, int width, int height) {GL2JNILib. init (width, height);} private Context mContext; int textureId; private int [] TextureString = new int [1]; public void onSurfaceCreated (GL10 gl, EGLConfig config) {mContext = GL2JNIActivity. getContext (); // B Itmap bitmap = getBitmap (mContext, R. drawable. bac); Bitmap bitmap = getBitmap (mContext, R. drawable. wall); if (bitmap! = Null) {Log. e (step, bing the texture succeed !); Gl. glEnable (gles1_gl _ TEXTURE_2D); gl. glGenTextures (1, TextureString, 0); textureId = TextureString [0]; Log. e (textureId, String. valueOf (textureId); gl. glBindTexture (gles0000gl _ TEXTURE_2D, textureId); gl. glTexParameterf (gles‑gl _ TEXTURE_2D, gles‑gl _ TEXTURE_MIN_FILTER, gles‑gl _ NEAREST); gl. glTexParameterf (gles‑gl _ TEXTURE_2D, gles‑gl _ TEXTURE_MAG_FILTER, gles‑gl _ LINEAR); gl. glTexParameterf (gles‑gl _ TEXTURE_2D, gles‑gl _ TEXTURE_WRAP_S, gles‑gl _ CLAMP_TO_EDGE); gl. glTexParameterf (gles1_gl _ TEXTURE_2D, gles1_gl _ TEXTURE_WRAP_T, gles1_gl _ CLAMP_TO_EDGE); GLUtils. texImage2D (gles1_gl _ TEXTURE_2D, 0, bitmap, 0); GL2JNILib. setTextures (TextureString); // GL2JNILib. setTextures (textureId); bitmap. recycle () ;}} private Bitmap getBitmap (Context context, int resId) {// getBitmap by decodeResources () // BitmapFactory. options options = new BitmapFactory. options (); // options. inScaled = false; // return BitmapFactory. decodeResource (context. getResources (), resId, options); // getBitmap by decodeStream () InputStream bitmapStream = null; bitmapStream = context. getResources (). openRawResource (R. drawable. bac); return BitmapFactory. decodeStream (bitmapStream); // both methods can be verified }}
Because this part has been problematic before, and the texture has been flashing and black, and many changes have been made. I am not sure which are the root causes of the problem, but I try to post it as much as possible, there are also many exchanges:
1. If the image format is a multiple of 2 x a multiple of 2, and some say that the image format is not more than 1024, it is a little less than 512. It is better to use 256x256 for testing.
2.
gl.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
To
gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
Before
3.
gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
The final parameter is
GLES20.GL_CLAMP_TO_EDGE
It seems to be related to mipmap.
4.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
This must be put to the end
5.
GL2JNILib.setTextures(TextureString);
The parameter passed to the C ++ layer must be an int array.
Followed by the c ++ Layer Code
First, modify the script
static const char gVertexShader[] = attribute vec4 vPosition;attribute vec2 vTexCoords;varying vec2 colorVarying; void main() { gl_Position = vPosition; colorVarying = vTexCoords; };static const char gFragmentShader[] = precision mediump float;varying vec2 colorVarying;uniform sampler2D sampler; void main() { //gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);gl_FragColor = texture2D(sampler,colorVarying); };
Added fixed point texture coordinates and passed to pixelShader variable
PixelShader added parameters passed by vertexShader.
Bool setupGraphics (int w, int h) Modification
GLuint gProgram;GLuint gvPositionHandle;GLuint gvTexCoorHandle;bool setupGraphics(int w, int h) { printGLString(Version, GL_VERSION); printGLString(Vendor, GL_VENDOR); printGLString(Renderer, GL_RENDERER); printGLString(Extensions, GL_EXTENSIONS); LOGI(setupGraphics(%d, %d), w, h); gProgram = createProgram(gVertexShader, gFragmentShader); if (!gProgram) { LOGE(Could not create program.); return false; } gvPositionHandle = glGetAttribLocation(gProgram, vPosition); checkGlError(glGetAttribLocation); LOGI(glGetAttribLocation(Position) = %d, gvPositionHandle); gvTexCoorHandle = glGetAttribLocation(gProgram, vTexCoords); checkGlError(glGetAttribLocation); LOGI(glGetAttribLocation(TexCoords) = %d, gvTexCoorHandle); glViewport(0, 0, w, h); checkGlError(glViewport); return true;}
Added
gvTexCoorHandle = glGetAttribLocation(gProgram, vTexCoords);
Obtains the reference id of the texture coordinate attribute.
Modify void renderFrame ()
const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f };const GLfloat gTexCoor[] = { 0.5f,0, 0,1,1,1 };void renderFrame() { static float grey; grey += 0.01f; if (grey > 1.0f) { grey = 0.0f; } glClearColor(grey, grey, grey, 1.0f); checkGlError(glClearColor); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); //glClear( GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); checkGlError(glClear); glUseProgram(gProgram); checkGlError(glUseProgram); glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices); checkGlError(glVertexAttribPointer); glVertexAttribPointer(gvTexCoorHandle, 2, GL_FLOAT, GL_FALSE, 0, gTexCoor); checkGlError(glVertexAttribPointer); glEnableVertexAttribArray(gvPositionHandle); checkGlError(glEnableVertexAttribArray); glEnableVertexAttribArray(gvTexCoorHandle); checkGlError(glEnableVertexAttribArray); glActiveTexture(GL_TEXTURE0); checkGlError(glActiveTexture); glBindTexture(GL_TEXTURE_2D,mTexture[0]); checkGlError(glBindTexture); glDrawArrays(GL_TRIANGLES, 0, 3); checkGlError(glDrawArrays);}
Data with texture coordinates is added, texture is bound, and a triangle with texture is drawn.
Add the texture id passed by the receiving Java Layer
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_setTextures(JNIEnv * env, jobject obj,jintArray texture){mTexture = (GLuint *)env->GetIntArrayElements(texture,0);//m_texture = (unsigned int)env->GetIntArrayElements(texture,0);//it doesnt work!!!!what the fuck dont try this anymore!!!// const char *v = (const char *) m_texture;// LOGI(GL %s = %s, m_texture:, v);// v = (const char *) mTexture;// LOGI(GL %s = %s, mTexture:, v);}
The main cause of this problem is the black texture behind it:
The GLuint * type is used to receive the IDS passed by Java. In this way
glBindTexture(GL_TEXTURE_2D,mTexture[0]);
It will not be wrong.
All blame me for poor c ++ basics...
In the end, I hope you can share more information, such as my new experience with OpenGL, especially on ndk.
Project download link:
Http://download.csdn.net/detail/chrisfxs/7547637