日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenGL ES教程VI之纹理贴图(原文对照)

發(fā)布時間:2024/3/13 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenGL ES教程VI之纹理贴图(原文对照) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

注:又是一篇,是否有人能解釋得清楚,2是重復兩次,那么是否N就是重復N次呢?接近1.0的坐標值整數(shù)部分加上幾就是重復幾次嗎?這個好像之前驗證過不一定的。


轉自:http://melord.iteye.com/blog/1126135

OpenGL ES教程VI之紋理貼圖(原文對照)

  • 博客分類:?
  • J2ME,Android
Android OpenGL ES?

OpenGL ES Tutorial for Android – Part VI – Textures

December 30th, 2010 by?Per-Erik Bergman?—?Android,?Embedded,?Java

Last tutorial we worked a bit more on meshes and we have also talked about adding colors to our mesh. The most common way of adding colors to your mesh is to add a texture. There is a couple of different steps involved with adding a texture to the mesh I will try to go through them all and explain the basics about them.

上一教程我們生成了一些模型,而且我們已經(jīng)知道如何給模型著色。但最常用的著色方式還是添加紋理。給模型添加紋理有幾個不同的操作步驟。下面我將一一展開。

Loading bitmaps

First step would be to get a bitmap to generate a texture from. You can get hold of a bitmap in many different ways from downloading, generating or simply just load one from the resources. I'm going with the simplest one for this example witch is loading from the resources.

第一步,我們需要得到貼圖的圖片,這有許多方式。你可以下載,生成,或是簡單地從資源中加載,我使用了最后一種:從一個資源文件中加載。

Bitmap bitmap = BitmapFactory.decodeResource(contect.getResources(),

?????????????????????????????????????????????R.drawable.icon);

One other thing about textures is that some hardware requires that the height and width are in the power of 2 (1, 2, 4, 8, 16, 32, 64...). If you run a texture with a size of 30x30pixels on a hardware that don’t support it you will just get a white square (unless you change the default color).

需要注意的是,在某些硬件上,貼圖需要的圖片尺寸必須是2的n次方(1,2,4,8,16,32…)。如果你的圖片是30X30的話,而且硬件不支持的話,那么你只能看到一個白色的方框(除非,你更改了默認顏色)

Generating a texture

After we have loaded the bitmap we need to tell OpenGL to actually create the texture.

圖片加載之后,就可以告訴OpenGL?來產(chǎn)生紋理了。

First thing we need to do is to let OpenGL generate some texture id's that we will use as handles to the textures later on. In this example we will only have one texture.

首先要做的是讓OpenGL產(chǎn)生紋理ID,這些ID將在后面用到。例子中我們只有一個紋理。

// Create an int array with the number of textures we want,

// in this case 1.

int[]?textures =?new?int[1];

// Tell OpenGL to generate textures.

gl.glGenTextures(1, textures,?0);

With the same parameters you can delete the textures:

// Delete a texture.

gl.glDeleteTextures(1, textures,?0)

Now when the texture id's are generated we need to just like everything else tell OpenGL what to work with. With textures we use the command glBindTexture:

ID產(chǎn)生之后,我們需要將這些ID使用glBindTexture方式進行綁定

gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

From this point all commands we call on regarding textures will be applied on to your texture with the generated id.

那么在此之后,我們后面將使用產(chǎn)生的ID來調用紋理

glTexParameter

There is a couple of parameters we need to set on the texture, the first one is to tell OpenGL what to do if the texture need to be shrunk or magnified to match the rendered image.

在紋理映射,我們需要設置幾個參數(shù),第一個是告訴OpenGL在渲染圖片時,怎么縮小或放大以適合大小。
If the texture is smaller it needs to be magnified that is done with the magnification function:

如果貼圖小的話,那我們需要使用放大函數(shù)進行放大操作。

// Scale up if the texture if smaller.

gl.glTexParameterf(GL10.GL_TEXTURE_2D,

???????????????????GL10.GL_TEXTURE_MAG_FILTER,

???????????????????GL10.GL_LINEAR);

And how to scale if the texture needs to be scaled down using the minification function.

類似,在貼圖過多時,使用壓縮函數(shù)進行縮小。

// scale linearly when image smalled than texture

