Files
bullet3/ObsoleteDemos/NativeClient/cube.cc
erwin coumans 69e5454d18 Add the old Bullet 2.x obsolete demos, and CMake buildsystem files, and gradually move them to newer Bullet 3.x structure
Use statically linked freeglut, instead of dynamic glut for the obsolete Bullet 2.x demos
Add the 'reset' method to b3GpuDynamicsWorld, and use it in the BasicGpuDemo (pretty slow in debug mode, use release mode)
Don't crash in btCollisionWorld, if there is no collision dispatcher
2013-12-19 12:40:59 -08:00

268 lines
7.8 KiB
C++

// Copyright (c) 2011 The Native Client Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cube.h"
#include <algorithm>
#include "shader_util.h"
#include "transforms.h"
namespace tumbler {
static const size_t kVertexCount = 24;
static const int kIndexCount = 36;
Cube::Cube(SharedOpenGLContext opengl_context)
: opengl_context_(opengl_context),
width_(1),
height_(1) {
eye_[0] = eye_[1] = 0.0f;
eye_[2] = 2.0f;
orientation_[0] = 0.0f;
orientation_[1] = 0.0f;
orientation_[2] = 0.0f;
orientation_[3] = 1.0f;
}
Cube::~Cube() {
glDeleteBuffers(3, cube_vbos_);
glDeleteProgram(shader_program_object_);
}
void Cube::PrepareOpenGL() {
CreateShaders();
CreateCube();
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
}
void Cube::Resize(int width, int height) {
width_ = std::max(width, 1);
height_ = std::max(height, 1);
// Set the viewport
glViewport(0, 0, width_, height_);
// Compute the perspective projection matrix with a 60 degree FOV.
GLfloat aspect = static_cast<GLfloat>(width_) / static_cast<GLfloat>(height_);
transform_4x4::LoadIdentity(perspective_proj_);
transform_4x4::Perspective(perspective_proj_, 60.0f, aspect, 1.0f, 20.0f);
}
void Cube::Draw() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Compute a new model-view matrix, then use that to make the composite
// model-view-projection matrix: MVP = MV . P.
GLfloat model_view[16];
ComputeModelViewTransform(model_view);
transform_4x4::Multiply(mvp_matrix_, model_view, perspective_proj_);
glBindBuffer(GL_ARRAY_BUFFER, cube_vbos_[0]);
glUseProgram(shader_program_object_);
glEnableVertexAttribArray(position_location_);
glVertexAttribPointer(position_location_,
3,
GL_FLOAT,
GL_FALSE,
3 * sizeof(GLfloat),
NULL);
glEnableVertexAttribArray(color_location_);
glBindBuffer(GL_ARRAY_BUFFER, cube_vbos_[1]);
glVertexAttribPointer(color_location_,
3,
GL_FLOAT,
GL_FALSE,
3 * sizeof(GLfloat),
NULL);
glUniformMatrix4fv(mvp_location_, 1, GL_FALSE, mvp_matrix_);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube_vbos_[2]);
glDrawElements(GL_TRIANGLES, kIndexCount, GL_UNSIGNED_SHORT, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
bool Cube::CreateShaders() {
const char vertex_shader_src[] =
"uniform mat4 u_mvpMatrix; \n"
"attribute vec4 a_position; \n"
"attribute vec3 a_color; \n"
"varying lowp vec4 v_color; \n"
"void main() \n"
"{ \n"
" v_color.xyz = a_color; \n"
" v_color.w = 1.0; \n"
" gl_Position = u_mvpMatrix * a_position; \n"
"} \n";
const char fragment_shader_src[] =
"varying lowp vec4 v_color; \n"
"void main() \n"
"{ \n"
" gl_FragColor = v_color; \n"
"} \n";
// Load the shaders and get a linked program object
shader_program_object_ =
shader_util::CreateProgramFromVertexAndFragmentShaders(
vertex_shader_src, fragment_shader_src);
if (shader_program_object_ == 0)
return false;
position_location_ = glGetAttribLocation(shader_program_object_,
"a_position");
color_location_ = glGetAttribLocation(shader_program_object_, "a_color");
mvp_location_ = glGetUniformLocation(shader_program_object_, "u_mvpMatrix");
return true;
}
void Cube::CreateCube() {
static const GLfloat cube_vertices[] = {
// Vertex coordinates interleaved with color values
// Bottom
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, -0.5f,
// Top
-0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
// Back
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
// Front
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
// Left
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
// Right
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f
};
static const GLfloat cube_colors[] = {
// Vertex coordinates interleaved with color values
// Bottom
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
// Top
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
// Back
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
// Front
1.0, 0.0, 1.0,
1.0, 0.0, 1.0,
1.0, 0.0, 1.0,
1.0, 0.0, 1.0,
// Left
1.0, 1.0, 0.0,
1.0, 1.0, 0.0,
1.0, 1.0, 0.0,
1.0, 1.0, 0.0,
// Right
0.0, 1.0, 1.0,
0.0, 1.0, 1.0,
0.0, 1.0, 1.0,
0.0, 1.0, 1.0
};
static const GLushort cube_indices[] = {
// Bottom
0, 2, 1,
0, 3, 2,
// Top
4, 5, 6,
4, 6, 7,
// Back
8, 9, 10,
8, 10, 11,
// Front
12, 15, 14,
12, 14, 13,
// Left
16, 17, 18,
16, 18, 19,
// Right
20, 23, 22,
20, 22, 21
};
// Generate the VBOs and upload them to the graphics context.
glGenBuffers(3, cube_vbos_);
glBindBuffer(GL_ARRAY_BUFFER, cube_vbos_[0]);
glBufferData(GL_ARRAY_BUFFER,
kVertexCount * sizeof(GLfloat) * 3,
cube_vertices,
GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, cube_vbos_[1]);
glBufferData(GL_ARRAY_BUFFER,
kVertexCount * sizeof(GLfloat) * 3,
cube_colors,
GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube_vbos_[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
kIndexCount * sizeof(GL_UNSIGNED_SHORT),
cube_indices,
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void Cube::ComputeModelViewTransform(GLfloat* model_view) {
// This method takes into account the possiblity that |orientation_|
// might not be normalized.
double sqrx = orientation_[0] * orientation_[0];
double sqry = orientation_[1] * orientation_[1];
double sqrz = orientation_[2] * orientation_[2];
double sqrw = orientation_[3] * orientation_[3];
double sqrLength = 1.0 / (sqrx + sqry + sqrz + sqrw);
transform_4x4::LoadIdentity(model_view);
model_view[0] = (sqrx - sqry - sqrz + sqrw) * sqrLength;
model_view[5] = (-sqrx + sqry - sqrz + sqrw) * sqrLength;
model_view[10] = (-sqrx - sqry + sqrz + sqrw) * sqrLength;
double temp1 = orientation_[0] * orientation_[1];
double temp2 = orientation_[2] * orientation_[3];
model_view[1] = 2.0 * (temp1 + temp2) * sqrLength;
model_view[4] = 2.0 * (temp1 - temp2) * sqrLength;
temp1 = orientation_[0] * orientation_[2];
temp2 = orientation_[1] * orientation_[3];
model_view[2] = 2.0 * (temp1 - temp2) * sqrLength;
model_view[8] = 2.0 * (temp1 + temp2) * sqrLength;
temp1 = orientation_[1] * orientation_[2];
temp2 = orientation_[0] * orientation_[3];
model_view[6] = 2.0 * (temp1 + temp2) * sqrLength;
model_view[9] = 2.0 * (temp1 - temp2) * sqrLength;
model_view[3] = 0.0;
model_view[7] = 0.0;
model_view[11] = 0.0;
// Concatenate the translation to the eye point.
model_view[12] = -eye_[0];
model_view[13] = -eye_[1];
model_view[14] = -eye_[2];
model_view[15] = 1.0;
}
} // namespace tumbler