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
分享到:
相关推荐
OpenGL绘制旋转六面体并纹理贴图是一个典型的计算机图形学应用,主要涉及到OpenGL库的使用,C++编程,以及纹理映射技术。在VS2019环境下开发这样的项目,可以提供一个良好的集成开发环境来实现3D图形的动态渲染。 ...
在这个“OpenGL实现的正方体六面贴图”的项目中,我们主要关注的是如何使用OpenGL来绘制一个正方体,并为每个面分别应用不同的纹理图像。下面我们将详细探讨相关的知识点。 首先,OpenGL是一个低级别的图形库,它...
计算机图形学作业-基于C++和OpenGL实现六面体的旋转平移缩放等操作+扫描线源码(含演示视频).zip计算机图形学作业-基于C++和OpenGL实现六面体的旋转平移缩放等操作+扫描线源码(含演示视频).zip计算机图形学作业-基于...
在本例中,平行六面体由六个矩形面构成,需要正确设置顶点顺序以确保正确的连接。 为了实现动画效果,可能包含了额外的逻辑,比如在Animation文件中,可能会有定时器函数,每隔一定时间更新模型的旋转角度或者位置...
本设计的主要目标是在三维坐标系中,以原点作为中心绘制一个正六面体,并在其六个面上分别贴上六张不同的图像。通过这种方式,可以实现图像的动态显示,并能够通过键盘控制正六面体的旋转状态。 #### 设计需求 1. ...
天空盒是一种常见的3D图形技术,它通过在六面体的每个面上绘制全景图像来模拟无限远的天空背景,给人一种广阔无垠的空间感。这种技术可以有效减少性能开销,因为天空盒通常只在远处可见,且不会与场景中的其他对象...
六个面不同的图片贴图,针对于不同的贴图,才用的是C语言,首先自行安装必须要的库函数,配置好
《正六面纹理贴图(VC6.0)——OpenGL中的纹理映射技术解析》 在计算机图形学领域,纹理贴图是一种常见的增强图形表现力的技术。本项目以Visual C++ 6.0为开发环境,结合OpenGL图形库,实现了正六面体的纹理映射...
OpenGL生成有贴图的旋转的正六面体 源文件 里面的正六面体会转动 用 1 2 可以控制转动停止 六个面都有贴图
每个六面体元素由八个节点定义,形成六个矩形或平行六边形的面。这种网格结构因其高精度和稳定性,在结构工程、流体力学等领域的有限元分析中被广泛采用。 ### 从表面四边形网格生成六面体网格的技术 #### 表面...
首先,天空盒的基本概念是将一个六面体(立方体)的每个面都贴上天空的图像,这六个面分别对应正前方、正后方、正上方、正下方、右方和左方。在渲染时,这六个面会被映射到无限远处,从而创造出一个看似无边界的天空...
立方体贴图是一种特殊的纹理类型,用于表示环境映射,它可以将六个正交的2D纹理面组合成一个3D对象的周围环境。这六个面分别代表了正前方、正后方、右方、左方、上方和下方的视角。这种技术广泛应用于反射、折射和...
在这个示例中,我们使用 Opengl 在正六面体上实现纹理映射,并添加了旋转、移动等调节功能。 Opengl 是一种跨平台的图形API,它提供了一个强大的三维图形渲染引擎,可以在Windows、Linux、Mac OS 等多种平台上运行...
总的来说,"六面天空盒JPG_skybox"是一种有效的3D场景背景解决方案,通过巧妙地利用六个JPEG图像,为虚拟世界带来了生动逼真的天空效果。无论是游戏开发、虚拟现实还是其他应用,这种技术都是提高视觉质量的不可或缺...
多面体和二次曲面的生成,及基本的纹理映射
六面体是有限元分析中常见的一种元素类型,它具有六个面,通常被用来近似三维空间中的复杂几何形状。这种元素结构稳定,适合于构建精确的数值模型,特别是在解决固体力学问题时。 压缩包内的文件功能如下: 1. `do...
六面体由六个正方形面组成,每个面有自己的坐标系统。通过改变这些面的旋转角度,可以实现六面体的动态旋转。在JavaScript中,可以使用sin和cos函数计算旋转后的坐标,然后更新到canvas上。 为了实现两者结合,可以...
在对六面体进行纹理映射时,我们首先需要创建六面体的几何形状,这通常包括六个矩形面,每个面都有四个顶点。接着,我们需要为每个顶点指定纹理坐标。例如,一个简单的六面体可能有以下纹理坐标: - 面1:(0, 0), ...
这六个平面分别对应于视锥体的前、后、左、右、上、下六个面。每个平面都有一个裁剪方程,用于判断点是否在平面内、外或上。裁剪过程通常使用模拟裁剪立方体的方法,对每个几何图元的顶点进行裁剪,并根据裁剪结果...
本设计任务是通过OpenGL技术在3D空间中绘制一个正方体,并将6张不同的图片作为纹理映射到正方体的六个面上,以此增强视觉效果,提升立体感。设计师需要具备一定的OpenGL编程能力,以及对图像处理的理解。实现后的...