3D立方体及光照
来源:互联网 发布:cms源码 编辑:程序博客网 时间:2024/06/10 15:53
本代码主要实现了一个旋转立方体, 并添加了光照效果。
Qt 版:
myglwidget.h
#ifndef MYGLWIDGET_H#define MYGLWIDGET_H#include <QGLWidget>#include <QVector2D>#include <QVector3D>#include <QTimer>class MyGLWidget : public QGLWidget{ Q_OBJECTpublic: explicit MyGLWidget(QWidget *parent = 0);signals:public slots:protected: // Set up the rendering context, define display lists etc.: void initializeGL(); void resizeGL(int w, int h); void paintGL();private: void makeObject(); void initLighting(); GLfloatxrot;// X 旋转量 GLfloatyrot;// Y 旋转量 GLfloatzrot;// Z 旋转量 GLuinttextures[6];// 存储一个纹理 QVector<QVector3D> vertices; QVector<QVector2D> texCoords; QTimer *timer;};#endif // MYGLWIDGET_H
myglwidget.cpp
#include "myglwidget.h"#ifndef GL_MULTISAMPLE#define GL_MULTISAMPLE 0x809D#endifMyGLWidget::MyGLWidget(QWidget *parent) : QGLWidget(parent){ xrot = 0.0f; yrot = 0.0f; zrot = 0.0f; timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(updateGL())); timer->start(10);} void MyGLWidget::initializeGL() { makeObject();initLighting(); glShadeModel(GL_SMOOTH);// 启用阴影平滑 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);// 黑色背景 glClearDepth(1.0f);// 设置深度缓存 glEnable(GL_CULL_FACE); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST);// 启用深度测试 glDepthFunc(GL_LEQUAL);// 所作深度测试的类型 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// 告诉系统对透视进行修正 } void MyGLWidget::resizeGL(int width, int height) { if (height==0)// 防止被零除 { height=1;// 将Height设为1 } glViewport(0, 0, width, height);// 重置当前的视口 glMatrixMode(GL_PROJECTION);// 选择投影矩阵 glLoadIdentity(); // 重置投影矩阵 // 设置视口的大小 gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW);// 选择模型观察矩阵 glLoadIdentity();// 重置模型观察矩阵 } void MyGLWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 清除屏幕和深度缓存 glLoadIdentity();// 重置当前的模型观察矩阵 glColor3f(1.0, 0.0, 1.0); glTranslatef(0.0f,0.0f,-5.0f);// 移入屏幕 5 个单位 glRotatef(xrot,1.0f,0.0f,0.0f);// 绕X轴旋转 glRotatef(yrot,0.0f,1.0f,0.0f);// 绕Y轴旋转 glRotatef(zrot,0.0f,0.0f,1.0f);// 绕Z轴旋转 glVertexPointer(3, GL_FLOAT, 0, vertices.constData()); glTexCoordPointer(2, GL_FLOAT, 0, texCoords.constData()); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); for (int i = 0; i < 6; ++i) { glBindTexture(GL_TEXTURE_2D, textures[i]); glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4); } xrot+=0.3f;// X 轴旋转 yrot+=0.2f;// Y 轴旋转 zrot+=0.4f;// Z 轴旋转 } void MyGLWidget::initLighting() { GLfloat lightPos[] = { 75.0f, 0.0f, 0.0f, 1.0f }; GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f}; GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat ambientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f}; GLfloat spotDir[] = { 0.0f, 0.0f, -1.0f }; glEnable(GL_DEPTH_TEST); // Hidden surface removal glFrontFace(GL_CCW); // Counterclockwise polygons face out glEnable(GL_CULL_FACE); // Do not try to display the back sides // Enable lighting glEnable(GL_LIGHTING); // Set up and enable light 0 // Supply a slight ambient light so the objects can be seen glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight); // The light is composed of just diffuse and specular components glLightfv(GL_LIGHT0,GL_DIFFUSE,ambientLight); glLightfv(GL_LIGHT0,GL_SPECULAR,specular); glLightfv(GL_LIGHT0,GL_POSITION,lightPos); // Specific spot effects // Cut-off angle is 60 degrees glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,60.0f); // Enable this light in particular glEnable(GL_LIGHT0); // Enable color tracking glEnable(GL_COLOR_MATERIAL); // Set material properties to follow glColor values glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // All materials hereafter have full specular reflectivity // with a high shine glMaterialfv(GL_FRONT, GL_SPECULAR,specref); glMateriali(GL_FRONT, GL_SHININESS,128); // Black background glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); } void MyGLWidget::makeObject() { static const int coords[6][4][3] = { { { +1, -1, -1 }, { -1, -1, -1 }, { -1, +1, -1 }, { +1, +1, -1 } }, { { +1, +1, -1 }, { -1, +1, -1 }, { -1, +1, +1 }, { +1, +1, +1 } }, { { +1, -1, +1 }, { +1, -1, -1 }, { +1, +1, -1 }, { +1, +1, +1 } }, { { -1, -1, -1 }, { -1, -1, +1 }, { -1, +1, +1 }, { -1, +1, -1 } }, { { +1, -1, +1 }, { -1, -1, +1 }, { -1, -1, -1 }, { +1, -1, -1 } }, { { -1, -1, +1 }, { +1, -1, +1 }, { +1, +1, +1 }, { -1, +1, +1 } } }; for (int j=0; j < 6; ++j) { textures[j] = bindTexture (QPixmap(QString(":/images/side%1.png").arg(j + 1)), GL_TEXTURE_2D); } for (int i = 0; i < 6; ++i) { for (int j = 0; j < 4; ++j) { texCoords.append (QVector2D(j == 0 || j == 3, j == 0 || j == 1)); vertices.append (QVector3D(0.5 * coords[i][j][0], 0.5 * coords[i][j][1], 0.5 * coords[i][j][2])); } } }
main.cpp
#include <QApplication>#include "myglwidget.h"int main(int argc, char *argv[]){ QApplication a(argc, argv); MyGLWidget win ; win.show(); return a.exec();}
Android 版本:
MyRender.java
import java.io.IOException;import java.io.InputStream;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.opengl.GLSurfaceView.Renderer;import android.opengl.GLU;import android.opengl.GLUtils;public class MyRenderer implements Renderer {public MyRenderer(Context ctx) {mContext = ctx;}@Overridepublic void onDrawFrame(GL10 gl) {// TODO Auto-generated method stub gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 清除屏幕和深度缓存 gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity();// 重置当前的模型观察矩阵 gl.glTranslatef(0, 0, 5); gl.glRotatef(xrot,1.0f,0.0f,0.0f);// 绕X轴旋转 gl.glRotatef(yrot,0.0f,1.0f,0.0f);// 绕Y轴旋转 gl.glRotatef(zrot,0.0f,0.0f,1.0f);// 绕Z轴旋转 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer); for (int i = 0; i < 6; ++i) { gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[i]); gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, i * 4, 4); } xrot+=0.3f;// X 轴旋转 yrot+=0.2f;// Y 轴旋转 zrot+=0.4f;// Z 轴旋转}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {// TODO Auto-generated method stub if (height==0)// 防止被零除 { height=1;// 将Height设为1 } gl.glViewport(0, 0, width, height);// 重置当前的视口 gl.glMatrixMode(GL10.GL_PROJECTION);// 选择投影矩阵 gl.glLoadIdentity(); // 重置投影矩阵 // 设置视口的大小 GLU.gluPerspective(gl, 45.0f,(float)width/(float)height,0.1f,100.0f); GLU.gluLookAt(gl, 0, 0, -5, 0, 0, 0, 0, 1, 0); gl.glMatrixMode(GL10.GL_MODELVIEW);// 选择模型观察矩阵 gl.glLoadIdentity();// 重置模型观察矩阵}@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {// TODO Auto-generated method stubmakeObject(gl);initLigthing(gl); gl.glEnable(GL10.GL_DEPTH_TEST); gl.glEnable(GL10.GL_CULL_FACE); gl.glFrontFace(GL10.GL_CW); gl.glEnable(GL10.GL_TEXTURE_2D);//gl.glEnable(GL10.GL_LIGHTING);//gl.glEnable(GL10.GL_LIGHT0);}private int bindTexture(GL10 gl, int rsid) {int[] textures = new int[1];// 创建纹理gl.glGenTextures(1, textures, 0);gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);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_CLAMP_TO_EDGE);gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,GL10.GL_REPLACE);InputStream is = mContext.getResources().openRawResource(rsid);Bitmap bitmapTmp;try {bitmapTmp = BitmapFactory.decodeStream(is);} finally {try {is.close();} catch (IOException e) {// Ignore.}}GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmapTmp, 0);bitmapTmp.recycle();return textures[0];}private void initLigthing(GL10 gl) {float mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };float mat_shininess[] = { 50.0f };float light_position[] = { 0.0f, 0.0f, 1.0f, 0.0f };float white_light[] = { 1.0f, 1.0f, 1.0f, 1.0f };float lmodel_ambient[] = { 0.1f, 0.1f, 0.1f, 1.0f };//gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//gl.glShadeModel(GL10.GL_SMOOTH);FloatBuffer specularBuffer;ByteBuffer bb1 = ByteBuffer.allocateDirect(mat_specular.length * 4);bb1.order(ByteOrder.nativeOrder());specularBuffer = bb1.asFloatBuffer();gl.glMaterialfv(GL10.GL_FRONT, GL10.GL_SPECULAR, specularBuffer);FloatBuffer shininessBuffer;ByteBuffer bb2 = ByteBuffer.allocateDirect(mat_shininess.length * 4);bb2.order(ByteOrder.nativeOrder());shininessBuffer = bb2.asFloatBuffer();gl.glMaterialfv(GL10.GL_FRONT, GL10.GL_SHININESS, shininessBuffer);FloatBuffer positionBuffer;ByteBuffer bb3 = ByteBuffer.allocateDirect(light_position.length * 4);bb3.order(ByteOrder.nativeOrder());positionBuffer = bb3.asFloatBuffer();gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, positionBuffer);FloatBuffer lightBuffer;ByteBuffer bb4 = ByteBuffer.allocateDirect(white_light.length * 4);bb4.order(ByteOrder.nativeOrder());lightBuffer = bb4.asFloatBuffer();gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightBuffer);gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, lightBuffer);FloatBuffer ambientBuffer;ByteBuffer bb5 = ByteBuffer.allocateDirect(lmodel_ambient.length * 4);bb5.order(ByteOrder.nativeOrder());ambientBuffer = bb5.asFloatBuffer();gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT, ambientBuffer); gl.glEnable(GL10.GL_LIGHTING); gl.glEnable(GL10.GL_LIGHT0);}private void makeObject(GL10 gl) {float []vertices = {//底部 +1, -1, -1 , -1, -1, -1 , -1, +1, -1 , +1, +1, -1 , //后面 +1, +1, -1 , -1, +1, -1 , -1, +1, +1 , +1, +1, +1 , //右面 +1, -1, +1 , +1, -1, -1 , +1, +1, -1 , +1, +1, +1 , //左面 -1, -1, -1 , -1, -1, +1 , -1, +1, +1 , -1, +1, -1 , //前面 +1, -1, +1 , -1, -1, +1 , -1, -1, -1 , +1, -1, -1 , //顶面 -1, -1, +1 , +1, -1, +1 , +1, +1, +1 , -1, +1, +1 };for (int i = 0; i < vertices.length; i++)vertices[i] = (float) (0.5 * vertices[i]);float []texcoords = {// 前面0.0f, 0.0f, // 纹理左下1.0f, 0.0f,// 纹理右下1.0f, 1.0f,// 纹理右上0.0f, 1.0f,// 纹理左上// 后面1.0f, 0.0f,// 纹理右下1.0f, 1.0f,// 纹理右上0.0f, 1.0f,// 纹理左上0.0f, 0.0f,// 纹理左下// 顶面0.0f, 1.0f,// 纹理左上0.0f, 0.0f,// 纹理左下1.0f, 0.0f,// 纹理右下1.0f, 1.0f,// 纹理右上// 底面1.0f, 1.0f,// 纹理右上0.0f, 1.0f,// 纹理左上0.0f, 0.0f,// 纹理左下1.0f, 0.0f,// 纹理右下// 右面1.0f, 0.0f,// 纹理右下1.0f, 1.0f,// 纹理右上0.0f, 1.0f,// 纹理左上0.0f, 0.0f,// 纹理左下// 左面0.0f, 0.0f,// 纹理左下1.0f, 0.0f,// 纹理右下1.0f, 1.0f,// 纹理右上0.0f, 1.0f// 纹理左上};int[] rids = { R.raw.side1, R.raw.side2, R.raw.side3, R.raw.side4, R.raw.side5, R.raw.side6 };textures = new int[6]; for (int j=0; j < 6; ++j) { textures[j] = bindTexture(gl, rids[j]); } ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); vertexBuffer = vbb.asFloatBuffer(); vertexBuffer.put(vertices); vertexBuffer.position(0); ByteBuffer tbb = ByteBuffer.allocateDirect(texcoords.length * 4); tbb.order(ByteOrder.nativeOrder()); mTexBuffer = tbb.asFloatBuffer(); mTexBuffer.put(texcoords); mTexBuffer.position(0);}private int textures[];private FloatBuffer vertexBuffer;private FloatBuffer mTexBuffer;private Context mContext;private static final float PI = 3.1415f; private float xrot = 0; private float yrot = 0; private float zrot = 0;}
Activity
import android.app.Activity;import android.opengl.GLSurfaceView;import android.os.Bundle;public class TextureTestActivity extends Activity { private GLSurfaceView mView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mView = new GLSurfaceView(this); mView.setRenderer(new MyRenderer(this)); setContentView(mView); } @Overrideprotected void onResume() {super.onResume();mView.onResume();}@Overrideprotected void onPause() {super.onPause();mView.onPause();} }
- 3D立方体及光照
- 3D 旋转立方体
- 3D立方体(代码)
- cocos 3D 光照
- XNA-3D-绘制立方体
- Android opengl 3D立方体
- wpf 3D立方体旋转
- 3D旋转立方体演示
- 3D动画立方体实现
- h5 3D旋转立方体
- css3之3D立方体
- CSS3 3D旋转立方体
- 3D局部光照模型
- 3D光照渲染小球
- 3D局部光照模型
- 3D局部光照模型
- 3d 绘制中的光照
- Android 3D opengl 立方体 多纹理
- MYSQL复习1
- C++中堆和栈的区别,自由存储区、全局/静态存储区和常量存储区
- mongodb 学习笔记一
- 使用迅雷代替SDK Manager快速下载Android SDK相关
- 深入理解C++中的mutable关键字
- 3D立方体及光照
- 【郭林专刊】自信还是危机感
- 一个cdecl 程序的混乱版本 150行的代码用15行解决
- 搞IT的到底怎么了
- PHP做的一个简单投票系统
- Got the job
- toj 3140
- [hdu3477] Temperature [3472] HS BDC
- 作为程序员为什么一直都很努力,却没有进步? .