gl.glTexParameterf(GL10.GL_TEXTURE_2D,

???????????????????GL10.GL_TEXTURE_MIN_FILTER,

???????????????????GL10.GL_LINEAR);

You need to pass an argument to these functions. I'm only going to show you two of them the rest you can investigate your self

請看上面的函數(shù),你可以自己研究一下,該給它傳遞什么參數(shù)。

If you want a crisp and clean rendering like this image you need to use the GL10.GL_NEAREST parameter.

如果你想要清晰的渲染效果,你可以使用GL10.GL_NEAREST。

?

If you rather want a blurred image you should use the GL10.GL_LINEAR parameter.

如果你喜歡模糊一點,應該使用GL10.GL_LINEAR

UV Mapping

We will also need to tell OpenGL how to map this image onto the mesh this is done in two steps, fist we need to assign UV coordinates

下面我們需要告訴OpenGL怎樣將圖片映射到模型上,有兩個步驟。首先我們指定一個UV坐標

UV mapping is the way we map the pixels on the bitmap to the vertices in our mesh. The UV coordinates are 0,0 in the upper left and 1,1 is the bottom right, like the left image below. The right image below illustrates how our plane is built. To get the texture mapped correctly we need to map the lower left part of the texture (0,1) to the lower left vertex (0) in our plane and we need to map the the bottom right (1,1) in the texture to the bottom right (1) to the bottom right in our plane and... you get the idea.

我們使用UV映射將圖片的每一像素映射到模型的頂點上。UV坐標中,左上角為0,0,右下角為1,1,請看下圖的左半部分。右半部分是我們要創(chuàng)建的平面。為保證映射正確,我們將紋理左下角映射到左下角頂點0,右下角映射到頂點1…依此類推。

注:在OpenGL教程里講道,圖片左下角為0,0坐標。不過我們這里是Android的OpenGL ES。或許Android在接口封裝上,有些許改動吧。

?

We put this mapping into a float array like this:

紋理坐標數(shù)組的定義如下:

float?textureCoordinates[]?=?{0.0f,?1.0f,

??????????????????????????????1.0f,?1.0f,

??????????????????????????????0.0f,?0.0f,

??????????????????????????????1.0f,?0.0f?};

?

If we instead used 0.5 instead of 1.0 like this:

float?textureCoordinates[]?=?{0.0f,?0.5f,

??????????????????????????????0.5f,?0.5f,

??????????????????????????????0.0f,?0.0f,

??????????????????????????????0.5f,?0.0f?};

?


The texture will be mapped so the plane will have the upper left part of it.

那么將映射圖片的左上角到平面中

Back to the glTexParameterf, if we go the other way and uses values higher then 1.0 like this:

請回想一下glTexParameterf函數(shù)。如果我們將1.0放大到2.0

float?textureCoordinates[]?=?{0.0f,?2.0f,

??????????????????????????????2.0f,?2.0f,

??????????????????????????????0.0f,?0.0f,

??????????????????????????????2.0f,?0.0f?};

We actually tell OpenGL to use part of the texture that does not exist so we need to tell OpenGL what to do with the part that does not exist.

那么超過圖片的位置,OpenGL該如何處理呢?這正是下面我們討論的。

We use the glTexParameterf function to tell OpenGL what to do with the texture. By default OpenGL uses something called GL_REPEAT.

我們使用glTexParameterf函數(shù)來告訴OpenGL該如何進行貼圖,默認使用的參數(shù)項為GL_REPEAT

GL_REPEAT?means that OpenGL should repeat the texture beyond 1.0.

GL_REPEAT意味著OpenGL應該重復紋理超過1.0的部分
GL_CLAMP_TO_EDGE
?means that OpenGL only will draw the image once and after that just repeat the last pixel line the rest of the image.

GL_CLAMP_TO_EDGE表示OpenGL只畫圖片一次,剩下的部分將使用圖片最后一行像素重復

Since we are working with a 2D texture so we need to tell OpenGL what to do in two directions: GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T.

對于一個2D紋理,我們還需要告訴它們的方向。

Below you see a chart with the 4 combinations of GL_REPEAT and GL_CLAMP_TO_EDGE.

下面請看它們的四種組合(第三種組合對應的圖片錯了。)

