OpenGL 绘制彩色六面体(六个面六种颜色)

Android API Demo 中有个 Touch Rotate 的彩色立方体,把这个立方体修改成 -- 每个面有单一不同颜色的长方体。

OpenGL可以为顶点着色,OpenGL允许为同一多边形的不同顶点指定不同的颜色。


在默认情况下,OpenGL会计算两点顶点之间的其它点,并为它们填上“合适”的颜色,使相邻的点的颜色值都比较接近。如果使用的是RGB模式,看起来就具有渐变的效果。如果是使用颜色索引模式,则其相邻点的索引值是接近的,如果将颜色表中接近的项设置成接近的颜色,则看起来也是渐变的效果。但如果颜色表中接近的项颜色却差距很大,则看起来可能是很奇怪的效果。
使用glShadeModel函数可以关闭这种计算,如果顶点的颜色不同,则将顶点之间的其它点全部设置为与某一个点相同。(直线以后指定的点的颜色为准,而多边形将以任意顶点的颜色为准,由实现决定。)为了避免这个不确定性,尽量在多边形中使用同一种颜色。
glShadeModel的使用方法:
glShadeModel(GL_SMOOTH); // 平滑方式,这也是默认方式
glShadeModel(GL_FLAT); // 单色方式

Demo中默认使用glShadeModel(GL_SMOOTH),Demo中为每个顶点设置不同颜色,所以可以看到Demo中是一个渐变色的立方体。想把每个面改成单一的颜色有两种思路:
1. 指定画笔颜色,画一个面,切换画笔颜色,画另一个面,循环上述,将其与四个面出来
可以参考
http://yarin.blog.51cto.com/1130898/380303 的画法。

2. 使用 glShadeModel(GL_FLAT)方式, 为每个顶点指定颜色,在同一平面上的定点颜色一致。那么会遇到的问题是:如果设置长方体有8个顶点,每个顶点被三个面所共有,而三个面的颜色却不一样,解决的办法是把每个顶点拆分成三个点,这样三个点分别为三个面所使用。

/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.android.apis.graphics;

import android.R.integer;
import android.util.Log;
import android.view.InflateException;

import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

/**
* A vertex shaded cube.
*/
class Cube
{
public Cube()
{
int one = 0x10000;
int two = 0x20000;
int three = 0x30000;
int six = 0x60000;

// 重新定义顶点,将原来的每个顶点拆分成三个点
int vertices[] = {
-two, -three, -six,
-two, -three, -six,
-two, -three, -six,

two, -three, -six,
two, -three, -six,
two, -three, -six,

two, three, -six,
two, three, -six,
two, three, -six,

-two, three, -six,
-two, three, -six,
-two, three, -six,

-two, -three, six,
-two, -three, six,
-two, -three, six,

two, -three, six,
two, -three, six,
two, -three, six,

two, three, six,
two, three, six,
two, three, six,

-two, three, six,
-two, three, six,
-two, three, six,
};


// int colors[] = {
// 0, 0, 0, one,
// one, 0, 0, one, // 红
// one, one, 0, one, // 黄
// 0, one, 0, one, // 绿
// 0, 0, one, one, 蓝
// one, 0, one, one, 粉
// one, one, one, one,
// 0, one, one, one, 浅蓝
// };

// 为每个点指定颜色,在同一平面上的点颜色相同,indices 每行的点颜色一样
int colors[] = {

one, 0, 0, one,
0, 0, one, one,
0, one, one, one,
one, 0, 0, one,
one, one, 0, one,
0, one, one, one,
one, one, 0, one,
0, one, 0, one,
0, one, one, one,
0, one, 0, one,
0, 0, one, one,
0, one, one, one,
one, 0, 0, one,
0, 0, one, one,
one, 0, one, one,
one, 0, 0, one,
one, one, 0, one,
one, 0, one, one,
one, one, 0, one,
0, one, 0, one,
one, 0, one, one,
0, one, 0, one,
0, 0, one, one,
one, 0, one, one,
};
// 每个顶点被拆分为三个点,要保证同一个点不能被不同的平面使用,indices 每一行代表一个平面
byte indices[] = {
0, 12, 15, 0, 15, 3,
4, 16, 18, 4, 18, 6,
7, 19, 21, 7, 21, 9,
10, 22, 13, 10, 13, 1,
14, 23, 20, 14, 20, 17,
11, 2, 5, 11, 5, 8
};

// Buffers to be passed to gl*Pointer() functions
// must be direct, i.e., they must be placed on the
// native heap where the garbage collector cannot
// move them.
//
// Buffers with multi-byte datatypes (e.g., short, int, float)
// must have their byte order set to native order

ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);

ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asIntBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);

mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
mIndexBuffer.put(indices);
mIndexBuffer.position(0);
}

public void draw(GL10 gl)
{
if (gl instanceof GL11) {
GL11 gl11 = (GL11) gl;
FloatBuffer params = FloatBuffer.allocate(16);
gl11.glGetFloatv(gl11.GL_PROJECTION_MATRIX, params);
Log.i("draw", "params " + params.array().toString());
}
gl.glFrontFace(GL10.GL_CW);
gl.glShadeModel(GL10.GL_FLAT);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer); //使用单色方式
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
}

private IntBuffer mVertexBuffer;
private IntBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
}


ITEYE 居然不能直接在博客上贴图!!! 附件上传了效果图以及当时把顶点拆分时的模型顶点分析手稿。

你可能感兴趣的:(OpenGL)