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 居然不能直接在博客上贴图!!! 附件上传了效果图以及当时把顶点拆分时的模型顶点分析手稿。
- 大小: 842 KB
- 大小: 13.6 KB
- 大小: 13.7 KB
分享到:
相关推荐
1、基于VS2019的C++OpenGL语言工程,亲自测试运行流畅。2、是基于OpenGL的六面体绘制,并且六个平面可以贴上不同的图片纹理,可自行修改。
用opengl实现的正六面体贴图,每面的图形都不一样,图像文件存放在Data文件夹下。 使用vs2005及以上版本编译。 按键盘上的上、下、左、右可实现六面体旋转的方向及速度。
改程序说明了如何在MFC环境下用OpenGL,对初学者有一定借鉴作用
正六面体 贴图 纹理贴图 源码
OpenGL生成有贴图的旋转的正六面体 源文件 里面的正六面体会转动 用 1 2 可以控制转动停止 六个面都有贴图
计算机图形学作业-基于C++和OpenGL实现六面体的旋转平移缩放等操作+扫描线源码(含演示视频).zip计算机图形学作业-基于C++和OpenGL实现六面体的旋转平移缩放等操作+扫描线源码(含演示视频).zip计算机图形学作业-基于...
多面体和二次曲面的生成,及基本的纹理映射
利用Visual c++编写的调用openGL图形软件包实现的正六面体纹理贴图的小程序源代码和一个设计文档。纹理贴图所使用的图片在data文件夹中。
六个面不同的图片贴图,针对于不同的贴图,才用的是C语言,首先自行安装必须要的库函数,配置好
基于VS2010的Opengl在正六面体上的纹理映射,实现贴图,旋转,移动等调节功能
六面体生成技术文献(从表面四边形网格生成空间六面体进行有限元分析的文献)
matlab编制的八节点六面体单元刚度矩阵计算程序
六面天空盒JPG_skybox
VS工程奉上,运行逻辑应该无问题,用六面体代表贪吃蛇的身体,绘制用一个数组保存所有的顶点,用一个数组保存顶点的序号。但最后绘制的时候,不是编写循环语句逐个的指定顶点了,而是通知OpenGL,”保存顶点的数组”...
个LED,作为标记【类似于传统的骰子),能够对 正六面体端面进行识别,内置控制电路。随机转动 六面体,等待此六面体静止后,实现自动识别平行 于地面上方的端面并点亮LED。用LED不同位数 显示标记信息,...
有限元六面体单元MATLAB代码,有限元,FEM,六面体单元,等参元
实现空间六面体的有限元形变,有图有真相。doit.m是总体的命令行批处理执行文件。
四面体网格与六面体网格的比较,可以供大家参考一下。
拼图游戏,基于opengl的六面体拼图,
flex 六面体翻转例子