WRAP_S: GL_REPEAT
WRAP_T: GL_REPEAT
WRAP_S: GL_REPEAT
WRAP_T: GL_CLAMP_TO_EDGE
WRAP_S: GL_REPEAT
WRAP_T: GL_CLAMP_TO_EDGE
WRAP_S: GL_CLAMP_TO_EDGE
WRAP_T: GL_CLAMP_TO_EDGE

This is how we use the glTexParameterf function:

gl.glTexParameterf(GL10.GL_TEXTURE_2D,

???????????????????GL10.GL_TEXTURE_WRAP_S,

???????????????????GL10.GL_REPEAT);

gl.glTexParameterf(GL10.GL_TEXTURE_2D,

???????????????????GL10.GL_TEXTURE_WRAP_T,

???????????????????GL10.GL_REPEAT);

The last thing we need to do is to bind the bitmap we loaded to the texture id we created.

GLUtils.texImage2D(GL10.GL_TEXTURE_2D,?0, bitmap,?0);

Using the texture

To be able to use the texture we need just like with everything else create a byte buffer with the UV coordinates:

對于UV坐標,我們同樣使用字節(jié)緩沖

FloatBuffer byteBuf = ByteBuffer.allocateDirect(texture.length?*?4);

byteBuf.order(ByteOrder.nativeOrder());

textureBuffer = byteBuf.asFloatBuffer();

textureBuffer.put(textureCoordinates);

textureBuffer.position(0);

Rendering

// Telling OpenGL to enable textures.

gl.glEnable(GL10.GL_TEXTURE_2D);

// Tell OpenGL where our texture is located.

gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

// Tell OpenGL to enable the use of UV coordinates.

gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

// Telling OpenGL where our UV coordinates are.

gl.glTexCoordPointer(2, GL10.GL_FLOAT,?0, textureBuffer);

?

// ... here goes the rendering of the mesh ...

?

// Disable the use of UV coordinates.

gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

// Disable the use of textures.

gl.glDisable(GL10.GL_TEXTURE_2D);

Putting it all together

I'm using a modified version of the code from the previous tutorial. The different is mostly that I renamed some variables and functions and added more comments and all code is now under Apache License. To make the code easier to understand I removed the previous plane and added a new easier one called SimplePlane.

Updating the Mesh class

The first thing we need to do is to update the Mesh class (se.jayway.opengl.tutorial.mesh.Mesh). We need to add the functionality to load and render a texture.

We need to be able to set and store the UV coordinates.

// Our UV texture buffer.

private?FloatBuffer mTextureBuffer;

?

/**

?* Set the texture coordinates.

?*

?* @param textureCoords

?*/

protected?void?setTextureCoordinates(float[]?textureCoords)?{

????????// float is 4 bytes, therefore we multiply the number if

????????// vertices with 4.

????????ByteBuffer byteBuf = ByteBuffer.allocateDirect(

???????????????????????????????????????????textureCoords.length?*?4);

????????byteBuf.order(ByteOrder.nativeOrder());

????????mTextureBuffer = byteBuf.asFloatBuffer();

????????mTextureBuffer.put(textureCoords);

????????mTextureBuffer.position(0);

}

?

We also need to add functions to set the bitmap and create the texture.

// Our texture id.

private?int?mTextureId =?-1;

?

// The bitmap we want to load as a texture.

private?Bitmap mBitmap;

?

/**

?* Set the bitmap to load into a texture.

?*

?* @param bitmap

?*/

public?void?loadBitmap(Bitmap bitmap)?{

????????this.mBitmap?= bitmap;

????????mShouldLoadTexture =?true;

}

?

/**

?* Loads the texture.

?*

?* @param gl

?*/

private?void?loadGLTexture(GL10 gl)?{

????????// Generate one texture pointer...

????????int[]?textures =?new?int[1];

????????gl.glGenTextures(1, textures,?0);

????????mTextureId = textures[0];

?

????????// ...and bind it to our array

????????gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);

?

????????// Create Nearest Filtered Texture

????????gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,

???????????????????????GL10.GL_LINEAR);

????????gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,

???????????????????????GL10.GL_LINEAR);

?

????????// Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE

????????gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,

???????????????????????GL10.GL_CLAMP_TO_EDGE);

????????gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,

