#include "instancing_1.h"
#include "vutils.h"
#include "vmath.h"
#include "vbm_ch3_intancing1.h"
namespace instancing1
{
float shade_aspect = 800 / 600;
GLuint color_buffer;
GLuint model_matrix_buffer;
GLuint render_prog;
GLuint model_matrix_loc;
GLuint view_matrix_loc;
GLuint projection_matrix_loc;
VBObject object;
#define INSTANCE_COUNT 100
GLenum gl_err = 0;
static const GLubyte* errorStr = NULL;
};
using namespace instancing1;
void instancing1Init()
{
int n;
//创建着色器程序
render_prog = glCreateProgram();
//着色器字符串
static const char render_vs[] =
"#version 410\n"
"\n"
"// 'position' and 'normal' are regular vertex attributes\n"
"layout (location = 0) in vec4 position;\n"
"layout (location = 1) in vec3 normal;\n"
"\n"
"// Color is a per-instance attribute\n"
"layout (location = 2) in vec4 color;\n"
"\n"
"// model_matrix will be used as a per-instance transformation\n"
"// matrix. Note that a mat4 consumes 4 consecutive locations, so\n"
"// this will actually sit in locations, 3, 4, 5, and 6.\n"
"layout (location = 3) in mat4 model_matrix;\n"
"\n"
"// The view matrix and the projection matrix are constant across a draw\n"
"uniform mat4 view_matrix;\n"
"uniform mat4 projection_matrix;\n"
"\n"
"// The output of the vertex shader (matched to the fragment shader)\n"
"out VERTEX\n"
"{\n"
" vec3 normal;\n"
" vec4 color;\n"
"} vertex;\n"
"\n"
"// Ok, go!\n"
"void main(void)\n"
"{\n"
" // Construct a model-view matrix from the uniform view matrix\n"
" // and the per-instance model matrix.\n"
" mat4 model_view_matrix = view_matrix * model_matrix;\n"
"\n"
" // Transform position by the model-view matrix, then by the\n"
" // projection matrix.\n"
" gl_Position = projection_matrix * (model_view_matrix * position);\n"
" // Transform the normal by the upper-left-3x3-submatrix of the\n"
" // model-view matrix\n"
" vertex.normal = mat3(model_view_matrix) * normal;\n"
" // Pass the per-instance color through to the fragment shader.\n"
" vertex.color = color;\n"
"}\n";
static const char render_fs[] =
"#version 410\n"
"\n"
"layout (location = 0) out vec4 color;\n"
"\n"
"in VERTEX\n"
"{\n"
" vec3 normal;\n"
" vec4 color;\n"
"} vertex;\n"
"\n"
"void main(void)\n"
"{\n"
" color = vertex.color * (0.1 + abs(vertex.normal.z)) + vec4(0.8, 0.9, 0.7, 1.0) * pow(abs(vertex.normal.z), 40.0);\n"
"}\n";
//shader创建,编译,装载
vglAttachShaderSource( render_prog, GL_VERTEX_SHADER, render_vs );
vglAttachShaderSource( render_prog, GL_FRAGMENT_SHADER, render_fs );
//连接着色器成为可用程序
glLinkProgram(render_prog);
//激活着色器
glUseProgram(render_prog);
//获取视图矩阵位置
view_matrix_loc = glGetUniformLocation(render_prog, "view_matrix");
//获取投影矩阵位置
projection_matrix_loc = glGetUniformLocation(render_prog, "projection_matrix");
//加载vbm模型文件
//@pram 1路径、2顶点location 3法线location、4纹理location(颜色)
object.LoadFromVBM("../8edlib/media/armadillo_low.vbm", 0, 1, 2);
//绑定顶点数组
object.BindVertexArray();
//获取顶点着色器in变量location
int position_loc = glGetAttribLocation( render_prog, "position" );
int normal_loc = glGetAttribLocation( render_prog, "normal" );
int color_loc = glGetAttribLocation( render_prog, "color" );
int matrix_loc = glGetAttribLocation( render_prog, "model_matrix");
//每个实例的颜色数组
vmath::vec4 colors[INSTANCE_COUNT];
for (n = 0; n < INSTANCE_COUNT; n++ )
{
float a = float(n) / 4.0f;
float b = float(n) / 5.0f;
float c = float(n) / 6.0f;
colors[n][0] = 0.5f + 0.25f * (sinf(a + 1.0f) + 1.0f );
colors[n][1] = 0.5f + 0.25f * (sinf(b + 2.0f) + 1.0f );
colors[n][2] = 0.5f + 0.25f * (sinf(c + 3.0f) + 1.0f );
colors[n][3] = 1.0f;
}
//缓存对象
glGenBuffers(1, &color_buffer);
glBindBuffer(GL_ARRAY_BUFFER, color_buffer);//3个工作。
glBufferData( GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW );//动态改变用于绘制的数据
glVertexAttribPointer( color_loc, 4, GL_FLOAT, GL_FALSE, 0, NULL );
glEnableVertexAttribArray( color_loc );
//!!!启用顶点属性多实例属性,每个实例读取一次颜色值
glVertexAttribDivisor( color_loc, 1);
//模型矩阵数据
glGenBuffers(1, &model_matrix_buffer );
glBindBuffer( GL_ARRAY_BUFFER, model_matrix_buffer );
//NULL保留内存
glBufferData( GL_ARRAY_BUFFER, INSTANCE_COUNT * sizeof(vmath::mat4), NULL, GL_DYNAMIC_DRAW );
for (int i = 0; i < 4; i++ )
{
glVertexAttribPointer(matrix_loc + i, 4, GL_FLOAT, GL_FALSE, sizeof(vmath::mat4), (void *)(sizeof(vmath::vec4)* i));
glEnableVertexAttribArray( matrix_loc + i );
glVertexAttribDivisor( matrix_loc + i, 1 );
}
//解除vao绑定,至于为什么要这句呢,我的理解是:这是个好习惯,用完之后吧OpenGL还原默认状态。
glBindVertexArray(0);
}
static inline int min( int a, int b )
{
return a < b ? a : b;
}
void instancing1Display()
{
float t = float(GetTickCount() & 0x3FFF) / float(0x3FFF);
int n;
//清屏
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//
glEnable( GL_CULL_FACE );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
//绑定vbo,修改数据
glBindBuffer( GL_ARRAY_BUFFER, model_matrix_buffer );
//获取当前vbo的OpenGL指针
vmath::mat4* matrices = (vmath::mat4*)glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
for (n = 0; n < INSTANCE_COUNT; n++ )
{
float a = 50.0f * float(n) / 4.0f;
float b = 50.0f * float(n) / 5.0f;
float c = 50.0f * float(n) / 6.0f;
matrices[n] = vmath::rotate(a + t * 360.0f, 1.0f, 0.0f, 0.0f) *
vmath::rotate(a + t * 360.0f, 0.0f, 1.0f, 0.0f) *
vmath::rotate(a + t * 360.0f, 0.0f, 0.0f, 1.0f) *
vmath::translate(10.0f + a, 40.0f + b, 50.0f + c);//平移,再旋转
}
//数据操作完毕,解除映射!必须
glUnmapBuffer( GL_ARRAY_BUFFER );
//确认激活需要的着色器程序
glUseProgram( render_prog );
//生成视图矩阵和投影矩阵
vmath::mat4 view_matrix(vmath::translate(0.0f, 0.0f, -1500.0f) * vmath::rotate(t * 360.0f * 2.0f, 0.0f, 1.0f, 0.0f));
vmath::mat4 projection_matrix(vmath::frustum(-1.0f, 1.0f, -shade_aspect, shade_aspect, 1.0f, 5000.0f));
//设置视图矩阵和投影矩阵
glUniformMatrix4fv( view_matrix_loc, 1, GL_FALSE, view_matrix );//这次你就没写错参数,能不能不坑爹,之前我都以为自己智商出问题了。
glUniformMatrix4fv( projection_matrix_loc, 1, GL_FALSE, projection_matrix );
//渲染多个实例
object.Render( 0, INSTANCE_COUNT ); //能不能不坑爹。。后面的vbm居然不兼容前面的vbm.....
GLenum error = glGetError();//
const GLubyte* errorStr = gluErrorString(error);
//这个几个意思。。。lookat只是生成了一个矩阵而已。。。
//vmath::lookat( vmath::vec3(0.0f, 0.0f, 0.0f), vmath::vec3(1.0f, 0.0f, 0.0f), vmath::vec3(0.0f, 1.0f, 0.0f) ); //摄像机?????????/
}
void instancing1Update(float)
{
}原文地址:http://blog.csdn.net/coderling/article/details/44254809