???????????????????????GL10.GL_REPEAT);

?

????????// Use the Android GLUtils to specify a two-dimensional texture image

????????// from our bitmap

????????GLUtils.texImage2D(GL10.GL_TEXTURE_2D,?0, mBitmap,?0);

}

?

And finally we need to add the call to the texture loading and to actually tell OpenGL to render with this texture. I removed some code so the page would not be so long but you will find the code complete in the attached zip file.

// Indicates if we need to load the texture.

private?boolean?mShouldLoadTexture =?false;

?

/**

?* Render the mesh.

?*

?* @param gl

?*????????????the OpenGL context to render to.

?*/

public?void?draw(GL10 gl)?{

????????...

?

????????// Smooth color

????????if?(mColorBuffer !=?null)?{

???????????????// Enable the color array buffer to be used during rendering.

???????????????gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

???????????????gl.glColorPointer(4, GL10.GL_FLOAT,?0, mColorBuffer);

????????}

?

????????if?(mShouldLoadTexture)?{

???????????????loadGLTexture(gl);

???????????????mShouldLoadTexture =?false;

????????}

????????if?(mTextureId !=?-1?&& mTextureBuffer !=?null)?{

???????????????gl.glEnable(GL10.GL_TEXTURE_2D);

???????????????// Enable the texture state

???????????????gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

?

???????????????// Point to our buffers

???????????????gl.glTexCoordPointer(2, GL10.GL_FLOAT,?0, mTextureBuffer);

???????????????gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);

????????}

?

????????gl.glTranslatef(x, y, z);

?

????????...

?

????????// Point out the where the color buffer is.

????????gl.glDrawElements(GL10.GL_TRIANGLES, mNumOfIndices,

???????????????????????GL10.GL_UNSIGNED_SHORT, mIndicesBuffer);

?

????????...

?

????????if?(mTextureId !=?-1?&& mTextureBuffer !=?null)?{

???????????????gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

????????}

?

????????...

?

}

Creating the SimplePlane class

We also need to create the SimplePlane.java. The code is pretty simple and self-explaining if you have read my previous tutorials. The new element is the textureCoordinates variable.

?

package?se.jayway.opengl.tutorial.mesh;

?

/**

?* SimplePlane is a setup class for Mesh that creates a plane mesh.

?*

?* @author Per-Erik Bergman (per-erik.bergman@jayway.com)

?*

?*/

public?class?SimplePlane?extends?Mesh?{

????????/**

?????????* Create a plane with a default with and height of 1 unit.

?????????*/

????????public?SimplePlane()?{

???????????????this(1,?1);

????????}

?

????????/**

?????????* Create a plane.

?????????*

?????????* @param width

?????????*????????????the width of the plane.

?????????* @param height

?????????*????????????the height of the plane.

?????????*/

????????public?SimplePlane(float?width,?float?height)?{

???????????????// Mapping coordinates for the vertices

???????????????float?textureCoordinates[]?=?{?0.0f,?2.0f,?//

???????????????????????????????2.0f,?2.0f,?//

???????????????????????????????0.0f,?0.0f,?//

???????????????????????????????2.0f,?0.0f,?//

???????????????};

?

???????????????short[]?indices =?new?short[]?{?0,?1,?2,?1,?3,?2?};

?

????????????????float[]?vertices =?new?float[]?{?-0.5f,?-0.5f,?0.0f,

??????????????????????????????????????????????????0.5f,?-0.5f,?0.0f,

?????????????????????????????????????????????????-0.5f,??0.5f,?0.0f,

??????????????????????????????????????????????????0.5f,?0.5f,?0.0f?};

?

???????????????setIndices(indices);

???????????????setVertices(vertices);

???????????????setTextureCoordinates(textureCoordinates);

????????}

}

?

References

The info used in this tutorial is collected from:
Android Developers
OpenGL ES 1.1 Reference Pages

You can download the source for this tutorial here:?Tutorial_Part_VI
You can also checkout the code from:?code.google.com

Previous tutorial:?OpenGL ES Tutorial for Android – Part V – More on Meshes

Per-Erik Bergman?
Consultant at?Jayway







總結

以上是生活随笔為你收集整理的OpenGL ES教程VI之纹理贴图(原文对照)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。